Index: /branches/PublicaMundi_David_integration_01-devel/debian/changelog
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/changelog	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/changelog	(revision 672)
@@ -0,0 +1,20 @@
+zoo-project (1.4~devel01) UNRELEASED; urgency=low
+
+  * Added Gdal ZOO Services
+  * Added Cgal ZOO Services
+  * Added WPS Status Services
+
+ -- David Saggiorato <david@saggiorato.net>  Fri, 31 Oct 2014 17:54:34 +0100
+
+zoo-project (1.3.0-1~trusty10) trusty; urgency=low
+
+  * Added OGR ZOO Services.
+
+ -- Angelos Tzotsos <gcpp.kalxas@gmail.com>  Sun, 28 Jul 2014 19:48:00 +0200
+
+zoo-project (1.3.0-1~trusty7) trusty; urgency=low
+
+  * Initial Debian packaging.
+
+ -- Angelos Tzotsos <gcpp.kalxas@gmail.com>  Tue, 10 Jun 2014 21:17:04 +0200
+
Index: /branches/PublicaMundi_David_integration_01-devel/debian/compat
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/compat	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/compat	(revision 672)
@@ -0,0 +1,1 @@
+9
Index: /branches/PublicaMundi_David_integration_01-devel/debian/control
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/control	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/control	(revision 672)
@@ -0,0 +1,49 @@
+Source: zoo-project
+Maintainer: Angelos Tzotsos <gcpp.kalxas@gmail.com>
+Section: web
+Priority: optional
+Build-Depends: debhelper (>= 9),
+               dpkg-dev (>= 1.16.1.1),
+               autoconf,
+               automake,
+               autotools-dev,
+               flex,
+               bison,
+               libssl-dev,
+               libcurl4-gnutls-dev,
+               libcgic-dev (>= 2.06),
+               libgdal-dev,
+               python-all (>= 2.6.6-3~) |  python-dev,
+               libfcgi-dev,
+               libxml2-dev,
+               libxslt1-dev,
+               libcgal-dev,
+               libmozjs185-dev,
+Build-Conflicts: libcurl3-openssl-dev
+Standards-Version: 3.9.3
+X-Python-Version: >= 2.7
+Homepage: http://zoo-project.org
+
+Package: zoo-kernel
+Architecture: any
+Section: web
+Depends: ${shlibs:Depends},
+         ${misc:Depends}
+Description: This package contains the CGI ZOO Kernel
+ .
+ ZOO is a WPS (Web Processing Service) open source project released 
+ under a  MIT/X-11 style license . It provides an OGC WPS compliant
+ developer-friendly framework to create and chain WPS Web services. 
+
+Package: zoo-services
+Architecture: any
+Section: web
+Depends: ${shlibs:Depends},
+         ${misc:Depends},
+         python (>=2.7), 
+         python-gdal
+Description: This package contains the CGI ZOO Services
+ .
+ ZOO is a WPS (Web Processing Service) open source project released 
+ under a  MIT/X-11 style license . It provides an OGC WPS compliant
+ developer-friendly framework to create and chain WPS Web services. 
Index: /branches/PublicaMundi_David_integration_01-devel/debian/copyright
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/copyright	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/copyright	(revision 672)
@@ -0,0 +1,37 @@
+This package was debianized by Angelos Tzotsos gcpp.kalxas@gmail.com on
+Tue, 10 Jun 2014 21:17:04 +0200.
+
+It was downloaded from:
+
+    http://zoo-project.org
+
+Upstream author:
+
+    Gerald Fenoy <gerald.fenoy@geolabs.fr>
+
+Copyright:
+
+    Copyright (C) 2010-2011 GeoLabs.
+
+License:
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+
Index: /branches/PublicaMundi_David_integration_01-devel/debian/rules
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/rules	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/rules	(revision 672)
@@ -0,0 +1,41 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+%:
+	dh  $@
+
+override_dh_auto_configure:
+	cd zoo-project/zoo-kernel && autoconf && ./configure --with-python --with-js --with-cgi-dir=$(CURDIR)/debian/tmp/usr/lib/cgi-bin
+
+override_dh_auto_build:
+	dh_auto_build --builddirectory zoo-project/zoo-kernel
+	dh_auto_build --builddirectory zoo-project/zoo-services/cgal
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/contour
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/translate
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/dem
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/grid
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/profile
+	dh_auto_build --builddirectory zoo-project/zoo-services/gdal/warp
+	dh_auto_build --builddirectory zoo-project/zoo-services/ogr/base-vect-ops
+	dh_auto_build --builddirectory zoo-project/zoo-services/ogr/ogr2ogr
+	dh_auto_build --builddirectory zoo-project/zoo-services/utils/status
+
+override_dh_auto_install:
+	dh_auto_install --builddirectory zoo-project/zoo-kernel
+	dh_auto_install --builddirectory zoo-project/zoo-services/cgal
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/contour
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/translate
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/dem
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/grid
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/profile
+	dh_auto_install --builddirectory zoo-project/zoo-services/gdal/warp
+	install -d $(CURDIR)/debian/tmp/usr/lib/cgi-bin/gdal/ndvi
+	install $(CURDIR)/zoo-project/zoo-services/gdal/ndvi/cgi-env/* $(CURDIR)/debian/tmp/usr/lib/cgi-bin/gdal/ndvi/
+	dh_auto_install --builddirectory zoo-project/zoo-services/ogr/base-vect-ops
+	dh_auto_install --builddirectory zoo-project/zoo-services/ogr/ogr2ogr
+	install -d $(CURDIR)/debian/tmp/usr/lib/cgi-bin/ogr/base-vect-ops-py
+	install $(CURDIR)/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/* $(CURDIR)/debian/tmp/usr/lib/cgi-bin/ogr/base-vect-ops-py/
+	dh_auto_install --builddirectory zoo-project/zoo-services/utils/status
+
+#override_dh_auto_clean:
+#	dh_auto_clean --builddirectory zoo-project/zoo-kernel
Index: /branches/PublicaMundi_David_integration_01-devel/debian/source/format
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/source/format	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/source/format	(revision 672)
@@ -0,0 +1,1 @@
+3.0 (native)
Index: /branches/PublicaMundi_David_integration_01-devel/debian/zoo-kernel.install
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/zoo-kernel.install	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/zoo-kernel.install	(revision 672)
@@ -0,0 +1,3 @@
+usr/lib/cgi-bin/zoo_loader.cgi
+usr/lib/cgi-bin/main.cfg
+zoo-project/zoo-api/js/*    usr/lib/cgi-bin/
Index: /branches/PublicaMundi_David_integration_01-devel/debian/zoo-services.install
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/debian/zoo-services.install	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/debian/zoo-services.install	(revision 672)
@@ -0,0 +1,9 @@
+usr/lib/cgi-bin/cgal	usr/lib/cgi-bin/
+usr/lib/cgi-bin/gdal	usr/lib/cgi-bin/
+usr/lib/cgi-bin/ogr	usr/lib/cgi-bin/
+usr/lib/cgi-bin/demo.zcfg	usr/lib/cgi-bin/
+usr/lib/cgi-bin/GetStatus.zcfg	usr/lib/cgi-bin/
+usr/lib/cgi-bin/longProcess.zcfg	usr/lib/cgi-bin/
+usr/lib/cgi-bin/service.py	usr/lib/cgi-bin/
+usr/lib/cgi-bin/updateStatus.xsl	usr/lib/cgi-bin/
+usr/lib/cgi-bin/wps_status.zo	usr/lib/cgi-bin/
Index: /branches/PublicaMundi_David_integration_01-devel/docs/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/Makefile	(revision 672)
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ZOOProject.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ZOOProject.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/ZOOProject"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ZOOProject"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/basic.css
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/basic.css	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/basic.css	(revision 672)
@@ -0,0 +1,545 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 25%;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+    padding:10px;
+   	background: #FFCD0B;
+    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#FFCD0B'); /* for IE */
+    background:-webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#FFCD0B)); /* for webkit browsers */
+    background: -moz-linear-gradient(center top , #FFFFFF, #FFCD0B) repeat scroll 0 0 transparent;
+     -moz-border-radius-bottomright: 5px;
+border-bottom-right-radius:5px;
+-webkit-border-bottom-right-radius:5px;
+-moz-border-radius-bottomleft: 5px;
+border-bottom-left-radius:5px;
+-webkit-border-bottom-left-radius:5px;
+background:#FFFFFF;
+    }
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: Verdana;
+    font-size: 1em;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div  td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    clear: both;
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlighted {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.refcount {
+    color: #060;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: verdana;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+  div.footer {
+        padding:0;
+        margin:0;
+    }
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/default.css
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/default.css	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/default.css	(revision 672)
@@ -0,0 +1,528 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size: 14px;
+    background-color: #ffffff;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: white;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+     background:#bababa;
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#bababa', endColorstr='#707070'); /* for IE */
+background:-webkit-gradient(linear, left top, left bottom, from(#bababa), to(#707070)); /* for webkit browsers */
+background:-moz-linear-gradient(top,  #bababa,  #707070); /* for firefox 3.6+ */
+ }
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+
+}
+
+div.body {
+background:#FFFFFF;
+    color: #333333;
+    padding: 10px 20px 20px 20px;
+}
+div.bodywrapper {
+    margin: 1em 25% 1em 1em;
+}
+
+
+div.footer {
+    color: #333333;
+    width: 100%;
+    padding:0;
+    text-align: center;
+    font-size:12px;
+}
+
+#footer p{padding:10px 0 5px 0;}
+
+
+div.footer a {
+    color: #646464;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #ed910d;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+	margin: 0 0 10px 10px;
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+    float: right;
+    
+}
+
+/* -- Custom Sidebar styles ----------------------------------------------------------- */
+
+.categories{
+	background: #ee920c;
+        filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee920c', endColorstr='#ffcd0b'); /* for IE */
+        background:-webkit-gradient(linear, left top, left bottom, from(#ee920c), to(#ffcd0b)); /* for webkit browsers */
+        background:-moz-linear-gradient(top,  #ee920c,  #ffcd0b); /* for firefox 3.6+ */
+	font-size: 1.3em;
+	width: 98%;
+	margin-bottom: 10px;
+	border:0;
+	padding:1%;
+	text-shadow: 1px 1px 1px #E0E0E0;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+        border-radius: 5px;
+}
+
+.twitts, .donate, #searchbox {
+    -moz-border-radius: 5px;
+    -webkit-border-radius:5px;
+    border-radius:5px;
+    background: #FFCD0B;
+    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#FFCD0B'); /* for IE */
+    background:-webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#FFCD0B)); /* for webkit browsers */
+    background: -moz-linear-gradient(center top , #FFFFFF, #FFCD0B) repeat scroll 0 0 transparent;
+    border: 0 none;
+    height: auto;
+    margin-bottom: 10px;
+    padding: 1%;
+    width: 98%;
+}
+
+.twitts img{width:180px;height:40px;}
+
+
+
+/* -- End Custom Sidebar styles ----------------------------------------------------------- */
+
+div.sphinxsidebar h1, .donate h1, .twitts h1 {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    color: #663e05;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+    margin:10px 0 10px 10px;
+}
+
+div.sphinxsidebar h3 {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    color: #663e05;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+
+}
+
+div.sphinxsidebar h3 a {
+    color: #5D3805;
+         -moz-border-radius-topright: 5px;
+border-top-right-radius:5px;
+-webkit-border-top-right-radius:5px;
+-moz-border-radius-topleft: 5px;
+border-top-left-radius:5px;
+-webkit-border-top-left-radius:5px;
+background:#FFFFFF;
+display:block;
+padding:5px;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Verdana, Arial, Helvetica, sans-serif';
+    color: #663e05;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #333333;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 0 0 1em 0;
+
+
+    
+}
+
+div.sphinxsidebar a {
+    color: #ED910D;
+    text-decoration:none;
+}
+
+
+div.sphinxsidebar a p.version{
+color:#FFFFFF;
+text-shadow: none;
+margin:0 0 10px 10px ;
+padding:0;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #5F3A05;
+    font-family: Verdana;
+    font-size: 1em;
+    -moz-border-radius:5px;
+    -webkit-border-radius:5px;
+    border-radius:5px;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: #ffac59;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #ffac59;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Verdana';
+    background-color: #ffffff;
+    font-weight: normal;
+    color: #663e05;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 {
+	font-size: 1.4em;
+	font-family:Verdana;
+	margin: 10px 0 0 0;
+	padding:0;
+	 }
+div.body h2 { font-size: 120%; }
+div.body h3 { font-size: 100%; }
+div.body h4 { font-size: 90%; }
+div.body h5 { font-size: 80%; }
+div.body h6 { font-size: 70%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #fff6ce;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #beb899;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #fff6ce;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
+
+/*  Custom Menu Bar ---------------------------------------- */
+
+ul.topnav {
+	position:relative;
+	top:0;
+	left:0;
+	list-style: none;
+	padding: 0 ;	
+	margin: 0;
+	float: left;
+	width: 100%;
+	height:40px;
+	background: #563404;
+filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#563404', endColorstr='#663e05'); /* for IE */
+background:-webkit-gradient(linear, left top, left bottom, from(#563404), to(#663e05)); /* for webkit browsers */
+background:-moz-linear-gradient(top,  #563404,  #663e05); /* for firefox 3.6+ */
+	font-size: 1.2em;
+}
+ul.topnav li {
+	float: left;
+	margin: 0;	
+	padding: 0 15px 0 0;
+	position: relative; /*--Declare X and Y axis base--*/
+}
+ul.topnav li a{
+	padding: 9px 10px 10px 20px;
+	color: #fff;
+	display: block;
+	text-decoration: none;
+	float: left;
+	
+}
+ul.topnav li a:hover{
+	background: transparent;
+	color:#ffcd0b;
+}
+ul.topnav li span { /*--Drop down trigger styles--*/
+	width: 17px;
+	height: 35px;
+	float: left;
+}
+ul.topnav li span.subhover {background-position: center bottom; cursor: pointer;} /*--Hover effect for trigger--*/
+ul.topnav li ul.subnav {
+	list-style: none;
+	position: absolute; /*--Important - Keeps subnav from affecting main navigation flow--*/
+	left: 20px; top: 35px;
+	margin: 0; padding: 0;
+	display: none;
+	float: left;
+	width: 170px;
+	-moz-border-radius-bottomleft: 5px;
+	-moz-border-radius-bottomright: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	border: 1px solid #663e05;
+	z-index:1000000;
+	
+
+}
+ul.topnav li ul.subnav li{
+	margin: 0; padding: 0;
+
+	clear: both;
+	width: 125px;
+}
+html ul.topnav li ul.subnav li a {
+		font-size:.8em;
+	float: left;
+	width: 155px;
+	background: #663e05;
+	padding:5px 5px 7px 10px ;
+
+}
+html ul.topnav li ul.subnav li a:hover { /*--Hover effect for subnav links--*/
+ 
+}
+
+/*  Custom Header ---------------------------------------- */
+
+#wrapper { 
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+
+#myheader {
+ color: #333;
+ width: 100%;
+ height: 180px;
+ margin: 0;
+ background: #FFFFFF ;
+filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#fff196'); /* for IE */
+background:-webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#fff196)); /* for webkit browsers */
+background:-moz-linear-gradient(top,  #FFFFFF, #fff196  ); /* for firefox 3.6+ */
+}
+
+.hleft{
+float:left;
+margin:0;
+width:380px;
+height:180px;
+background:url(images/zoo-title.png) no-repeat;}
+
+h1.title{width:290px;position:relative;top:102px;left:15px;font-size:1.4em;letter-spacing:2px;color:#727272;text-transform:uppercase;padding:5px;
+ background:#999999;font-weight:normal;
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e0e0e0', endColorstr='#bbbbbb'); /* for IE */
+background:-webkit-gradient(linear, left top, left bottom, from(#e0e0e0), to(#bbbbbb)); /* for webkit browsers */
+background:-moz-linear-gradient(top,  #e0e0e0,  #bbbbbb); /* for firefox 3.6+ */
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+	-webkit-border-radius: 5px;
+		border: 1px solid #d4d4d4;
+		text-align:center;
+		text-shadow: 1px 1px 1px #E0E0E0;
+}
+
+.orange{color:#ffaa17;display:block;padding:5px;}
+
+.hright{
+float:right;
+margin:0;
+width:533px;
+background:url(images/zoo-banner.png) no-repeat;
+height:180px;
+}
+
+/*  Custom Footer ---------------------------------------- */
+
+#footer { 
+	clear:both;
+ width:99.99%;
+ color: #333;
+ background: #ffcd0b;
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffcd0b', endColorstr='#ee920c'); /* for IE */
+background:-webkit-gradient(linear, left top, left bottom, from(#ffcd0b), to(#ee920c)); /* for webkit browsers */
+background:-moz-linear-gradient(top,  #ffcd0b, #ee920c  ); /* for firefox 3.6+ */
+ margin: 0;
+ padding: 0;
+}
+
+#footer p{
+	padding: 0;
+	text-align: center;
+	margin: 0;
+	padding:10px 0 10px 0;
+	color: #676561;
+	font-size: 12px;
+}
+
+#footer a{
+	color: #663e05;
+	font-weight: bold;
+	text-decoration: none;
+	font-size: 14px;
+}
+
+#footer .icon{
+	display: none;
+}
+
+#footer div{
+	text-align: center;
+}
+
+
+#footer .menuContainer{
+width: 750px; margin-left: auto; margin-right: auto;
+}
+
+#footer .menuItemList{
+	margin-top: 1em;
+	float: left;
+	padding-left: 1em;
+	padding-right: 1em;
+	border-left: 1px dashed #563404;;
+}
+
+#footer .menuItemList a{
+	font-weight: normal;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/doctools.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/doctools.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/doctools.js	(revision 672)
@@ -0,0 +1,247 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+    "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+};
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i] == item)
+      return true;
+  }
+  return false;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this);
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initIndexTable();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can safely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlighted');
+        });
+      }, 10);
+      $('<li class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
+          .appendTo($('.sidebar .this-page-menu'));
+    }
+  },
+
+  /**
+   * init the domain index toggle buttons
+   */
+  initIndexTable : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      $('tr.cg-' + idnum).toggle();
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
+    $('span.highlighted').removeClass('highlighted');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/jquery.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/jquery.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/jquery.js	(revision 672)
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/pygments.css
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/pygments.css	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/pygments.css	(revision 672)
@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #303030 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/searchtools.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/searchtools.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/searchtools.js	(revision 672)
@@ -0,0 +1,518 @@
+/*
+ * searchtools.js
+ * ~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+  var textLower = text.toLowerCase();
+  var start = 0;
+  $.each(keywords, function() {
+    var i = textLower.indexOf(this.toLowerCase());
+    if (i > -1)
+      start = i;
+  });
+  start = Math.max(start - 120, 0);
+  var excerpt = ((start > 0) ? '...' : '') +
+  $.trim(text.substr(start, 240)) +
+  ((start + 240 - text.length) ? '...' : '');
+  var rv = $('<div class="context"></div>').text(excerpt);
+  $.each(hlwords, function() {
+    rv = rv.highlightText(this, 'highlighted');
+  });
+  return rv;
+}
+
+/**
+ * Porter Stemmer
+ */
+var PorterStemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  loadIndex : function(url) {
+    $.ajax({type: "GET", url: url, data: null, success: null,
+            dataType: "script", cache: true});
+  },
+
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (var i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    };
+    pulse();
+  },
+
+  /**
+   * perform a search for something
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  query : function(query) {
+    var stopwords = ['and', 'then', 'into', 'it', 'as', 'are', 'in',
+                     'if', 'for', 'no', 'there', 'their', 'was', 'is',
+                     'be', 'to', 'that', 'but', 'they', 'not', 'such',
+                     'with', 'by', 'a', 'on', 'these', 'of', 'will',
+                     'this', 'near', 'the', 'or', 'at'];
+
+    // stem the searchterms and add them to the correct list
+    var stemmer = new PorterStemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
+    for (var i = 0; i < tmp.length; i++) {
+      if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+          tmp[i] == "") {
+        // skip this "word"
+        continue;
+      }
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      // select the correct list
+      if (word[0] == '-') {
+        var toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        var toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$.contains(toAppend, word))
+        toAppend.push(word);
+    };
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    // console.debug('SEARCH: searching for:');
+    // console.info('required: ', searchterms);
+    // console.info('excluded: ', excluded);
+
+    // prepare search
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+    var terms = this._index.terms;
+    var objects = this._index.objects;
+    var objtypes = this._index.objtypes;
+    var objnames = this._index.objnames;
+    var fileMap = {};
+    var files = null;
+    // different result priorities
+    var importantResults = [];
+    var objectResults = [];
+    var regularResults = [];
+    var unimportantResults = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    if (object != null) {
+      for (var prefix in objects) {
+        for (var name in objects[prefix]) {
+          var fullname = (prefix ? prefix + '.' : '') + name;
+          if (fullname.toLowerCase().indexOf(object) > -1) {
+            match = objects[prefix][name];
+            descr = objnames[match[1]] + _(', in ') + titles[match[0]];
+            // XXX the generated anchors are not generally correct
+            // XXX there may be custom prefixes
+            result = [filenames[match[0]], fullname, '#'+fullname, descr];
+            switch (match[2]) {
+            case 1: objectResults.push(result); break;
+            case 0: importantResults.push(result); break;
+            case 2: unimportantResults.push(result); break;
+            }
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    importantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    unimportantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+
+    // perform the search on the required terms
+    for (var i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) == null)
+        break;
+      if (files.length == undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (var j = 0; j < files.length; j++) {
+        var file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (var file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+        continue;
+
+      // ensure that none of the excluded terms is in the
+      // search result.
+      for (var i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+            $.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it
+      // to the result list
+      if (valid)
+        regularResults.push([filenames[file], titles[file], '', null]);
+    }
+
+    // delete unused variables in order to not waste
+    // memory until list is retrieved completely
+    delete filenames, titles, terms;
+
+    // now sort the regular results descending by title
+    regularResults.sort(function(a, b) {
+      var left = a[1].toLowerCase();
+      var right = b[1].toLowerCase();
+      return (left > right) ? -1 : ((left < right) ? 1 : 0);
+    });
+
+    // combine all results
+    var results = unimportantResults.concat(regularResults)
+      .concat(objectResults).concat(importantResults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
+          // dirhtml builder
+          var dirname = item[0] + '/';
+          if (dirname.match(/\/index\/$/)) {
+            dirname = dirname.substring(0, dirname.length-6);
+          } else if (dirname == 'index/') {
+            dirname = '';
+          }
+          listItem.append($('<a/>').attr('href',
+            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+            highlightstring + item[2]).html(item[1]));
+        } else {
+          // normal html builders
+          listItem.append($('<a/>').attr('href',
+            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+            highlightstring + item[2]).html(item[1]));
+        }
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
+                item[0] + '.txt', function(data) {
+            if (data != '') {
+              listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+              Search.output.append(listItem);
+            }
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          });
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  }
+}
+
+$(document).ready(function() {
+  Search.init();
+});
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/sidebar.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/sidebar.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/sidebar.js	(revision 672)
@@ -0,0 +1,148 @@
+/*
+ * sidebar.js
+ * ~~~~~~~~~~
+ *
+ * This script makes the Sphinx sidebar collapsible.
+ *
+ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
+ * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
+ * used to collapse and expand the sidebar.
+ *
+ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
+ * and the width of the sidebar and the margin-left of the document
+ * are decreased. When the sidebar is expanded the opposite happens.
+ * This script saves a per-browser/per-session cookie used to
+ * remember the position of the sidebar among the pages.
+ * Once the browser is closed the cookie is deleted and the position
+ * reset to the default (expanded).
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+$(function() {
+  // global elements used by the functions.
+  // the 'sidebarbutton' element is defined as global after its
+  // creation, in the add_sidebar_button function
+  var bodywrapper = $('.bodywrapper');
+  var sidebar = $('.sphinxsidebar');
+  var sidebarwrapper = $('.sphinxsidebarwrapper');
+
+  // original margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar expanded
+  var bw_margin_expanded = bodywrapper.css('margin-left');
+  var ssb_width_expanded = sidebar.width();
+
+  // margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar collapsed
+  var bw_margin_collapsed = '.8em';
+  var ssb_width_collapsed = '.8em';
+
+  // colors used by the current theme
+  var dark_color = $('.related').css('background-color');
+  var light_color = $('.document').css('background-color');
+
+  function sidebar_is_collapsed() {
+    return sidebarwrapper.is(':not(:visible)');
+  }
+
+  function toggle_sidebar() {
+    if (sidebar_is_collapsed())
+      expand_sidebar();
+    else
+      collapse_sidebar();
+  }
+
+  function collapse_sidebar() {
+    sidebarwrapper.hide();
+    sidebar.css('width', ssb_width_collapsed);
+    bodywrapper.css('margin-left', bw_margin_collapsed);
+    sidebarbutton.css({
+        'margin-left': '0',
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('»');
+    sidebarbutton.attr('title', _('Expand sidebar'));
+    document.cookie = 'sidebar=collapsed';
+  }
+
+  function expand_sidebar() {
+    bodywrapper.css('margin-left', bw_margin_expanded);
+    sidebar.css('width', ssb_width_expanded);
+    sidebarwrapper.show();
+    sidebarbutton.css({
+        'margin-left': ssb_width_expanded-12,
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('«');
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    document.cookie = 'sidebar=expanded';
+  }
+
+  function add_sidebar_button() {
+    sidebarwrapper.css({
+        'float': 'left',
+        'margin-right': '0',
+        'width': ssb_width_expanded - 28
+    });
+    // create the button
+    sidebar.append(
+        '<div id="sidebarbutton"><span>&laquo;</span></div>'
+    );
+    var sidebarbutton = $('#sidebarbutton');
+    light_color = sidebarbutton.css('background-color');
+    // find the height of the viewport to center the '<<' in the page
+    var viewport_height;
+    if (window.innerHeight)
+ 	  viewport_height = window.innerHeight;
+    else
+	  viewport_height = $(window).height();
+    sidebarbutton.find('span').css({
+        'display': 'block',
+        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
+    });
+
+    sidebarbutton.click(toggle_sidebar);
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    sidebarbutton.css({
+        'color': '#FFFFFF',
+        'border-left': '1px solid ' + dark_color,
+        'font-size': '1.2em',
+        'cursor': 'pointer',
+        'height': bodywrapper.height(),
+        'padding-top': '1px',
+        'margin-left': ssb_width_expanded - 12
+    });
+
+    sidebarbutton.hover(
+      function () {
+          $(this).css('background-color', dark_color);
+      },
+      function () {
+          $(this).css('background-color', light_color);
+      }
+    );
+  }
+
+  function set_position_from_cookie() {
+    if (!document.cookie)
+      return;
+    var items = document.cookie.split(';');
+    for(var k=0; k<items.length; k++) {
+      var key_val = items[k].split('=');
+      var key = key_val[0];
+      if (key == 'sidebar') {
+        var value = key_val[1];
+        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
+          collapse_sidebar();
+        else if ((value == 'expanded') && (sidebar_is_collapsed()))
+          expand_sidebar();
+      }
+    }
+  }
+
+  add_sidebar_button();
+  var sidebarbutton = $('#sidebarbutton');
+  set_position_from_cookie();
+});
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_static/underscore.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_static/underscore.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_static/underscore.js	(revision 672)
@@ -0,0 +1,16 @@
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
+a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
+var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
+d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
+function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
+function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
+0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
+e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
+a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_templates/index.html
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_templates/index.html	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_templates/index.html	(revision 672)
@@ -0,0 +1,3 @@
+{% extends "layout.html" %}
+{% set title = 'Overview' %}
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_templates/indexsidebar.html
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_templates/indexsidebar.html	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_templates/indexsidebar.html	(revision 672)
@@ -0,0 +1,20 @@
+<div class="categories">
+  <a href="/site/Downloads"><h1>Download now !</h1>
+        <p class="version">ZOO Version 1.4.0</p></a>
+</div>
+<div class="donate">
+  <h1 id="SupportZOO-Project">Support ZOO-Project</h1>
+    <form action="https://www.paypal.com/cgi-bin/webscr" method="post" style="text-align: center;">
+      <input type="hidden" name="cmd" value="_s-xclick"></input>
+      <input type="hidden" name="hosted_button_id" value="WTHKTUQBHBHSQ"></input>
+      <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" style="border:0"></input>
+      <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1"></img>
+    </form>
+</div>
+<div class="twitts">
+  <h1 id="FollowtheZOO">Follow the ZOO</h1>
+    <p>
+      <a style="padding:0; border:none" href="http://twitter.com/ZOO_Project"><img src="http://a0.twimg.com/a/1291253242/images/fronts/logo_withbird_home.png" alt="http://a0.twimg.com/a/1291253242/images/fronts/logo_withbird_home.png" title="http://a0.twimg.com/a/1291253242/images/fronts/logo_withbird_home.png"></img></a>
+    </p>
+</div>
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/_templates/layout.html
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/_templates/layout.html	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/_templates/layout.html	(revision 672)
@@ -0,0 +1,165 @@
+{% extends "!layout.html" %}
+
+{% block extrahead %}
+
+<script type="text/javascript">
+$(document).ready(function(){
+
+	$("ul.topnav li a").hover(function() {
+
+		//Following events are applied to the subnav itself (moving subnav up and down)
+		$(this).parent().find("ul.subnav").slideDown('fast').show(); //Drop down the subnav on click
+
+		$(this).parent().hover(function() {
+		}, function(){
+			$(this).parent().find("ul.subnav").slideUp('slow'); //When the mouse hovers out of the subnav, move it back up
+		});
+
+		//Following events are applied to the trigger (Hover events for the trigger)
+		}).hover(function() {
+			$(this).addClass("subhover"); //On hover over, add class "subhover"
+		}, function(){	//On Hover Out
+			$(this).removeClass("subhover"); //On hover out, remove class "subhover"
+	});
+
+});
+</script>
+
+    {{ super() }}
+{% endblock %}
+
+{% block header %}
+<!-- Begin Header -->
+<div id="wrapper">
+  	<div id="myheader">
+    	<div class="hleft">
+    	  <h1 class="title">Open WPS Platform</h1>
+    	</div>
+    	<div class="hright">
+    	</div>
+  	</div>
+</div>
+<ul class="topnav">
+  <li><a href="http://www.zoo-project.org/">Home</a></li>
+  <li><a href="#">ZOO Project</a>
+       <ul class="subnav">
+
+         <li><a href="/site/ZooWebSite/ZooProject/About">About</a></li>
+         <li><a href="/site/ZooWebSite/ZooProject/Tribe">ZOO Tribe</a></li>
+         <li><a href="/site/ZooWebSite/ZooProject/Events">Events</a></li>
+         <li><a href="/site/ZooWebSite/ZooProject/Photos">Photos</a></li>
+         <li><a href="/site/ZooWebSite/ZooProject/Contact">Contacts</a></li>
+       </ul>
+
+  </li>
+  <li>
+    <a href="#">Components</a>
+    <ul class="subnav">
+      <li><a href="/site/ZooWebSite/ZooKernel">ZOO Kernel</a></li>
+      <li><a href="/site/ZooWebSite/ZooServices">ZOO Services</a></li>
+      <li><a href="/site/ZooWebsite/ZooApi">ZOO API</a></li>
+
+    </ul>
+  </li>
+  <li><a href="/site/Downloads">Download</a></li>
+  <li><a href="{{ pathto('index') }}">Docs</a></li>
+  <li><a href="#">Demos</a>
+    <ul class="subnav">
+      <li><a href="/site/ZooWebSite/Demo/SpatialTools">ZOO Spatial Tools</a></li>
+
+      <li><a href="/site/ZooWebSite/Demo/CGAL">ZOO CGAL Vor</a></li>
+      <li><a href="/site/ZooWebSite/Demo/WFS-T">ZOO Mapserver WFS-T</a></li>
+      <li><a href="/site/ZooWebSite/Demo/GdalProfile">ZOO Elevation Profile</a></li>
+      <li><a href="/site/ZooWebSite/Demo/FormTools">ZOO Form tools</a></li>
+    </ul>
+  </li>
+  <li><a href="/trac">Trac</a></li>
+</ul>
+<!-- End Header -->
+    {{ super() }}
+{% endblock %}
+
+{% block footer %}
+<!-- Begin Footer -->
+<div id="footer">
+<div>
+
+<div>
+  <div class="menuContainer">
+    <div class="menuItemList">
+      <a href="{{ pathto('index') }}" shape="rect">Home</a>
+      <br/>
+    </div>
+    <div class="menuItemList">
+      <a href="#" shape="rect">ZOO Project</a>
+
+      <br/>
+      <a href="/site/ZooWebSite/ZooProject/About" shape="rect">About</a>
+      <br/>
+      <a href="/site/ZooWebSite/ZooProject/Tribe" shape="rect">ZOO Tribe</a>
+      <br/>
+      <a href="/site/ZooWebSite/ZooProject/Events" shape="rect">Events</a>
+      <br/>
+
+      <a href="/site/ZooWebSite/ZooProject/Photos" shape="rect">Photos</a>
+      <br/>
+      <a href="/site/ZooWebSite/ZooProject/Contact" shape="rect">Contacts</a>
+      <br/>
+    </div>
+    <div class="menuItemList">
+      <a href="#" shape="rect">Components</a>
+
+      <br/>
+      <a href="/site/ZooWebSite/ZooKernel" shape="rect">ZOO Kernel</a>
+      <br/>
+      <a href="/site/ZooWebSite/ZooServices" shape="rect">ZOO Services</a>
+      <br/>
+      <a href="/site/ZooWebsite/ZooApi" shape="rect">ZOO API</a>
+      <br/>
+
+    </div>
+    <div class="menuItemList">
+      <a href="{{ pathto('dl/index') }}" shape="rect">Download</a>
+      <br/>
+    </div>
+    <div class="menuItemList">
+      <a href="{{ pathto('doc/index') }}" shape="rect">Docs</a>
+      <br/>
+
+    </div>
+    <div class="menuItemList">
+      <a href="#" shape="rect">Demos</a>
+      <br/>
+      <a href="/site/ZooWebSite/Demo/SpatialTools" shape="rect">ZOO Spatial Tools</a>
+      <br/>
+      <a href="/site/ZooWebSite/Demo/WFS-T" shape="rect">ZOO Mapserver WFS-T</a>
+
+      <br/>
+      <a href="/site/ZooWebSite/Demo/GdalProfile" shape="rect">ZOO Elevation Profile</a>
+      <br/>
+      <a href="/site/ZooWebSite/Demo/FormTools" shape="rect">ZOO Form tools</a>
+      <br/>
+    </div>
+    <div class="menuItemList">
+      <a href="/trac" shape="rect">Trac</a>
+
+      <br/>
+    </div>
+  </div>
+  <br style="clear:both"/>
+</div>
+</div>
+<p>
+&copy; Copyright 2011 - <a class="ext-link" href="http://www.zoo-project.org" shape="rect"><span class="icon"> </span>ZOO Project</a> - All Rights Reserved. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{sphinx_version}}.
+</p>
+</div>
+<!-- End Footer -->
+    {{ super() }}
+{% endblock %}
+
+{# put the sidebar before the body #}
+{% block sidebar1 %}{% endblock %}
+{% block sidebar2 %}{{ sidebar() }}{% endblock %}
+
+{# remove second relbar, at the bottom of the page #}
+{% block relbar2 %}{% endblock %}
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/classes.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/classes.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/classes.txt	(revision 672)
@@ -0,0 +1,38 @@
+.. _api-classes:
+
+Classes
+=======
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+The following classes are available in the ZOO API:
+
+.. toctree::
+   :maxdepth: 2
+   
+   zoo
+   zoo-bounds  
+   zoo-feature   
+   zoo-format
+   zoo-format-geojson 
+   zoo-format-gml   
+   zoo-format-json 
+   zoo-format-kml
+   zoo-format-wkt  
+   zoo-format-wps  
+   zoo-geometry  
+   zoo-geometry-collection  
+   zoo-geometry-curve
+   zoo-geometry-linearring   
+   zoo-geometry-linestring   
+   zoo-geometry-multilinestring   
+   zoo-geometry-multipoint 
+   zoo-geometry-multipolygon   
+   zoo-geometry-point 
+   zoo-geometry-polygon   
+   zoo-geometry-surface 
+   zoo-process   
+   zoo-projection   
+   zoo-request
+   zoo-string   
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/description.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/description.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/description.txt	(revision 672)
@@ -0,0 +1,43 @@
+.. _api-description:
+
+Description
+===========
+
+ZOO API is a Javascript library designed to make the WPS Process creation and chaining 
+easier. It works on the server-side using the Mozilla foundation `JavaScript <https://developer.mozilla.org/en/JavaScript>`__
+engine,  `SpiderMonkey <https://developer.mozilla.org/en/SpiderMonkey>`__. 
+It uses a  `Proj4js <http://proj4js.org/>`__ adaptation for server-side reprojection. It also allows to easily 
+convert vector formats (such as `GML <http://www.opengeospatial.org/standards/gml>`__,  `KML <http://www.opengeospatial.org/standards/kml>`__,  
+`GeoJSON <http://geojson.org/geojson-spec.html>`__, etc). The API lets you orchestrate WPS 
+services simply and offers the ability to add logic and controls in the WPS chaining.
+
+Download ZOO API
+----------------
+
+    * `zoo-api.js <http://zoo-project.org/trac/export/1/trunk/zoo-api/js/ZOO-api.js>`__
+    * `zoo-proj4js.js <http://zoo-project.org/trac/export/1/trunk/zoo-api/js/ZOO-proj4js.js>`__
+
+ZOO API MIT/X-11 License
+------------------------
+
+::
+
+  Copyright (c) 2011 3LIZ
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this 
+  software and associated documentation files (the "Software"), to deal in the Software 
+  without restriction, including without limitation the rights to use, copy, modify, 
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 
+  permit persons to whom the Software is furnished to do so, subject to the following 
+  conditions:
+
+  The above copyright notice and this permission notice shall be included in all copies 
+  or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
+  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
+  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
+  OR OTHER DEALINGS IN THE SOFTWARE. 
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/examples.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/examples.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/examples.txt	(revision 672)
@@ -0,0 +1,54 @@
+.. _api-examples:
+
+Examples
+========
+
+In this page you can find some small examples on how to use the JavaScript ZOO-API 
+on the server side.
+
+ZOO-API contains many classes and functions. You can find the description list :ref:`here <api-classes>`.
+
+ZOO.Process example of use
+--------------------------
+
+::
+
+  function SampleService(conf,inputs,outputs){
+     var myProcess = new ZOO.Process('http://localhost/cgi-bin-new1/zoo_loader_new1.cgi','Boundary');
+     var myInputs = {InputPolygon: { type: 'complex', value: '{"type":"Polygon","coordinates":[[[-106.993853,35.998758],[-107.407233,35.997524],[-107.430525,35.997726],[-107.4824,35.99878],[-108.37013,35.999472],[-109.043633,35.996652],[-109.096265,35.997817],[-109.148763,36.001751],[-109.200981,36.008442],[-109.252775,36.017871],[-109.304,36.030014],[-109.354516,36.044835],[-106.468201,35.991497],[-106.855511,35.989504],[-106.90933,35.990676],[-106.963008,35.994743],[-106.993853,35.998758]]]}', mimeType: "application/json"} };
+     var myExecuteResult=myProcess.Execute(myInputs);
+     return {result: ZOO.SERVICE_SUCCEEDED, outputs: [ {name:"Result", value: myExecuteResult} ] };
+  }
+
+In this really short example you can see how to create ``ZOO.Process`` class instance and 
+call the Execute method on such an instance. Then you'll just need to return a JavaScript 
+object containing the attributes result and outputs, which I'm sure you already know 
+what is about. The first is about the status of the process (can be ``ZOO.SERVICE_SUCEEDED``,
+``ZOO.SERVICE_FAILED`` and so on), the last is obviously the resulting maps (take a 
+look at the maps internal data structure used by ZOO Kernel in ``service.h``).
+
+ZOO.UpdateStatus
+----------------
+
+::
+
+  function SampleLongService(conf,inputs,outputs){
+     var my_i=0;
+     while(my_i<100){
+         try{
+           conf["lenv"]["status"]=my_i;
+         }
+         catch(e){
+         }
+         ZOOUpdateStatus(conf,my_i);
+         SampleService(conf,inputs,outputs);
+         my_i+=10;
+     }
+     return SampleService(conf,inputs,outputs);
+  }
+
+You can see in this sample code how to use the ``ZOOUpdateStatus`` function to update the 
+current status of your running process. This information will be really helpfull when the 
+ZOO Kernel will run your JavaScript Service in background mode (if the user set to ``true`` 
+the ``storeExecuteResponse`` parameter in his request).
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/index.txt	(revision 672)
@@ -0,0 +1,14 @@
+.. _api:
+
+ZOO API Documentation
+=====================
+
+The following sections will assist you with the ZOO API:
+
+.. toctree::
+   :maxdepth: 2
+   
+   description
+   classes
+   examples
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-bounds.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-bounds.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-bounds.txt	(revision 672)
@@ -0,0 +1,254 @@
+.. _api-zoo-bounds:
+
+ZOO.Bounds
+==========
+
+Instances of this class represent bounding boxes.
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`left <left>`
+     - {Number} Minimum horizontal coordinate.
+   * - :ref:`bottom <bottom>`
+     - {Number} Minimum vertical coordinate. 
+   * - :ref:`right <right>` 
+     - {Number} Maximum horizontal coordinate.
+   * - :ref:`top <top>`
+     - {Number} Maximum vertical coordinate.   
+     
+Functions
+---------  
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Bounds <ZOO.Bounds>`
+     - Construct a new bounds object.
+   * - :ref:`clone <clone>`
+     - Create a cloned instance of this bounds.
+   * - :ref:`equals <equals>` 
+     - Test a two bounds for equivalence.
+   * - :ref:`toString <toString>`
+     - {String} String representation of bounds object.
+   * - :ref:`toBBOX <toBBOX>`
+     - 
+   * - :ref:`toGeometry <toGeometry>`
+     - Create a new polygon geometry based on this bounds.
+   * - :ref:`getWidth <getWidth>` 
+     - {Float} The width of the bounds
+   * - :ref:`getHeight <getHeight>`
+     - {Float} The height of the bounds (top minus bottom)  
+   * - :ref:`add <add>`
+     - 
+   * - :ref:`extend <extend>`
+     - Extend the bounds to include the point, lonlat, or bounds specified.
+   * - :ref:`intersectsBounds <intersectsBounds>` 
+     - Determine whether the target bounds intersects this bounds.
+   * - :ref:`containsBounds <containsBounds>`
+     - Determine whether the target bounds is contained within this bounds.     
+
+**Properties**
+   
+.. _left:   
+   
+left	
+  ``{Number}`` Minimum horizontal coordinate.
+  
+.. _bottom:     
+  
+bottom	
+  ``{Number}`` Minimum vertical coordinate.
+
+.. _right:     
+
+right	
+  ``{Number}`` Maximum horizontal coordinate.
+
+.. _top:     
+
+top	
+  ``{Number}`` Maximum vertical coordinate.
+
+**Functions**
+
+.. _ZOO.Bounds:     
+
+ZOO.Bounds	
+  Construct a new bounds object.
+  
+  *Parameters*
+
+  | ``left {Number}`` The left bounds of the box.  Note that for width calculations, this is assumed to be less than the right value.
+  | ``bottom {Number}`` The bottom bounds of the box.  Note that for height calculations, this is assumed to be more than the top value.
+  | ``right {Number}`` The right bounds.
+  | ``top {Number}`` The top bounds.  
+  
+.. _clone:       
+
+clone	
+  ::
+  
+    clone:function()
+
+  Create a cloned instance of this bounds.
+
+  *Returns*
+
+  :ref:`{ZOO.Bounds} <api-zoo-bounds>` A fresh copy of the bounds
+
+.. _equals:       
+
+equals	
+  ::
+  
+    equals:function(bounds)
+
+  Test a two bounds for equivalence.
+
+  *Parameters*
+  
+  | ``bounds {ZOO.Bounds}``
+  
+  *Returns*
+
+  ``{Boolean}`` The passed-in bounds object has the same left, right, top, bottom components as this.  Note 
+  that if bounds passed in is null, returns false.
+
+.. _toString: 
+
+toString	
+  :: 
+  
+    toString:function()
+
+  *Returns*
+
+  ``{String}`` String representation of bounds object.  (ex. *<i>"left-bottom=(5,42) right-top=(10,45)"</i>*)
+  
+.. _toBBOX:   
+  
+toBBOX	
+  ::
+  
+    toBBOX:function(decimal)
+
+  *Parameters*
+  
+  ``decimal {Integer}`` How many significant digits in the bbox coords?  Default is 6
+
+  *Returns*
+
+  ``{String}`` Simple String representation of bounds object.  (ex. *<i>"5,42,10,45"</i>*)  
+
+.. _toGeometry:   
+
+toGeometry	
+  ::
+  
+    toGeometry: function()
+
+  Create a new polygon geometry based on this bounds.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A new polygon with the coordinates of this bounds.
+  
+.. _getWidth:     
+
+getWidth	
+  ::    
+  
+    getWidth:function()
+
+  *Returns*
+
+  ``{Float}`` The width of the bounds
+  
+.. _getHeight:       
+  
+getHeight	
+  ::
+  
+    getHeight:function()
+
+  *Returns*
+
+  ``{Float}`` The height of the bounds (top minus bottom).
+
+.. _add:       
+
+add
+  ::
+  
+    add:function(x,y)
+
+  *Parameters*
+
+  | ``x	{Float}``
+  | ``y	{Float}``
+
+  *Returns*
+
+  :ref:`{ZOO.Bounds} <api-zoo-bounds>` A new bounds whose coordinates are the same as this, but shifted by the passed-in x and y values.
+
+.. _extend:       
+
+extend	
+  ::
+  
+    extend:function(object)
+
+  Extend the bounds to include the point, lonlat, or bounds specified.  Note, this function assumes that left 
+  < right and bottom < top.
+  
+  *Parameters*
+  
+  ``object {Object}`` Can be Point, or Bounds.
+  
+.. _intersectsBounds:         
+  
+intersectsBounds	
+  ::
+  
+    intersectsBounds:function(bounds,inclusive)
+
+  Determine whether the target bounds intersects this bounds.  Bounds are considered intersecting if any 
+  of their edges intersect or if one bounds contains the other.
+
+  *Parameters*
+  
+  | ``bounds`` :ref:`{ZOO.Bounds} <api-zoo-bounds>` The target bounds.
+  | ``inclusive	{Boolean}`` Treat coincident borders as intersecting.  Default is true.  If false, bounds that do not overlap but only touch at the border will not be considered as intersecting.
+
+  *Returns*
+
+  ``{Boolean}`` The passed-in bounds object intersects this bounds.
+ 
+.. _containsBounds:          
+ 
+containsBounds	
+  ::
+  
+    containsBounds:function(bounds,partial,inclusive)
+
+  Determine whether the target bounds is contained within this bounds.
+
+  *Parameters*
+  
+  | ``bounds`` :ref:`{ZOO.Bounds} <api-zoo-bounds>` The target bounds.
+  | ``partial {Boolean}`` If any of the target corners is within this bounds consider the bounds contained.  Default is false.  If true, the entire target bounds must be contained within this bounds.
+  | ``inclusive	{Boolean}`` Treat shared edges as contained.  Default is true.
+
+  *Returns*
+
+  ``{Boolean}`` The passed-in bounds object is contained within this bounds.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-feature.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-feature.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-feature.txt	(revision 672)
@@ -0,0 +1,107 @@
+.. _api-zoo-feature:
+
+ZOO.Feature
+===========
+
+Vector features use the ZOO.Geometry classes as geometry description.
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`fid <fid>`
+     - {String}
+   * - :ref:`geometry <geometry>`
+     - {ZOO.Geometry}
+   * - :ref:`attributes <attributes>`
+     - {Object} This object holds arbitrary properties that describe the feature.
+   * - :ref:`bounds <bounds>`
+     - {ZOO.Bounds} The box bounding that feature's geometry, that property can be set by an ZOO.Format object when deserializing the feature, so in most cases it represents an information set by the server.
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Feature <ZOO.Feature>`
+     - Create a vector feature.
+   * - :ref:`destroy <destroy>`
+     - nullify references to prevent circular references and memory leaks
+   * - :ref:`clone <clone>`
+     - Create a clone of this vector feature.
+   * - :ref:`move <move>`
+     - Moves the feature and redraws it at its new location
+   
+     
+**Properties**
+       
+.. _fid: 
+
+fid	
+  ``{String}``
+  
+.. _geometry:   
+  
+geometry	
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+.. _attributes:     
+  
+attributes	
+  ``{Object}`` This object holds arbitrary properties that describe the feature.
+  
+.. _bounds:       
+  
+bounds	
+  :ref:`{ZOO.Bounds} <api-zoo-bounds>` The box bounding that feature's geometry, that 
+  property can be set by an ZOO.Format object when deserializing the feature, so in most cases 
+  it represents an information set by the server.
+
+**Functions**
+       
+.. _ZOO.Feature: 
+
+ZOO.Feature
+  Create a vector feature.
+
+
+  *Parameters*
+  
+  | ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` The geometry that this feature represents.
+  | ``attributes {Object}`` An optional object that will be mapped to the attributes property. 
+  
+.. _destroy:   
+  
+destroy	
+  ::
+  
+    destroy: function()
+
+  nullify references to prevent circular references and memory leaks  
+  
+.. _clone:     
+  
+clone	
+  ::
+  
+    clone: function ()
+
+  Create a clone of this vector feature.  Does not set any non-standard properties.
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` An exact clone of this vector feature.  
+  
+.. _move:       
+  
+move	
+  Moves the feature and redraws it at its new location
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-geojson.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-geojson.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-geojson.txt	(revision 672)
@@ -0,0 +1,455 @@
+.. _api-zoo-format-geojson:
+
+ZOO.Format.GeoJSON
+==================
+
+Read and write GeoJSON.
+
+Inherits from
+
+- :ref:`ZOO.Format.JSON <api-zoo-format-json>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Format.GeoJSON <ZOO.Format.GeoJSON>`
+     - Create a new parser for GeoJSON.
+   * - :ref:`read <read>`
+     - Deserialize a GeoJSON string.
+   * - :ref:`isValidType <isValidType>`
+     - Check if a GeoJSON object is a valid representative of the given type.
+   * - :ref:`parseFeature <parseFeature>`
+     - Convert a feature object from GeoJSON into an ZOO.Feature. 
+   * - :ref:`parseGeometry <parseGeometry>`
+     - Convert a geometry object from GeoJSON into an ZOO.Geometry.   
+     
+parseCoords Properties	
+----------------------
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`parseCoords <parseCoords>`
+     - Object with properties corresponding to the GeoJSON geometry types.  
+     
+parseCoords Functions	
+---------------------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`parseCoords.point <parseCoords.point>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.Point.
+   * - :ref:`parseCoords.multipoint <parseCoords.multipoint>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.MultiPoint.
+   * - :ref:`parseCoords.linestring <parseCoords.linestring>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.LineString.
+   * - :ref:`parseCoords.multilinestring <parseCoords.multilinestring>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.MultiLineString.
+   * - :ref:`parseCoords.polygon <parseCoords.polygon>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.Polygon.  
+   * - :ref:`parseCoords.multipolygon <parseCoords.multipolygon>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.MultiPolygon.
+   * - :ref:`parseCoords.box <parseCoords.box>`
+     - Convert a coordinate array from GeoJSON into an ZOO.Geometry.Polygon.
+   * - :ref:`write <write>`
+     - Serialize a feature, geometry, array of features into a GeoJSON string.
+   * - :ref:`createCRSObject <createCRSObject>`
+     - Create the CRS object for an object.     
+     
+extract Properties
+------------------
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`extract <extract>`
+     - Object with properties corresponding to the GeoJSON types.   
+     
+extract Functions	
+-----------------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`extract.feature <extract.feature>`
+     - Return a partial GeoJSON object representing a single feature.
+   * - :ref:`extract.geometry <extract.geometry>`
+     - Return a GeoJSON object representing a single geometry.
+   * - :ref:`extract.point <extract.point>`
+     - Return an array of coordinates from a point.
+   * - :ref:`extract.multipoint <extract.multipoint>`
+     - Return an array of coordinates from a multipoint.  
+   * - :ref:`extract.linestring <extract.linestring>`
+     - Return an array of coordinate arrays from a linestring.
+   * - :ref:`extract.multilinestring <extract.multilinestring>`
+     - Return an array of linestring arrays from a linestring.
+   * - :ref:`extract.polygon <extract.polygon>`
+     - Return an array of linear ring arrays from a polygon.
+   * - :ref:`extract.multipolygon <extract.multipolygon>`
+     - Return an array of polygon arrays from a multipolygon.  
+   * - :ref:`extract.collection <extract.collection>`
+     - Return an array of geometries from a geometry collection.      
+     
+**Functions**	
+  
+.. _ZOO.Format.GeoJSON:                         
+  
+ZOO.Format.GeoJSON	
+  Create a new parser for GeoJSON.
+
+
+  *Parameters*
+
+  ``options {Object}`` An optional object whose properties will be set on this instance.
+  
+.. _read:                           
+  
+read	
+  ::
+  
+    read: function(json,type,filter)
+
+  Deserialize a GeoJSON string.
+
+  *Parameters*
+
+  | ``json {String}`` A GeoJSON string
+  | ``type {String}`` Optional string that determines the structure of the output.  Supported values are "Geometry", "Feature", and "FeatureCollection".  If absent or null, a default of "FeatureCollection" is assumed.
+  | ``filter {Function}`` A function which will be called for every key and value at every level of the final result.  Each value will be replaced by the result of the filter function.  This can be used to reform generic objects into instances of classes, or to transform date strings into Date objects.
+
+  *Returns*
+
+  ``{Object}`` The return depends on the value of the type argument.  If type is "FeatureCollection" (the default), 
+  the return will be an array of :ref:`ZOO.Feature <api-zoo-feature>`.  If type is "Geometry", the input json must 
+  represent a single geometry, and the return will be an :ref:`ZOO.Geometry <api-zoo-geometry>`.  If type 
+  is "Feature", the input json must represent a single feature, and the return will be an :ref:`ZOO.Feature <api-zoo-feature>`.
+  
+.. _isValidType:                             
+  
+isValidType	
+  ::
+  
+    isValidType: function(obj,type)
+
+  Check if a GeoJSON object is a valid representative of the given type.
+
+  *Returns*
+
+  ``{Boolean}`` The object is valid GeoJSON object of the given type.
+  
+.. _parseFeature:                               
+  
+parseFeature	
+  ::
+  
+    parseFeature: function(obj)
+
+  Convert a feature object from GeoJSON into a :ref:`ZOO.Feature <api-zoo-feature>`.
+
+  *Parameters*
+  
+  ``obj	{Object}`` An object created from a GeoJSON object
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A feature.  
+  
+.. _parseGeometry:                                 
+  
+parseGeometry	
+  ::
+  
+    parseGeometry: function(obj)
+
+  Convert a geometry object from GeoJSON into a :ref:`ZOO.Geometry <api-zoo-geometry>`.
+
+  *Parameters*
+  
+  ``obj {Object}`` An object created from a GeoJSON object
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` A geometry.
+  
+**parseCoords Properties**
+
+.. _parseCoords:                                 
+
+parseCoords	
+  Object with properties corresponding to the GeoJSON geometry types. Property 
+  values are functions that do the actual parsing.
+  
+**parseCoords Functions**
+
+.. _parseCoords.point:                                 
+
+parseCoords.point	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.Point <api-zoo-geometry-point>`.
+
+  *Parameters*
+
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A geometry.
+  
+.. _parseCoords.multipoint:                                   
+  
+parseCoords.multipoint	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.MultiPoint <api-zoo-geometry-multipoint>`.
+
+  *Parameters*
+  
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.MultiPoint} <api-zoo-geometry-multipoint>` A geometry.
+  
+.. _parseCoords.linestring:                                     
+  
+parseCoords.linestring	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.LineString <api-zoo-geometry-linestring>`.
+
+  *Parameters*
+  
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>` A geometry. 
+  
+.. _parseCoords.multilinestring: 
+  
+parseCoords.multilinestring	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.MultiLineString <api-zoo-geometry-multilinestring>`.
+
+  *Parameters*
+  
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.MultiLineString} <api-zoo-geometry-multilinestring>` A geometry.
+  
+.. _parseCoords.polygon:  
+  
+parseCoords.polygon	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.Polygon <api-zoo-geometry-polygon>`.
+
+  *Parameters*
+  
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A geometry.
+  
+.. _parseCoords.multipolygon:  
+
+parseCoords.multipolygon	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.MultiPolygon <api-zoo-geometry-multipolygon>`.
+  
+  *Parameters*
+
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.MultiPolygon} <api-zoo-geometry-multipolygon>` A geometry.  
+  
+.. _parseCoords.box:  
+  
+parseCoords.box	
+  Convert a coordinate array from GeoJSON into a :ref:`ZOO.Geometry.Polygon <api-zoo-geometry-polygon>`.
+
+  *Parameters*
+  
+  ``array {Object}`` The coordinates array from the GeoJSON fragment.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A geometry.  
+  
+.. _write:  
+  
+write	
+  ::
+  
+    write: function(obj,pretty)
+
+  Serialize a feature, geometry, array of features into a GeoJSON string.
+
+  *Parameters*
+  
+  | ``obj {Object}`` A :ref:`{ZOO.Feature} <api-zoo-feature>`, :ref:`{ZOO.Geometry} <api-zoo-geometry>`, or an array of features.
+  | ``pretty {Boolean}`` Structure the output with newlines and indentation.  Default is false.
+
+  *Returns*
+
+  ``{String}`` The GeoJSON string representation of the input geometry, features, or array of features. 
+  
+.. _createCRSObject:    
+  
+createCRSObject	
+  ::
+  
+    createCRSObject: function(object)
+
+  Create the CRS object for an object.
+  
+  *Parameters*
+  
+  ``object`` :ref:`{ZOO.Feature} <api-zoo-feature>`
+
+  *Returns*
+
+  ``{Object}`` An object which can be assigned to the crs property of a GeoJSON object. 
+  
+**extract Properties**
+
+.. _extract:    
+
+extract	
+  Object with properties corresponding to the GeoJSON types. Property values are 
+  functions that do the actual value extraction.
+  
+**extract Functions**
+
+.. _extract.feature:    
+
+extract.feature	
+  Return a partial GeoJSON object representing a single feature.
+
+
+  *Parameters*
+  
+  ``feature`` :ref:`{ZOO.Feature} <api-zoo-feature>`
+
+  *Returns*
+
+  ``{Object}`` An object representing the point.  
+  
+.. _extract.geometry:      
+  
+extract.geometry	
+  Return a GeoJSON object representing a single geometry.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+  *Returns*
+
+  ``{Object}`` An object representing the geometry. 
+  
+.. _extract.point:        
+  
+extract.point	
+  Return an array of coordinates from a point.
+
+  *Parameters*
+  
+  ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>`
+
+  *Returns*
+
+  ``{Array}`` An array of coordinates representing the point. 
+  
+.. _extract.multipoint:          
+  
+extract.multipoint	
+  Return an array of coordinates from a multipoint.
+
+  *Parameters*
+  
+  ``multipoint`` :ref:`{ZOO.Geometry.MultiPoint} <api-zoo-geometry-multipoint>`
+
+  *Returns*
+
+  ``{Array}`` An array of point coordinate arrays representing the multipoint.
+  
+.. _extract.linestring:            
+  
+extract.linestring	
+  Return an array of coordinate arrays from a linestring.
+
+  *Parameters*
+  
+  ``linestring`` :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>`
+
+  *Returns*
+
+  ``{Array}`` An array of coordinate arrays representing the linestring. 
+  
+.. _extract.multilinestring:              
+  
+extract.multilinestring	
+  Return an array of linestring arrays from a linestring.
+
+  *Parameters*
+  
+  ``multilinestring`` :ref:`{ZOO.Geometry.MultiLineString} <api-zoo-geometry-multilinestring>`
+
+  *Returns*
+
+  ``{Array}`` An array of linestring arrays representing the multilinestring. 
+  
+.. _extract.polygon:             
+  
+extract.polygon	
+  Return an array of linear ring arrays from a polygon.
+
+  *Parameters*
+  
+  ``polygon`` :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>`
+  
+  *Returns*
+
+  ``{Array}`` An array of linear ring arrays representing the polygon. 
+  
+.. _extract.multipolygon:                 
+  
+extract.multipolygon	
+  Return an array of polygon arrays from a multipolygon.
+  
+  *Parameters*
+  
+  ``multipolygon`` :ref:`{ZOO.Geometry.MultiPolygon} <api-zoo-geometry-multipolygon>`
+
+  *Returns*
+
+  ``{Array}`` An array of polygon arrays representing the multipolygon  
+  
+.. _extract.collection:  
+  
+extract.collection	
+  Return an array of geometries from a geometry collection.
+
+  *Parameters*
+
+  ``collection`` :ref:`{ZOO.Geometry.Collection} <api-zoo-geometry-collection>`
+
+  *Returns*
+
+  ``{Array}`` An array of geometry objects representing the geometry collection.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-gml.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-gml.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-gml.txt	(revision 672)
@@ -0,0 +1,446 @@
+.. _api-zoo-format-gml:
+
+ZOO.Format.GML
+==============
+
+Read/Write GML.
+
+Inherits from
+
+- :ref:`ZOO.Format <api-zoo-format>`
+
+Properties and Functions	
+------------------------
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`schemaLocation <schemaLocation>`
+     - {String} Schema location for a particular minor version.
+   * - :ref:`namespaces <namespaces>`
+     - {Object} Mapping of namespace aliases to namespace URIs.
+   * - :ref:`defaultPrefix <defaultPrefix>`
+     - 
+   * - :ref:`collectionName <collectionName>`
+     - {String} Name of featureCollection element. 
+   * - :ref:`featureName <featureName>`
+     - {String} Element name for features. 
+   * - :ref:`geometryName <geometryName>`
+     - {String} Name of geometry element.
+   * - :ref:`xy <xy>`
+     - {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x) Changing is not recommended, a new Format should be instantiated.
+   * - :ref:`extractAttributes <extractAttributes>`
+     - {Boolean} Could we extract attributes
+   * - :ref:`ZOO.Format.GML <ZOO.Format.GML>`
+     - Create a new parser for GML.
+   * - :ref:`read <read>`
+     - Read data from a string, and return a list of features. 
+   * - :ref:`parseFeature <parseFeature>`
+     - This function is the core of the GML parsing code in ZOO.
+   * - :ref:`parseGeometry <parseGeometry>`
+     - Properties of this object are the functions that parse geometries based on their type.
+   * - :ref:`parseGeometry.point <parseGeometry.point>`
+     - Given a GML node representing a point geometry, create a ZOO point geometry.  
+   * - :ref:`parseGeometry.multipoint <parseGeometry.multipoint>`
+     - Given a GML node representing a point geometry, create a ZOO multipoint geometry.     
+   * - :ref:`parseGeometry.linestring <parseGeometry.linestring>`
+     - Given a GML node representing a linestring geometry, create a ZOO linestring geometry.
+   * - :ref:`parseGeometry.polygon <parseGeometry.polygon>`
+     - Given a GML node representing a polygon geometry, create a ZOO polygon geometry.
+   * - :ref:`parseGeometry.multigeometry <parseGeometry.multigeometry>`
+     - Given a GML node representing a multigeometry, create a ZOO geometry collection.
+   * - :ref:`parseAttributes <parseAttributes>`
+     -  
+   * - :ref:`parseExtendedData <parseExtendedData>`
+     - Parse ExtendedData from GML.  
+   * - :ref:`write <write>`
+     - Accept Feature Collection, and return a string.
+   * - :ref:`createFeature <createFeature>`
+     - Accept an ZOO.Feature, and build a GML node for it.
+   * - :ref:`buildGeometryNode <buildGeometryNode>`
+     - Builds and returns a GML geometry node with the given geometry.
+   * - :ref:`buildGeometry <buildGeometry>`
+     - Object containing methods to do the actual geometry node building based on geometry type.
+   * - :ref:`buildGeometry.point <buildGeometry.point>`
+     - Given a ZOO point geometry, create a GML point.     
+   * - :ref:`buildGeometry.multipoint <buildGeometry.multipoint>`
+     - Given a ZOO multipoint geometry, create a GML GeometryCollection.
+   * - :ref:`buildGeometry.linestring <buildGeometry.linestring>`
+     -  Given a ZOO linestring geometry, create a GML linestring.
+   * - :ref:`buildGeometry.multilinestring <buildGeometry.multilinestring>`
+     - Given a ZOO multilinestring geometry, create a GML GeometryCollection. 
+   * - :ref:`buildGeometry.linearring <buildGeometry.linearring>`
+     - Given a ZOO linearring geometry, create a GML linearring.
+   * - :ref:`buildGeometry.polygon <buildGeometry.polygon>`
+     - Given a ZOO polygon geometry, create a GML polygon.
+   * - :ref:`buildGeometry.multipolygon <buildGeometry.multipolygon>`
+     - Given a ZOO multipolygon geometry, create a GML GeometryCollection.
+   * - :ref:`buildGeometry.collection <buildGeometry.collection>`
+     - Given a ZOO geometry collection, create a GML MultiGeometry.
+   * - :ref:`buildCoordinatesNode <buildCoordinatesNode>`
+     - builds the coordinates XmlNode 
+
+.. _schemaLocation:  
+  		
+schemaLocation	
+  ``{String}`` Schema location for a particular minor version.
+  
+.. _namespaces:    
+  
+namespaces	
+  ``{Object}`` Mapping of namespace aliases to namespace URIs.
+
+.. _defaultPrefix:    
+
+defaultPrefix
+
+.. _collectionName:    
+
+collectionName	
+  ``{String}`` Name of featureCollection element.
+  
+.. _featureName:      
+  
+featureName	
+  ``{String}`` Element name for features. Default is "sql_statement".
+  
+.. _geometryName:        
+  
+geometryName	
+  ``{String}`` Name of geometry element. Defaults to "geometryProperty".
+  
+.. _xy:          
+  
+xy	
+  ``{Boolean}`` Order of the GML coordinate true:(x,y) or false:(y,x) Changing is not recommended, a new Format should be instantiated.
+
+.. _extractAttributes:          
+
+extractAttributes	
+  ``{Boolean}`` Could we extract attributes
+  
+.. _ZOO.Format.GML:            
+  
+ZOO.Format.GML	
+  Create a new parser for GML.
+
+  *Parameters*
+  
+  ``options {Object}`` An optional object whose properties will be set on this instance.  
+  
+.. _read:              
+  
+read	
+  ::
+  
+    read: function(data)
+
+  Read data from a string, and return a list of features.
+
+  *Parameters*
+  
+  ``data {String}`` data to read/parse.
+
+  *Returns*
+
+  :ref:`{Array(ZOO.Feature)} <api-zoo-feature>` An array of features.  
+  
+.. _parseFeature:  
+  
+parseFeature	
+  ::
+  
+    parseFeature: function(node)
+
+  This function is the core of the GML parsing code in ZOO.  It creates the geometries 
+  that are then attached to the returned feature, and calls parseAttributes() to get 
+  attribute data out.
+  
+  *Parameters*
+  
+  ``node {E4XElement}``
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A vector feature.  
+  
+.. _parseGeometry:    
+  
+parseGeometry	
+  Properties of this object are the functions that parse geometries based on their type.
+  
+.. _parseGeometry.point:      
+  
+parseGeometry.point	
+  Given a GML node representing a point geometry, create a ZOO point geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A point geometry. 
+  
+.. _parseGeometry.multipoint:        
+  
+parseGeometry.multipoint	
+  Given a GML node representing a multipoint geometry, create a ZOO multipoint geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A multipoint geometry.   
+  
+.. _parseGeometry.linestring:          
+  
+parseGeometry.linestring	
+  Given a GML node representing a linestring geometry, create a ZOO linestring geometry.
+  
+  *Parameters*
+    
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+  
+  :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>` A linestring geometry. 
+
+.. _parseGeometry.multilinestring:          
+
+parseGeometry.multilinestring	
+  Given a GML node representing a multilinestring geometry, create a ZOO multilinestring geometry.
+  
+  *Parameters*
+    
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+  
+  :ref:`{ZOO.Geometry.MultiLineString} <api-zoo-geometry-multilinestring>` A multilinestring geometry.   
+
+.. _parseGeometry.polygon:          
+
+parseGeometry.polygon	
+  Given a GML node representing a polygon geometry, create a ZOO polygon geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A polygon geometry.   
+
+.. _parseGeometry.multipolygon:          
+
+parseGeometry.multipolygon	
+  Given a GML node representing a multipolygon geometry, create a ZOO multipolygon geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.MultiPolygon} <api-zoo-geometry-multipolygon>` A multipolygon geometry.  
+
+.. _parseGeometry.envelope:          
+
+parseGeometry.envelope	
+  Given a GML node representing an envelope, create a ZOO polygon geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A GML node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A polygon geometry.  
+
+.. _parseAttributes:          
+
+parseAttributes	
+  ::
+  
+    parseAttributes: function(node)
+
+  *Parameters*
+  
+  ``node {E4XElement}``
+  
+  *Returns*
+
+  ``{Object}`` An attributes object.
+
+.. _write:          
+
+write	
+  ::
+  
+    write: function(features)
+
+  Generate a GML document string given a list of features.
+  
+  *Parameters*
+  
+  ``features`` :ref:`{Array(ZOO.Feature)} <api-zoo-feature>` List of features to serialize into a string.
+
+  *Returns*
+
+  ``{String}`` A string representing the GML document.
+  
+.. _createFeature:          
+
+createFeature	
+  ::
+  
+    createFeature: function(feature)
+
+  Accept an ZOO.Feature, and build a GML node for it.
+  
+  *Parameters*
+  
+  ``feature`` :ref:`{ZOO.Feature} <api-zoo-feature>` The feature to be built as GML.
+  
+  *Returns*
+
+  ``{E4XElement}`` A node reprensting the feature in GML.
+  
+.. _buildGeometryNode:          
+
+buildGeometryNode
+  ::
+  
+    buildGeometryNode: function(geometry)
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` The geometry to be built as GML.
+  
+  *Returns*
+
+  ``{E4XElement}`` A node reprensting the geometry in GML.
+
+.. _buildGeometry:          
+
+buildGeometry	
+  Object containing methods to do the actual geometry node building based on geometry type.
+
+.. _buildGeometry.point:          
+
+buildGeometry.point	
+  Given a ZOO point geometry, create a GML point.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A point geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML point node.
+  
+.. _buildGeometry.multipoint:          
+
+buildGeometry.multipoint	
+  Given a ZOO multipoint geometry, create a GML multipoint.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.MultiPoint} <api-zoo-geometry-multipoint>` A multipoint geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML multipoint node.  
+
+.. _buildGeometry.linestring:          
+
+buildGeometry.linestring	
+  Given a ZOO linestring geometry, create a GML linestring.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>` A linestring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML linestring node.
+  
+.. _buildGeometry.multilinestring:          
+
+buildGeometry.multilinestring	
+  Given a ZOO multilinestring geometry, create a GML multilinestring.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.MultiLineString} <api-zoo-geometry-multilinestring>` A multilinestring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML multilinestring node.  
+
+.. _buildGeometry.linearring:          
+
+buildGeometry.linearring	
+  Given a ZOO linearring geometry, create a GML linearring.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.LinearRing} <api-zoo-geometry-linearring>` A linearring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML linearring node.
+  
+.. _buildGeometry.polygon:          
+
+buildGeometry.polygon	
+  Given an ZOO polygon geometry, create a GML polygon.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A polygon geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML polygon node.
+  
+.. _buildGeometry.multipolygon:          
+
+buildGeometry.multipolygon	
+  Given a ZOO multipolygon geometry, create a GML multipolygon.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.MultiPolygon} <api-zoo-geometry-multipolygon>` A multipolygon geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A GML multipolygon node.  
+
+.. _buildCoordinatesNode:          
+
+buildCoordinatesNode	
+  ::
+  
+    buildCoordinatesNode: function(geometry)
+
+  builds the coordinates XmlNode
+
+    ::
+    
+      <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+
+  *Returns*
+
+  ``{E4XElement}`` created E4XElement  
+  
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-json.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-json.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-json.txt	(revision 672)
@@ -0,0 +1,287 @@
+.. _api-zoo-format-json:
+
+ZOO.Format.JSON
+===============
+
+A parser to read/write JSON safely.
+
+Inherits from
+
+- :ref:`ZOO.Format <api-zoo-format>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`indent <indent>`
+     - {String} For "pretty" printing, the indent string will be used once for each indentation level.
+   * - :ref:`space <space>`
+     - {String} For "pretty" printing, the space string will be used after the ":" separating a name/value pair.
+   * - :ref:`newline <newline>`
+     - {String} For "pretty" printing, the newline string will be used at the end of each name/value pair or array item.
+   * - :ref:`level <level>`
+     - {Integer} For "pretty" printing, this is incremented/decremented during serialization.  
+   * - :ref:`pretty <pretty>`
+     - {Boolean} Serialize with extra whitespace for structure.    
+     
+Functions	
+---------
+
+.. list-table::
+   :widths: 14 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Format.JSON <ZOO.Format.JSON>`
+     - Create a new parser for JSON.
+   * - :ref:`read <read>`
+     - Deserialize a json string.
+   * - :ref:`write <write>`
+     - Serialize an object into a JSON string.
+   * - :ref:`writeIndent <writeIndent>`
+     - Output an indentation string depending on the indentation level.  
+   * - :ref:`writeNewline <writeNewline>`
+     - Output a string representing a newline if in pretty printing mode.   
+   * - :ref:`writeSpace <writeSpace>`
+     - Output a string representing a space if in pretty printing mode. 
+     
+Serialize Properties	
+--------------------
+
+.. list-table::
+   :widths: 14 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`serialize <serialize>`
+     - Object with properties corresponding to the serializable data types. 
+     
+Serialize Functions	
+-------------------
+
+.. list-table::
+   :widths: 14 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`serialize.object <serialize.object>`
+     - Transform an object into a JSON string.
+   * - :ref:`serialize.array <serialize.array>`
+     - Transform an array into a JSON string.
+   * - :ref:`serialize.string <serialize.string>`
+     - Transform a string into a JSON string.
+   * - :ref:`serialize.number <serialize.number>`
+     - Transform a number into a JSON string.  
+   * - :ref:`serialize.boolean <serialize.boolean>`
+     - Transform a boolean into a JSON string.   
+   * - :ref:`serialize.date <serialize.date>`
+     - Transform a date into a JSON string.     
+       
+**Properties**
+
+.. _indent:   
+
+indent	
+  ``{String}`` For "pretty" printing, the indent string will be used once for each indentation level.
+  
+.. _space:     
+  
+space	
+  ``{String}`` For "pretty" printing, the space string will be used after the ":" separating a name/value pair.
+  
+.. _newline:       
+  
+newline	
+  ``{String}`` For "pretty" printing, the newline string will be used at the end of each name/value pair or array item.
+  
+.. _level:        
+  
+level	
+  ``{Integer}`` For "pretty" printing, this is incremented/decremented during serialization.
+  
+.. _pretty:          
+  
+pretty	
+  ``{Boolean}`` Serialize with extra whitespace for structure. This is set by the :ref:`write <write>` method.
+  
+**Functions**
+
+.. _ZOO.Format.JSON:          
+
+ZOO.Format.JSON	
+  Create a new parser for JSON.
+
+  *Parameters*
+  
+  ``options {Object}`` An optional object whose properties will be set on this instance. 
+  
+.. _read:            
+  
+read	
+  ::
+  
+    read: function(json,filter)
+
+  Deserialize a json string.
+
+  *Parameters*
+  
+  | ``json {String}`` A JSON string
+  | ``filter {Function}`` A function which will be called for every key and value at every level of the final result.  Each value will be replaced by the result of the filter function.  This can be used to reform generic objects into instances of classes, or to transform date strings into Date objects.
+
+  *Returns*
+
+  ``{Object}`` An object, array, string, or number.
+  
+.. _write:              
+  
+write	
+  ::
+  
+    write: function(value,pretty)
+
+  Serialize an object into a JSON string.
+
+  *Parameters*
+  
+  | ``value {String}`` The object, array, string, number, boolean or date to be serialized.
+  | ``pretty {Boolean}`` Structure the output with newlines and indentation.  Default is false.
+
+  *Returns*
+
+  ``{String}`` The JSON string representation of the input value.  
+  
+.. _writeIndent:               
+  
+writeIndent	
+  ::
+  
+    writeIndent: function()
+
+  Output an indentation string depending on the indentation level.
+  
+  *Returns*
+
+  ``{String}`` An appropriate indentation string.
+  
+.. _writeNewline:               
+  
+writeNewline	
+  ::
+  
+    writeNewline: function()
+
+  Output a string representing a newline if in pretty printing mode.
+  
+  *Returns*
+
+  ``{String}`` A string representing a new line.
+  
+.. _writeSpace:               
+  
+writeSpace	
+  ::
+  
+    writeSpace: function()
+
+  Output a string representing a space if in pretty printing mode.  
+
+  *Returns*
+
+  ``{String}`` A space.
+  
+**Serialize Properties**
+
+.. _serialize:               
+
+serialize	
+  Object with properties corresponding to the serializable data types. Property 
+  values are functions that do the actual serializing.
+  
+**Serialize Functions**
+
+.. _serialize.object:               
+
+serialize.object	
+  Transform an object into a JSON string.
+
+  *Parameters*
+
+  ``object {Object}`` The object to be serialized.
+  
+  *Returns*
+
+  ``{String}`` A JSON string representing the object. 
+  
+.. _serialize.array:                 
+  
+serialize.array	
+  Transform an array into a JSON string.
+
+  *Parameters*
+  
+  ``array {Array}`` The array to be serialized
+
+  *Returns*
+
+  ``{String}`` A JSON string representing the array. 
+  
+.. _serialize.string:                   
+  
+serialize.string	
+  Transform a string into a JSON string.
+
+  *Parameters*
+  
+  ``string {String}`` The string to be serialized
+
+  *Returns*
+
+  ``{String}`` A JSON string representing the string. 
+  
+.. _serialize.number:                     
+  
+serialize.number	
+  Transform a number into a JSON string.
+
+  *Parameters*
+  
+  ``number {Number}`` The number to be serialized.
+  
+  *Returns*
+
+  ``{String}`` A JSON string representing the number.  
+  
+.. _serialize.boolean:                       
+  
+serialize.boolean	
+  Transform a boolean into a JSON string.
+
+  *Parameters*
+  
+  ``bool {Boolean}`` The boolean to be serialized.
+
+  *Returns*
+
+  ``{String}`` A JSON string representing the boolean. 
+  
+.. _serialize.date:                         
+  
+serialize.date	
+  Transform a date into a JSON string.
+
+  *Parameters*
+  
+  ``date {Date}`` The date to be serialized.
+
+  *Returns*
+
+  ``{String}`` A JSON string representing the date.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-kml.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-kml.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-kml.txt	(revision 672)
@@ -0,0 +1,412 @@
+.. _api-zoo-format-kml:
+
+ZOO.Format.KML
+==============
+
+Read/Write KML.
+
+Inherits from
+
+- :ref:`ZOO.Format <api-zoo-format>`
+
+Properties and Functions	
+------------------------
+
+.. list-table::
+   :widths: 20 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`kmlns <kmlns>`
+     - {String} KML Namespace to use.
+   * - :ref:`foldersName <foldersName>`
+     - {String} Name of the folders.
+   * - :ref:`foldersDesc <foldersDesc>`
+     - {String} Description of the folders.
+   * - :ref:`placemarksDesc <placemarksDesc>`
+     - {String} Name of the placemarks. 
+   * - :ref:`extractAttributes <extractAttributes>`
+     - {Boolean} Extract attributes from KML.   
+   * - :ref:`ZOO.Format.KML <ZOO.Format.KML>`
+     - Create a new parser for KML.
+   * - :ref:`parseFeatures <parseFeatures>`
+     - Loop through all Placemark nodes and parse them.
+   * - :ref:`parseFeature <parseFeature>`
+     - This function is the core of the KML parsing code in ZOO.
+   * - :ref:`parseGeometry <parseGeometry>`
+     - Properties of this object are the functions that parse geometries based on their type.
+   * - :ref:`parseGeometry.point <parseGeometry.point>`
+     - Given a KML node representing a point geometry, create a ZOO point geometry.  
+   * - :ref:`parseGeometry.linestring <parseGeometry.linestring>`
+     - Given a KML node representing a linestring geometry, create a ZOO linestring geometry.
+   * - :ref:`parseGeometry.polygon <parseGeometry.polygon>`
+     - Given a KML node representing a polygon geometry, create a ZOO polygon geometry.
+   * - :ref:`parseGeometry.multigeometry <parseGeometry.multigeometry>`
+     - Given a KML node representing a multigeometry, create a ZOO geometry collection.
+   * - :ref:`parseAttributes <parseAttributes>`
+     -  
+   * - :ref:`parseExtendedData <parseExtendedData>`
+     - Parse ExtendedData from KML.  
+   * - :ref:`write <write>`
+     - Accept Feature Collection, and return a string.
+   * - :ref:`createPlacemark <createPlacemark>`
+     - Creates and returns a KML placemark node representing the given feature.
+   * - :ref:`buildGeometryNode <buildGeometryNode>`
+     - Builds and returns a KML geometry node with the given geometry.
+   * - :ref:`buildGeometry <buildGeometry>`
+     - Object containing methods to do the actual geometry node building based on geometry type.
+   * - :ref:`buildGeometry.point <buildGeometry.point>`
+     - Given a ZOO point geometry, create a KML point.     
+   * - :ref:`buildGeometry.multipoint <buildGeometry.multipoint>`
+     - Given a ZOO multipoint geometry, create a KML GeometryCollection.
+   * - :ref:`buildGeometry.linestring <buildGeometry.linestring>`
+     -  Given a ZOO linestring geometry, create a KML linestring.
+   * - :ref:`buildGeometry.multilinestring <buildGeometry.multilinestring>`
+     - Given a ZOO multilinestring geometry, create a KML GeometryCollection. 
+   * - :ref:`buildGeometry.linearring <buildGeometry.linearring>`
+     - Given a ZOO linearring geometry, create a KML linearring.
+   * - :ref:`buildGeometry.polygon <buildGeometry.polygon>`
+     - Given a ZOO polygon geometry, create a KML polygon.
+   * - :ref:`buildGeometry.multipolygon <buildGeometry.multipolygon>`
+     - Given a ZOO multipolygon geometry, create a KML GeometryCollection.
+   * - :ref:`buildGeometry.collection <buildGeometry.collection>`
+     - Given a ZOO geometry collection, create a KML MultiGeometry.
+   * - :ref:`buildCoordinatesNode <buildCoordinatesNode>`
+     - Builds and returns the KML coordinates node with the given geometry <coordinates>...</coordinates> 
+
+.. _kmlns:  
+  	
+kmlns	
+  ``{String}`` KML Namespace to use. Defaults to 2.2 namespace.
+  
+.. _foldersName:  
+  
+foldersName	
+  ``{String}`` Name of the folders. Default is "ZOO export".  If set to null, no name element will be created.
+  
+.. _foldersDesc:    
+  
+foldersDesc	
+  ``{String}`` Description of the folders. Default is "Exported on [date]."  If set to null, no description element will be created.
+  
+.. _placemarksDesc:      
+  
+placemarksDesc	
+  ``{String}`` Name of the placemarks. Default is "No description available".
+  
+.. _extractAttributes:        
+  
+extractAttributes	
+  ``{Boolean}`` Extract attributes from KML. Default is true.  Extracting styleUrls requires this to be set to true
+  
+.. _ZOO.Format.KML:          
+  
+ZOO.Format.KML	
+  Create a new parser for KML.
+
+  *Parameters*
+  
+  ``options {Object}`` An optional object whose properties will be set on this instance.
+  
+.. _parseFeatures:            
+  
+parseFeatures	
+  ::
+  
+    parseFeatures: function(nodes)
+
+  Loop through all Placemark nodes and parse them.  Will create a list of features
+
+  *Parameters*
+  
+  | ``nodes {Array}`` of {E4XElement} data to read/parse.
+  | ``options {Object}`` Hash of options
+  
+.. _parseFeature:              
+  
+parseFeature	
+  ::
+  
+    parseFeature: function(node)
+
+  This function is the core of the KML parsing code in ZOO.  It creates the geometries 
+  that are then attached to the returned feature, and calls parseAttributes() to get 
+  attribute data out.
+  
+  *Parameters*
+  
+  ``node {E4XElement}``
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A vector feature.  
+  
+.. _parseGeometry:                
+  
+parseGeometry	
+  Properties of this object are the functions that parse geometries based on their type.
+  
+.. _parseGeometry.point:                  
+  
+parseGeometry.point	
+  Given a KML node representing a point geometry, create a ZOO point geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A KML Point node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A point geometry. 
+  
+.. _parseGeometry.linestring:                    
+  
+parseGeometry.linestring	
+  Given a KML node representing a linestring geometry, create a ZOO linestring geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A KML LineString node.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>` A linestring geometry. 
+  
+.. _parseGeometry.polygon:                      
+  
+parseGeometry.polygon	
+  Given a KML node representing a polygon geometry, create a ZOO polygon geometry.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A KML Polygon node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A polygon geometry. 
+  
+.. _parseGeometry.multigeometry:                        
+  
+parseGeometry.multigeometry	
+  Given a KML node representing a multigeometry, create a ZOO geometry collection.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A KML MultiGeometry node.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Collection} <api-zoo-geometry-collection>` A geometry collection.  
+  
+.. _parseAttributes:                          
+  
+parseAttributes	
+  ::
+  
+    parseAttributes: function(node)
+
+  *Parameters*
+  
+  ``node {E4XElement}``
+  
+  *Returns*
+
+  ``{Object}`` An attributes object.
+
+.. _parseExtendedData:
+
+parseExtendedData	
+  ::
+  
+    parseExtendedData: function(node)
+
+  Parse ExtendedData from KML.  Limited support for schemas/datatypes.  See http://code.google.com/apis/kml/documentation/kmlreference.html#extendeddata 
+  for more information on extendeddata.
+  
+  *Parameters*
+  
+  ``node {E4XElement}``
+  
+  *Returns*
+
+  ``{Object}`` An attributes object. 
+  
+.. _write:  
+  
+write	
+  ::
+  
+    write: function(features)
+
+  Accept Feature Collection, and return a string.
+
+  *Parameters*
+  
+  ``features`` :ref:`{Array(ZOO.Feature)} <api-zoo-feature>` An array of features.
+  
+  *Returns*
+
+  ``{String}`` A KML string.  
+  
+.. _createPlacemark:   
+  
+createPlacemark	
+  ::
+  
+    createPlacemark: function(feature)
+
+  Creates and returns a KML placemark node representing the given feature.
+
+  *Parameters*
+  
+  ``feature`` :ref:`{ZOO.Feature} <api-zoo-feature>`
+  
+  *Returns*
+
+  ``{E4XElement}``
+  
+.. _buildGeometryNode:     
+  
+buildGeometryNode	
+  ::
+  
+    buildGeometryNode: function(geometry)
+
+  Builds and returns a KML geometry node with the given geometry.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+
+  *Returns*
+
+  ``{E4XElement}``
+  
+.. _buildGeometry:       
+  
+buildGeometry	
+  Object containing methods to do the actual geometry node building based on geometry type.
+  
+.. _buildGeometry.point:         
+  
+buildGeometry.point	
+  Given a ZOO point geometry, create a KML point.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A point geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML point node.  
+  
+.. _buildGeometry.multipoint:           
+  
+buildGeometry.multipoint	
+  Given a ZOO multipoint geometry, create a KML GeometryCollection.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.MultiPoint} <api-zoo-geometry-multipoint>` A multipoint geometry.
+  
+  *Returns*
+
+  ``{E4XElement}`` A KML GeometryCollection node. 
+  
+.. _buildGeometry.linestring:             
+  
+buildGeometry.linestring	
+  Given a ZOO linestring geometry, create a KML linestring.
+  
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.LineString} <api-zoo-geometry-linestring>` A linestring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML linestring node.
+  
+.. _buildGeometry.multilinestring:               
+  
+buildGeometry.multilinestring	
+  Given a ZOO multilinestring geometry, create a KML GeometryCollection.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.MultiLineString} <api-zoo-geometry-multilinestring>` A multilinestring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML GeometryCollection node. 
+  
+.. _buildGeometry.linearring:                 
+  
+buildGeometry.linearring	
+  Given a ZOO linearring geometry, create a KML linearring.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.LinearRing} <api-zoo-geometry-linearring>` A linearring geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML linearring node.  
+  
+.. _buildGeometry.polygon:                   
+  
+buildGeometry.polygon	
+  Given a ZOO polygon geometry, create a KML polygon.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Polygon} <api-zoo-geometry-polygon>` A polygon geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML polygon node.  
+  
+.. _buildGeometry.multipolygon:                     
+  
+buildGeometry.multipolygon	
+  Given a ZOO multipolygon geometry, create a KML GeometryCollection.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` A multipolygon geometry.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML GeometryCollection node.  
+  
+.. _buildGeometry.collection:                       
+  
+buildGeometry.collection	
+  Given a ZOO geometry collection, create a KML MultiGeometry.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry.Collection} <api-zoo-geometry-collection>` A geometry collection.
+
+  *Returns*
+
+  ``{E4XElement}`` A KML MultiGeometry node.  
+  
+.. _buildCoordinatesNode:                         
+  
+buildCoordinatesNode	
+  ::
+  
+    buildCoordinatesNode: function(geometry)
+
+  Builds and returns the KML coordinates node with the given geometry <coordinates>...</coordinates>
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+
+  *Return*
+
+  ``{E4XElement}`` 
+  
+  
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wkt.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wkt.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wkt.txt	(revision 672)
@@ -0,0 +1,196 @@
+.. _api-zoo-format-wkt:
+
+ZOO.Format.WKT
+==============
+
+Class for reading and writing Well-Known Text.
+
+Inherits from
+
+- :ref:`ZOO.Format <api-zoo-format>`
+
+Functions and Properties	
+------------------------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Format.WKT <ZOO.Format.WKT>`
+     - Create a new parser for WKT
+   * - :ref:`read <read>`
+     - Deserialize a WKT string and return a vector feature or an array of vector features.
+   * - :ref:`write <write>`
+     - Serialize a feature or array of features into a WKT string.
+   * - :ref:`extract <extract>`
+     - Object with properties corresponding to the geometry types.   
+   * - :ref:`parse <parse>`
+     - Object with properties corresponding to the geometry types.
+   * - :ref:`parse.point <parse.point>`
+     - Return point feature given a point WKT fragment.   
+   * - :ref:`parse.multipoint <parse.multipoint>`
+     - Return a multipoint feature given a multipoint WKT fragment.
+   * - :ref:`parse.linestring <parse.linestring>`
+     - Return a linestring feature given a linestring WKT fragment. 
+   * - :ref:`parse.multilinestring <parse.multilinestring>`
+     - Return a multilinestring feature given a multilinestring WKT fragment.
+   * - :ref:`parse.polygon <parse.polygon>`
+     - Return a polygon feature given a polygon WKT fragment.
+   * - :ref:`parse.multipolygon <parse.multipolygon>`
+     - Return a multipolygon feature given a multipolygon WKT fragment.
+   * - :ref:`parse.geometrycollection <parse.geometrycollection>`
+     - Return an array of features given a geometrycollection WKT fragment.     
+       
+.. _ZOO.Format.WKT:   
+
+ZOO.Format.WKT	
+  Create a new parser for WKT
+
+  *Parameters*
+  
+  ``options {Object}`` An optional object whose properties will be set on this instance
+
+  *Returns*
+
+  :ref:`{ZOO.Format.WKT} <api-zoo-format-wkt>` A new WKT parser. 
+  
+.. _read:     
+  
+read	
+  ::
+  
+    read: function(wkt)
+
+  Deserialize a WKT string and return a vector feature or an array of vector features.  
+  Supports WKT for POINT, MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, 
+  and GEOMETRYCOLLECTION.
+  
+  *Parameters*
+  
+  ``wkt	{String}`` A WKT string
+  
+  *Returns*
+
+  {<ZOO.Feature.Vector>|Array} A feature or array of features for GEOMETRYCOLLECTION WKT. 
+  
+.. _write:       
+  
+write	
+  ::
+  
+    write: function(features)
+
+  Serialize a feature or array of features into a WKT string.
+  
+  *Parameters*
+  
+  ``features {<ZOO.Feature.Vector>|Array}`` A feature or array of features
+
+  *Returns*
+
+  ``{String}`` The WKT string representation of the input geometries 
+  
+.. _extract:         
+  
+extract	
+  Object with properties corresponding to the geometry types. Property values are 
+  functions that do the actual data extraction.
+  
+.. _parse:           
+  
+parse	
+  Object with properties corresponding to the geometry types. Property values are 
+  functions that do the actual parsing.
+  
+.. _parse.point:             
+  
+parse.point	
+  Return point feature given a point WKT fragment.
+  
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the point 
+  
+  *Returns*
+  
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A point feature  
+  
+.. _parse.multipoint:               
+  
+parse.multipoint	
+  Return a multipoint feature given a multipoint WKT fragment.
+
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the multipoint
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A multipoint feature 
+  
+.. _parse.linestring:                
+ 
+parse.linestring	
+  Return a linestring feature given a linestring WKT fragment.
+
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the linestring
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A linestring feature
+  
+.. _parse.multilinestring:                  
+  
+parse.multilinestring	
+  Return a multilinestring feature given a multilinestring WKT fragment.
+  
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the multilinestring
+  
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A multilinestring feature  
+  
+.. _parse.polygon:                  
+  
+parse.polygon	
+  Return a polygon feature given a polygon WKT fragment.
+
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the polygon
+  
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A polygon feature 
+  
+.. _parse.multipolygon:                    
+  
+parse.multipolygon	
+  Return a multipolygon feature given a multipolygon WKT fragment.
+
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the multipolygon
+
+  *Returns*
+
+  :ref:`{ZOO.Feature} <api-zoo-feature>` A multipolygon feature  
+  
+.. _parse.geometrycollection:                      
+  
+parse.geometrycollection	
+  Return an array of features given a geometrycollection WKT fragment.
+
+  *Parameters*
+  
+  ``str	{String}`` A WKT fragment representing the geometrycollection
+
+  *Returns*
+
+  ``{Array}`` An array of ZOO.Feature
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wps.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wps.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format-wps.txt	(revision 672)
@@ -0,0 +1,120 @@
+.. _api-zoo-format-wps:
+
+ZOO.Format.WPS
+==============
+
+Read/Write WPS.
+
+Inherits from
+
+- :ref:`ZOO.Format <api-zoo-format>`
+
+Functions and Properties	
+------------------------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`schemaLocation <schemaLocation>`
+     - {String} Schema location for a particular minor version.
+   * - :ref:`namespaces <namespaces>`
+     - {Object} Mapping of namespace aliases to namespace URIs.
+   * - :ref:`read <read>`
+     - 
+   * - :ref:`parseExecuteResponse <parseExecuteResponse>`
+     -   
+   * - :ref:`parseData <parseData>`
+     - Object containing methods to analyse data response.
+   * - :ref:`parseData.complexdata <parseData.complexdata>`
+     - Given an Object representing the WPS complex data response.   
+   * - :ref:`parseData.literaldata <parseData.literaldata>`
+     - Given an Object representing the WPS literal data response.
+   * - :ref:`parseData.reference <parseData.reference>`
+     - Given an Object representing the WPS reference response. 
+       
+.. _schemaLocation:   
+
+schemaLocation	
+  ``{String}`` Schema location for a particular minor version.
+  
+.. _namespaces:   
+  
+namespaces	
+  ``{Object}`` Mapping of namespace aliases to namespace URIs.
+  
+.. _read:     
+  
+read
+  ::
+  
+    read:function(data)
+
+  *Parameters*
+  
+  ``data {String}`` A WPS xml document
+  
+  *Returns*
+
+  ``{Object}`` Execute response.
+
+.. _parseExecuteResponse:     
+
+parseExecuteResponse	
+  ::
+  
+    parseExecuteResponse: function(node)
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A WPS ExecuteResponse document
+
+  *Returns*
+
+  ``{Object}`` Execute response.
+
+.. _parseData:     
+
+parseData	
+  Object containing methods to analyse data response.
+  
+.. _parseData.complexdata:       
+  
+parseData.complexdata	
+  Given an Object representing the WPS complex data response.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A WPS node.
+  
+  *Returns*
+
+  ``{Object}`` A WPS complex data response.  
+  
+.. _parseData.literaldata:         
+  
+parseData.literaldata	
+  Given an Object representing the WPS literal data response.\
+  
+  *Parameters*
+  
+  ``node {E4XElement}`` A WPS node.
+  
+  *Returns*
+
+  ``{Object}`` A WPS literal data response.  
+  
+.. _parseData.reference:         
+  
+parseData.reference	
+  Given an Object representing the WPS reference response.
+
+  *Parameters*
+  
+  ``node {E4XElement}`` A WPS node.
+  
+  *Returns*
+
+  ``{Object}`` A WPS reference response.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-format.txt	(revision 672)
@@ -0,0 +1,143 @@
+.. _api-zoo-format:
+
+ZOO.Format
+==========
+
+Base class for format reading/writing a variety of formats.
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`options <options>`
+     - {Object} A reference to options passed to the constructor.
+   * - :ref:`externalProjection <externalProjection>`
+     - {ZOO.Projection} When passed a externalProjection and internalProjection, the format will reproject the geometries it reads or writes.
+   * - :ref:`internalProjection <internalProjection>`
+     - {ZOO.Projection} When passed a externalProjection and internalProjection, the format will reproject the geometries it reads or writes.
+   * - :ref:`data <data>`
+     - {Object} When keepData is true, this is the parsed string sent to read.
+   * - :ref:`keepData <keepData>`
+     - {Object} Maintain a reference (data) to the most recently read data.   
+     
+Functions	
+---------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Format <ZOO.Format>`
+     - Instances of this class are not useful.
+   * - :ref:`destroy <destroy>`
+     - Clean up.
+   * - :ref:`read <read>`
+     - Read data from a string, and return an object whose type depends on the subclass.
+   * - :ref:`data <data>`
+     - {Object} When keepData is true, this is the parsed string sent to read.
+   * - :ref:`write <write>`
+     - Accept an object, and return a string.     
+        
+**Properties**
+
+.. _options:   
+
+options	
+  ``{Object}`` A reference to options passed to the constructor.
+  
+.. _externalProjection:   
+
+externalProjection	
+  :ref:`{ZOO.Projection} <api-zoo-projection>` When passed a externalProjection and internalProjection, 
+  the format will reproject the geometries it reads or writes. The externalProjection is the projection 
+  used by the content which is passed into read or which comes out of write.  In order to reproject, 
+  a projection transformation function for the specified projections must be available.  This support 
+  is provided via zoo-proj4js.
+
+.. _internalProjection:   
+
+internalProjection	
+  :ref:`{ZOO.Projection} <api-zoo-projection>` When passed a externalProjection and internalProjection, 
+  the format will reproject the geometries it reads or writes. The internalProjection is the projection 
+  used by the geometries which are returned by read or which are passed into write.  In order to reproject, 
+  a projection transformation function for the specified projections must be available.  This support 
+  is provided via zoo-proj4js.
+
+.. _data:   
+
+data	
+  ``{Object}`` When :ref:`keepData <keepData>` is true, this is the parsed string sent to :ref:`read <read>`.
+
+.. _keepData:   
+
+keepData	
+  ``{Object}`` Maintain a reference (:ref:`data <data>`) to the most recently read data.  Default is false.
+
+**Functions**
+
+.. _ZOO.Format:   
+
+ZOO.Format	
+  Instances of this class are not useful.  See one of the subclasses.
+
+  *Parameters*
+  
+  ``options {Object}`` An optional object with properties to set on the format
+  
+  *Valid options*
+
+  ``keepData {Boolean}`` If true, upon read, the data property will be set to the parsed object (e.g. the json or xml object).
+
+  *Returns*
+
+  An instance of ZOO.Format
+  
+.. _destroy:     
+  
+destroy	
+  ::
+  
+    destroy: function()
+
+  Clean up.
+
+.. _read:     
+  
+read	
+  ::
+  
+    read: function(data)
+
+  Read data from a string, and return an object whose type depends on the subclass.
+
+  *Parameters*
+  
+  ``data {string}`` Data to read/parse.
+
+  *Returns*
+
+  Depends on the subclass
+
+.. _write:     
+
+write	
+  ::
+  
+    write: function(data)
+
+  Accept an object, and return a string.   
+
+  *Parameters*
+  
+  ``object {Object}`` Object to be serialized
+  
+  *Returns*
+
+  ``{String}`` A string representation of the object.  
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-collection.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-collection.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-collection.txt	(revision 672)
@@ -0,0 +1,355 @@
+.. _api-zoo-geometry-collection:
+
+ZOO.Geometry.Collection
+=======================
+
+A Collection is exactly what it sounds like: A collection of different Geometries.  
+These are stored in the local parameter :ref:`components <components>` (which can 
+be passed as a parameter to the constructor).
+
+As new geometries are added to the collection, they are NOT cloned.  When removing geometries, 
+they need to be specified by reference (ie you have to pass in the exact geometry to be removed).
+
+The <getArea> and :ref:`getLength <getLength>` functions here merely iterate through the components, 
+summing their respective areas and lengths.
+
+Create a new instance with the :ref:`ZOO.Geometry.Collection <ZOO.Geometry.Collection>` constructor.
+
+Inherits from
+
+- :ref:`ZOO.Geometry <api-zoo-geometry>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`components <components>`
+     - {Array(ZOO.Geometry)} The component parts of this geometry
+   * - :ref:`componentTypes <componentTypes>`
+     - {Array(String)} An array of class names representing the types of components that the collection can include.
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Geometry.Collection <ZOO.Geometry.Collection>`
+     - Creates a Geometry Collection -- a list of geoms.
+   * - :ref:`destroy <destroy>`
+     - Destroy this geometry.
+   * - :ref:`clone <clone>`
+     - Clone this geometry.
+   * - :ref:`getComponentsString <getComponentsString>`
+     - Get a string representing the components for this collection.
+   * - :ref:`calculateBounds <calculateBounds>`
+     - Recalculate the bounds by iterating through the components and calling extendBounds() on each item.
+   * - :ref:`addComponent <addComponent>`
+     - Add a new component (geometry) to the collection.
+   * - :ref:`removeComponents <removeComponents>`
+     - Remove components from this geometry.
+   * - :ref:`removeComponent <removeComponent>`
+     - Remove a component from this geometry.
+   * - :ref:`getLength <getLength>`
+     - Calculate the length of this geometry. 
+   * - :ref:`getCentroid <getCentroid>`
+     - {ZOO.Geometry.Point} The centroid of the collection.
+   * - :ref:`getGeodesicLength <getGeodesicLength>`
+     - Calculate the approximate length of the geometry were it projected onto the earth.
+   * - :ref:`move <move>`
+     - Moves a geometry by the given displacement along positive x and y axes.
+   * - :ref:`rotate <rotate>`
+     - Rotate a geometry around some origin.
+   * - :ref:`resize <resize>`
+     - Resize a geometry relative to some origin.
+   * - :ref:`equals <equals>`
+     - Determine whether another geometry is equivalent to this one.
+   * - :ref:`transform <transform>`
+     - Reproject the components geometry from source to dest.
+   * - :ref:`intersects <intersects>`
+     - Determine if the input geometry intersects this one.
+   * - :ref:`getVertices <getVertices>`
+     - Return a list of all points in this geometry.      
+   
+     
+**Properties**
+       
+.. _components: 
+
+components	
+  {Array(:ref:`ZOO.Geometry <api-zoo-geometry>`)} The component parts of this geometry
+  
+.. _componentTypes:   
+  
+componentTypes	
+  ``{Array(String)}`` An array of class names representing the types of components that the collection can include.
+  A null value means the component types are not restricted.
+
+**Functions**
+       
+.. _ZOO.Geometry.Collection:
+
+ZOO.Geometry.Collection	
+  Creates a Geometry Collection -- a list of geoms.
+
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry <api-zoo-geometry>`)} Optional array of geometries 
+  
+.. _destroy: 
+ 
+destroy	
+  ::
+  
+    destroy: function ()
+
+Destroy this geometry. 
+
+.. _clone:   
+  
+clone	
+  ::
+  
+    clone: function()
+
+  Clone this geometry.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Collection} <api-zoo-geometry-collection>` An exact clone of this collection.
+  
+.. _getComponentsString:     
+  
+getComponentsString	
+  ::
+  
+    getComponentsString: function()
+
+  Get a string representing the components for this collection.
+  
+  *Returns*
+
+  ``{String}`` A string representation of the components of this geometry.
+  
+.. _calculateBounds:  
+  
+calculateBounds	
+  ::
+  
+    calculateBounds: function()
+
+  Recalculate the bounds by iterating through the components and calling extendBounds() on each item.
+  
+.. _addComponent:    
+  
+addComponent	
+  ::
+  
+    addComponent: function(component,index)
+
+  Add a new component (geometry) to the collection.  If this.componentTypes is set, then the 
+  component class name must be in the componentTypes array.  The bounds cache is reset.
+  
+  *Parameters*
+  
+  | ``component`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` A geometry to add
+  | ``index {int}`` Optional index into the array to insert the component
+  
+  *Returns*
+
+  ``{Boolean}`` The component geometry was successfully added 
+  
+.. _removeComponents:      
+  
+removeComponents	
+  ::
+  
+    removeComponents: function(components)
+
+  Remove components from this geometry.\
+  
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry <api-zoo-geometry>`)} The components to be removed  
+  
+.. _removeComponent:  
+  
+removeComponent	
+  ::
+  
+    removeComponent: function(component)
+
+  Remove a component from this geometry.
+  
+  *Parameters*
+  
+  ``component`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+.. _getLength:    
+  
+getLength	
+  ::
+  
+    getLength: function()
+
+  Calculate the length of this geometry
+ 
+  *Returns*
+
+  ``{Float}`` The length of the geometry  
+  
+.. _getCentroid:      
+  
+getCentroid	
+  ::
+  
+    getCentroid: function()
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` The centroid of the collection 
+  
+.. _getGeodesicLength:        
+  
+getGeodesicLength	
+  ::
+  
+    getGeodesicLength: function(projection)
+
+  Calculate the approximate length of the geometry were it projected onto the earth.
+
+  *Parameters*
+  
+  ``projection`` :ref:`{ZOO.Projection} <api-zoo-projection>` The spatial 
+  reference system for the geometry coordinates.  If not provided, Geographic/WGS84 is assumed.
+  
+  *Returns*
+
+  ``{Float}`` The appoximate geodesic length of the geometry in meters. 
+  
+.. _move:          
+  
+move	
+  ::
+  
+    move: function(x,y)
+
+  Moves a geometry by the given displacement along positive x and y axes.  This modifies the 
+  position of the geometry and clears the cached bounds.
+  
+  *Parameters*
+  
+  | ``x	{Float}`` Distance to move geometry in positive x direction.
+  | ``y	{Float}`` Distance to move geometry in positive y direction.  
+  
+.. _rotate:            
+  
+rotate	
+  ::
+  
+    rotate: function(angle,origin)
+
+  Rotate a geometry around some origin
+  
+  *Parameters*
+  
+  | ``angle {Float}`` Rotation angle in degrees (measured counterclockwise from the positive x-axis)
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Center point for the rotation 
+  
+.. _resize:              
+  
+resize	
+  ::
+  
+    resize: function(scale,origin,ratio)
+
+  Resize a geometry relative to some origin.  Use this method to apply a uniform scaling to a geometry.
+
+  *Parameters*
+  
+  | ``scale {Float}`` Factor by which to scale the geometry.  A scale of 2 doubles the size of the geometry in each dimension (lines, for example, will be twice as long, and polygons will have four times the area).
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Point of origin for resizing
+  | ``ratio {Float}`` Optional x:y ratio for resizing.  Default ratio is 1.
+
+  *Returns*
+  
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>`  The current geometry.  
+
+.. _equals:                
+  
+equals	
+  ::
+  
+    equals: function(geometry)
+
+  Determine whether another geometry is equivalent to this one.  Geometries are considered equivalent if 
+  all components have the same coordinates.
+  
+  *Parameters*
+  
+  ``geom`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` The geometry to test.
+
+  *Returns*
+
+  ``{Boolean}`` The supplied geometry is equivalent to this geometry. 
+  
+.. _transform:                  
+  
+transform	
+  ::
+  
+    transform: function(source,dest)
+
+  Reproject the components geometry from source to dest.
+
+  *Parameters*
+  
+  | ``source`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+  | ``dest`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+.. _intersects:                    
+  
+intersects	
+  ::
+  
+    intersects: function(geometry)
+
+  Determine if the input geometry intersects this one.
+
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` Any type of geometry.
+
+  *Returns*
+
+  ``{Boolean}`` The input geometry intersects this one. 
+  
+.. _getVertices:                      
+  
+getVertices	
+  ::
+  
+    getVertices: function(nodes)
+
+  Return a list of all points in this geometry.
+  
+  *Parameters*
+  
+  ``nodes {Boolean}`` For lines, only return vertices that are endpoints.  If false, for lines, 
+  only vertices that are not endpoints will be returned.  If not provided, all vertices will be returned.
+
+  *Returns*
+
+  ``{Array}`` A list of all vertices in the geometry.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-curve.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-curve.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-curve.txt	(revision 672)
@@ -0,0 +1,68 @@
+.. _api-zoo-geometry-curve:
+
+ZOO.Geometry.Curve
+==================
+
+A Curve is a MultiPoint, whose points are assumed to be connected.  To this end, 
+we provide a "getLength()" function, which iterates through the points, summing the 
+distances between them.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.MultiPoint <api-zoo-geometry-multipoint>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`componentTypes <componentTypes>`
+     - {Array(String)} An array of class names representing the types of components that the collection can include.
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.Curve <ZOO.Geometry.Curve>`
+     - 
+   * - :ref:`getLength <getLength>`
+     - {Float} The length of the curve        
+     
+**Properties**
+       
+.. _componentTypes: 
+
+componentTypes	
+  ``{Array(String)}`` An array of class names representing the types of components that the 
+  collection can include.  A null value means the component types are not restricted.  
+  
+**Functions** 
+
+.. _ZOO.Geometry.Curve: 
+
+ZOO.Geometry.Curve
+
+  *Parameters*
+  
+  ``point`` {Array(:ref:`ZOO.Geometry.Point <api-zoo-geometry-point>`)}
+  
+.. _getLength: 
+
+getLength
+
+  ::
+  
+    getLength: function()
+
+  *Returns*
+
+  ``{Float}`` The length of the curve
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linearring.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linearring.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linearring.txt	(revision 672)
@@ -0,0 +1,231 @@
+.. _api-zoo-geometry-linearring:
+
+ZOO.Geometry.LinearRing
+=======================
+
+A Linear Ring is a special LineString which is closed.  It closes itself automatically 
+on every addPoint/removePoint by adding a copy of the first point as the last point.
+
+Also, as it is the first in the line family to close itself, a getArea() function is 
+defined to calculate the enclosed area of the linearRing
+
+Inherits from
+
+- :ref:`ZOO.Geometry.LineString <api-zoo-geometry-linestring>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`componentTypes <componentTypes>`
+     - {Array(String)} An array of class names representing the types of components that the collection can include.
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.LinearRing <ZOO.Geometry.LinearRing>`
+     - Linear rings are constructed with an array of points.
+   * - :ref:`addComponent <addComponent>`
+     - Adds a point to geometry components.  
+   * - :ref:`move <move>`
+     - Moves a geometry by the given displacement along positive x and y axes.
+   * - :ref:`rotate <rotate>`
+     - Rotate a geometry around some origin   
+   * - :ref:`resize <resize>`
+     - Resize a geometry relative to some origin.
+   * - :ref:`transform <transform>`
+     - Reproject the components geometry from source to dest. 
+   * - :ref:`getCentroid <getCentroid>`
+     - {ZOO.Geometry.Point} The centroid of the ring
+   * - :ref:`getArea <getArea>`
+     -     
+   * - :ref:`getGeodesicArea <getGeodesicArea>`
+     - Calculate the approximate area of the polygon were it projected onto the earth.   
+   * - :ref:`containsPoint <containsPoint>`
+     - Test if a point is inside a linear ring.     
+     
+**Properties**
+       
+.. _componentTypes: 
+
+componentTypes	
+  ``{Array(String)}`` An array of class names representing the types of components that the 
+  collection can include.  A null value means the component types are not restricted.  
+  
+**Functions** 
+
+.. _ZOO.Geometry.LinearRing: 
+
+ZOO.Geometry.LinearRing	
+  Linear rings are constructed with an array of points.  This array can represent a closed 
+  or open ring.  If the ring is open (the last point does not equal the first point), 
+  the constructor will close the ring.  If the ring is already closed (the last point does 
+  equal the first point), it will be left closed.
+  
+  *Parameters*
+  
+  ``points`` {Array(:ref:`ZOO.Geometry.Point <api-zoo-geometry-point>`)} points  
+  
+.. _addComponent:   
+  
+addComponent	
+  ::
+  
+    addComponent: function(point,index)
+
+  Adds a point to geometry components.  If the point is to be added to the end of the 
+  components array and it is the same as the last point already in that array, the 
+  duplicate point is not added.  This has the effect of closing the ring if it is not 
+  already closed, and doing the right thing if it is already closed.  This behavior can be 
+  overridden by calling the method with a non-null index as the second argument.
+  
+  *Parameter*
+  
+  | ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>`
+  | ``index {Integer}`` Index into the array to insert the component
+
+  *Returns*
+
+  ``{Boolean}`` Was the Point successfully added?  
+  
+.. _move:     
+  
+move	
+  ::
+  
+    move: function(x,y)
+
+  Moves a geometry by the given displacement along positive x and y axes.  This 
+  modifies the position of the geometry and clears the cached bounds.
+  
+  *Parameters*
+  
+  | ``x {Float}`` Distance to move geometry in positive x direction.
+  | ``y	{Float}`` Distance to move geometry in positive y direction.  
+
+.. _rotate:       
+  
+rotate	
+  ::
+  
+    rotate: function(angle,origin)
+
+  Rotate a geometry around some origin
+
+  *Parameters*
+  
+  | ``angle {Float}`` Rotation angle in degrees (measured counterclockwise from the positive x-axis)
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Center point for the rotation  
+
+.. _resize:         
+  
+resize	
+  ::
+  
+    resize: function(scale,origin,ratio)
+
+  Resize a geometry relative to some origin.  Use this method to apply a uniform scaling to a geometry.
+
+  *Parameters*
+  
+  | ``scale {Float}`` Factor by which to scale the geometry.  A scale of 2 doubles the size of the geometry in each dimension (lines, for example, will be twice as long, and polygons will have four times the area).
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Point of origin for resizing
+  | ``ratio {Float}`` Optional x:y ratio for resizing.  Default ratio is 1.
+
+  *Returns*
+  
+  ``{ZOO.Geometry}`` The current geometry.
+  
+.. _transform:           
+  
+transform	
+  ::
+  
+    transform: function(source,dest)
+
+  Reproject the components geometry from source to dest.
+
+  *Parameters*
+  
+  | ``source`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+  | ``dest`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` 
+  
+.. _getCentroid:             
+  
+getCentroid	
+  ::
+  
+    getCentroid: function()
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` The centroid of the ring  
+
+.. _getArea:               
+  
+getArea	
+  ::
+  
+    getArea: function()
+
+  .. note:: The area is positive if the ring is oriented CW, otherwise it will be negative.
+
+  *Returns*
+
+  ``{Float}`` The signed area for a ring.
+
+.. _getGeodesicArea:               
+
+getGeodesicArea	
+  ::
+  
+    getGeodesicArea: function(projection)
+
+  Calculate the approximate area of the polygon were it projected onto the earth.  Note that 
+  this area will be positive if ring is oriented clockwise, otherwise it will be negative.
+
+  *Parameters*
+  
+  ``projection`` :ref:`{ZOO.Projection} <api-zoo-projection>` The spatial reference system for the geometry coordinates.  If not provided, Geographic/WGS84 is assumed.
+
+  *Reference*
+
+  Robert.  G. Chamberlain and William H.  Duquette, "Some Algorithms for Polygons on a Sphere", 
+  JPL Publication 07-03, Jet Propulsion Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+
+  *Returns*
+
+  ``{float}`` The approximate signed geodesic area of the polygon in square meters.  
+
+.. _containsPoint:                 
+  
+containsPoint	
+  ::
+  
+    containsPoint: function(point)
+
+  Test if a point is inside a linear ring.  For the case where a point is coincident with a 
+  linear ring edge, returns 1.  Otherwise, returns boolean.
+
+  *Parameters*
+
+  ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>`
+
+  *Returns*
+
+  ``{Boolean | Number}`` The point is inside the linear ring.  Returns 1 if the point is coincident with an edge.  Returns boolean otherwise.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linestring.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linestring.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-linestring.txt	(revision 672)
@@ -0,0 +1,180 @@
+.. _api-zoo-geometry-linestring:
+
+ZOO.Geometry.LineString
+=======================
+
+A LineString is a Curve which, once two points have been added to it, can never be less than two points long.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.Curve <api-zoo-geometry-curve>`
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.LineString <ZOO.Geometry.LineString>`
+     - Create a new LineString geometry
+   * - :ref:`removeComponent <removeComponent>`
+     - Only allows removal of a point if there are three or more points in the linestring.  
+   * - :ref:`intersects <intersects>`
+     - Test for instersection between two geometries.
+   * - :ref:`getSortedSegments <getSortedSegments>`
+     - {Array} An array of segment objects.  
+   * - :ref:`splitWithSegment <splitWithSegment>`
+     - Split this geometry with the given segment.
+   * - :ref:`split <split>`
+     - Use this geometry (the source) to attempt to split a target geometry. 
+   * - :ref:`splitWith <splitWith>`
+     - Split this geometry (the target) with the given geometry (the source).
+   * - :ref:`getVertices <getVertices>`
+     - Return a list of all points in this geometry.       
+     
+.. _ZOO.Geometry.LineString: 
+
+ZOO.Geometry.LineString	
+  Create a new LineString geometry
+
+  *Parameters*
+  
+  ``points`` {Array(:ref:`ZOO.Geometry.Point <api-zoo-geometry-point>`)} An array of points used to generate the linestring  
+
+.. _removeComponent:  
+  
+removeComponent	
+  ::
+  
+    removeComponent: function(point)
+
+  Only allows removal of a point if there are three or more points in the linestring. (otherwise 
+  the result would be just a single point)
+
+  *Parameters*
+  
+  ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` The point to be removed  
+  
+.. _intersects:  
+  
+intersects	
+  ::
+  
+    intersects: function(geometry)
+
+  Test for instersection between two geometries.  This is a cheapo implementation of the 
+  Bently-Ottmann algorigithm.  It doesn't really keep track of a sweep line data structure.  
+  It is closer to the brute force method, except that segments are sorted and potential intersections 
+  are only calculated when bounding boxes intersect.
+  
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+  *Returns*
+
+  ``{Boolean}`` The input geometry intersects this geometry.  
+  
+.. _getSortedSegments:    
+  
+getSortedSegments	
+  ::
+  
+    getSortedSegments: function()
+
+  *Returns*
+
+  ``{Array}`` An array of segment objects.  Segment objects have properties x1, y1, x2, and y2.  
+  The start point is represented by x1 and y1.  The end point is represented by x2 and y2.  
+  Start and end are ordered so that x1 < x2.  
+  
+.. _splitWithSegment:      
+  
+splitWithSegment	
+  ::
+  
+    splitWithSegment: function(seg,options)
+
+  Split this geometry with the given segment.
+  
+  *Parameters*
+  
+  | ``seg {Object}`` An object with x1, y1, x2, and y2 properties referencing segment endpoint coordinates.
+  | ``options {Object}`` Properties of this object will be used to determine how the split is conducted.
+
+  *Valid options*
+  
+  | ``edge {Boolean}`` Allow splitting when only edges intersect.  Default is true.  If false, a vertex on the source segment must be within the tolerance distance of the intersection to be considered a split.
+  | ``tolerance	{Number}`` If a non-null value is provided, intersections within the tolerance distance of one of the source segment's endpoints will be assumed to occur at the endpoint.
+
+  *Returns*
+
+  ``{Object}`` An object with lines and points properties.  If the given segment intersects this linestring, the lines array will reference geometries that result from the split.  The points array will contain all intersection points.  Intersection points are sorted along the segment (in order from x1,y1 to x2,y2).  
+
+.. _split:        
+  
+split	
+  ::
+  
+    split: function(target,options)
+
+  Use this geometry (the source) to attempt to split a target geometry.
+  
+  *Parameters*
+  
+  | ``target`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` The target geometry.
+  | ``options {Object}`` Properties of this object will be used to determine how the split is conducted.
+
+  *Valid options*
+  
+  | ``mutual {Boolean}`` Split the source geometry in addition to the target geometry.  Default is false.
+  | ``edge {Boolean}`` Allow splitting when only edges intersect.  Default is true.  If false, a vertex on the source must be within the tolerance distance of the intersection to be considered a split.
+  | ``tolerance	{Number}`` If a non-null value is provided, intersections within the tolerance distance of an existing vertex on the source will be assumed to occur at the vertex.
+
+  *Returns*
+
+  ``{Array}`` A list of geometries (of this same type as the target) that result from splitting the target with the source geometry.  The source and target geometry will remain unmodified.  If no split results, null will be returned.  If mutual is true and a split results, return will be an array of two arrays - the first will be all geometries that result from splitting the source geometry and the second will be all geometries that result from splitting the target geometry.  
+
+.. _splitWith:          
+  
+splitWith	
+  ::
+  
+    splitWith: function(geometry,options)
+
+  Split this geometry (the target) with the given geometry (the source).
+  
+  *Parameters*
+  
+  | ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` A geometry used to split this geometry (the source).
+  | ``options {Object}`` Properties of this object will be used to determine how the split is conducted.
+
+  *Valid options*
+  
+  | ``mutual {Boolean}`` Split the source geometry in addition to the target geometry.  Default is false.
+  | ``edge {Boolean}`` Allow splitting when only edges intersect.  Default is true.  If false, a vertex on the source must be within the tolerance distance of the intersection to be considered a split.
+  | ``tolerance {Number}`` If a non-null value is provided, intersections within the tolerance distance of an existing vertex on the source will be assumed to occur at the vertex.
+
+  *Returns*
+
+  ``{Array}`` A list of geometries (of this same type as the target) that result from splitting the target with the source geometry.  The source and target geometry will remain unmodified.  If no split results, null will be returned.  If mutual is true and a split results, return will be an array of two arrays - the first will be all geometries that result from splitting the source geometry and the second will be all geometries that result from splitting the target geometry.  
+
+.. _getVertices:            
+  
+getVertices	
+  ::
+  
+    getVertices: function(nodes)
+
+  Return a list of all points in this geometry.
+  
+  *Parameters*
+  
+  ``nodes {Boolean}`` For lines, only return vertices that are endpoints.  If false, for lines, only vertices that are not endpoints will be returned.  If not provided, all vertices will be returned.
+
+  *Returns*
+
+  ``{Array}`` A list of all vertices in the geometry.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multilinestring.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multilinestring.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multilinestring.txt	(revision 672)
@@ -0,0 +1,31 @@
+.. _api-zoo-geometry-multilinestring:
+
+ZOO.Geometry.MultiLineString
+============================
+
+A MultiLineString is a geometry with multiple ZOO.Geometry.LineString components.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.Collection <api-zoo-geometry-collection>`
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.MultiLineString <ZOO.Geometry.MultiLineString>`
+     - Constructor for a MultiLineString Geometry.     
+     
+.. _ZOO.Geometry.MultiLineString: 
+
+ZOO.Geometry.MultiLineString	
+  Constructor for a MultiLineString Geometry.
+
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry.LineString <api-zoo-geometry-linestring>`)}
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipoint.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipoint.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipoint.txt	(revision 672)
@@ -0,0 +1,90 @@
+.. _api-zoo-geometry-multipoint:
+
+ZOO.Geometry.MultiPoint
+=======================
+
+MultiPoint is a collection of Points.  Create a new instance with the 
+:ref:`ZOO.Geometry.MultiPoint <ZOO.Geometry.MultiPoint>` constructor.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.Collection <api-zoo-geometry-collection>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`componentTypes <componentTypes>`
+     - {Array(String)} An array of class names representing the types of components that the collection can include.
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.MultiPoint <ZOO.Geometry.MultiPoint>`
+     - Create a new MultiPoint Geometry
+   * - :ref:`addPoint <addPoint>`
+     - rapper for ZOO.Geometry.Collection.addComponent  
+   * - :ref:`removePoint <removePoint>`
+     - Wrapper for ZOO.Geometry.Collection.removeComponent       
+     
+**Properties**
+       
+.. _componentTypes: 
+
+componentTypes	
+  ``{Array(String)}`` An array of class names representing the types of components that the collection can include.  
+  A null value means the component types are not restricted.
+  
+**Functions**  
+
+.. _ZOO.Geometry.MultiPoint: 
+
+ZOO.Geometry.MultiPoint	
+  Create a new MultiPoint Geometry
+
+
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry.Point <api-zoo-geometry-point>`)}
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry.MultPoint} <api-zoo-geometry-multipoint>` 
+  
+.. _addPoint:   
+  
+addPoint	
+  ::
+  
+    addPoint: function(point,index)
+
+  Wrapper for :ref:`ZOO.Geometry.Collection.addComponent <addComponent>`
+
+  *Parameters*
+  
+  | ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Point to be added
+  | ``index {Integer}`` Optional index  
+  
+.. _removePoint:     
+  
+removePoint	
+  ::
+  
+    removePoint: function(point)
+
+  Wrapper for :ref:`ZOO.Geometry.Collection.removeComponent <removeComponent>`
+  
+  *Parameters*
+  
+  ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Point to be removed
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipolygon.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipolygon.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-multipolygon.txt	(revision 672)
@@ -0,0 +1,32 @@
+.. _api-zoo-geometry-multipolygon:
+
+ZOO.Geometry.MultiPolygon
+=========================
+
+MultiPolygon is a geometry with multiple :ref:`ZOO.Geometry.Polygon <api-zoo-geometry-polygon>` components.  
+Create a new instance with the :ref:`ZOO.Geometry.MultiPolygon <ZOO.Geometry.MultiPolygon>` constructor.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.Collection <api-zoo-geometry-collection>`
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.MultiPolygon <ZOO.Geometry.MultiPolygon>`
+     - Create a new MultiPolygon geometry        
+     
+.. _ZOO.Geometry.MultiPolygon: 
+
+ZOO.Geometry.MultiPolygon
+  Create a new MultiPolygon geometry
+
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry.Polygon <api-zoo-geometry-polygon>`)} An array of polygons used to generate the MultiPolygon
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-point.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-point.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-point.txt	(revision 672)
@@ -0,0 +1,246 @@
+.. _api-zoo-geometry-point:
+
+ZOO.Geometry.Point
+==================
+
+Point geometry class.
+
+Inherits from
+
+- :ref:`ZOO.Geometry <api-zoo-geometry>`
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`x <x>`
+     - {float}
+   * - :ref:`y <y>`
+     - {float}
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.Point <ZOO.Geometry.Point>`
+     - Construct a point geometry.
+   * - :ref:`clone <clone>`
+     - {ZOO.Geometry.Point} An exact clone of this ZOO.Geometry.Point   
+   * - :ref:`calculateBounds <calculateBounds>`
+     - Create a new Bounds based on the x/y
+   * - :ref:`equals <equals>`
+     - Determine whether another geometry is equivalent to this one.
+   * - :ref:`toShortString <toShortString>`
+     - {String} Shortened String representation of Point object.
+   * - :ref:`move <move>`
+     - Moves a geometry by the given displacement along positive x and y axes.
+   * - :ref:`rotate <rotate>`
+     - Rotate a point around another.
+   * - :ref:`getCentroid <getCentroid>`
+     - {ZOO.Geometry.Point} The centroid of the collection 
+   * - :ref:`resize <resize>`
+     - Resize a point relative to some origin.
+   * - :ref:`intersects <intersects>`
+     - Determine if the input geometry intersects this one.  
+   * - :ref:`transform <transform>`
+     - Translate the x,y properties of the point from source to dest.
+   * - :ref:`getVertices <getVertices>`
+     - Return a list of all points in this geometry.      
+   
+     
+**Properties**
+       
+.. _x: 
+
+x	
+  ``{float}``
+  
+.. _y:  
+  
+y	
+  ``{float}``
+  
+**Functions**  
+
+.. _ZOO.Geometry.Point:  
+
+ZOO.Geometry.Point	
+  Construct a point geometry.
+
+  *Parameters*
+  
+  | ``x	{float}``
+  | ``y	{float}``
+  
+.. _clone:  
+  
+clone	
+  ::
+  
+    clone: function(obj)
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` An exact clone of this ZOO.Geometry.Point 
+  
+.. _calculateBounds:    
+  
+calculateBounds	
+  ::
+  
+    calculateBounds: function ()
+
+  Create a new Bounds based on the x/y  
+  
+.. _equals:      
+  
+equals	
+  ::
+  
+    equals: function(geom)
+
+  Determine whether another geometry is equivalent to this one.  Geometries are considered 
+  equivalent if all components have the same coordinates.
+  
+  *Parameters*
+  
+  ``geom`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` The geometry to test.
+  
+  *Returns*
+
+  ``{Boolean}`` The supplied geometry is equivalent to this geometry.
+  
+.. _toShortString:        
+  
+toShortString	
+  ::
+  
+    toShortString: function()
+
+  *Returns*
+
+  ``{String}`` Shortened String representation of Point object.  (ex.  <i>"5, 42"</i>)  
+  
+.. _move:          
+  
+move	
+  ::
+  
+    move: function(x,y)
+
+  Moves a geometry by the given displacement along positive x and y axes.  This modifies 
+  the position of the geometry and clears the cached bounds.
+
+  *Parameters*
+  
+  | ``x {Float}`` Distance to move geometry in positive x direction.
+  | ``y	{Float}`` Distance to move geometry in positive y direction. 
+  
+.. _rotate:            
+  
+rotate	
+  ::
+  
+    rotate: function(angle,origin)
+
+  Rotate a point around another.
+  
+  *Parameters*
+  
+  | ``angle {Float}`` Rotation angle in degrees (measured counterclockwise from the positive x-axis)
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Center point for the rotation 
+
+.. _getCentroid:             
+ 
+getCentroid	
+  ::
+  
+    getCentroid: function()
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` The centroid of the collection  
+  
+.. _resize:               
+  
+resize	
+  ::
+  
+    resize: function(scale,origin,ratio)
+
+  Resize a point relative to some origin.  For points, this has the effect of scaling a 
+  vector (from the origin to the point).  This method is more useful on geometry collection 
+  subclasses.
+  
+  *Parameters*
+  
+  | ``scale {Float}`` Ratio of the new distance from the origin to the old distance from the origin.  A scale of 2 doubles the distance between the point and origin.
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` Point of origin for resizing
+  | ``ratio {Float}`` Optional x:y ratio for resizing.  Default ratio is 1.
+
+  *Returns*
+  
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` The current geometry.  
+  
+.. _intersects:                 
+  
+intersects	
+  ::
+  
+    intersects: function(geometry)
+
+  Determine if the input geometry intersects this one.
+  
+  *Parameters*
+  
+  ``geometry`` :ref:`{ZOO.Geometry} <api-zoo-geometry>` Any type of geometry.
+
+  *Returns*
+
+  ``{Boolean}`` The input geometry intersects this one. 
+  
+.. _transform:                   
+  
+transform	
+  ::
+  
+    transform: function(source,dest)
+
+  Translate the x,y properties of the point from source to dest.
+  
+  *Parameters*
+  
+  | ``source`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+  | ``dest`` :ref:`{ZOO.Projection} <api-zoo-projection>`
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>`
+  
+.. _getVertices:                     
+  
+getVertices	
+  ::
+  
+    getVertices: function(nodes)
+
+  Return a list of all points in this geometry.
+  
+  *Parameters*
+  
+  ``nodes {Boolean}`` For lines, only return vertices that are endpoints.  If false, for lines, 
+  only vertices that are not endpoints will be returned.  If not provided, all vertices will be returned.
+
+  *Returns*
+
+  ``{Array}`` A list of all vertices in the geometry.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-polygon.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-polygon.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-polygon.txt	(revision 672)
@@ -0,0 +1,87 @@
+.. _api-zoo-geometry-polygon:
+
+ZOO.Geometry.Polygon
+====================
+
+Polygon is a collection of :ref:`ZOO.Geometry.LinearRing <api-zoo-geometry-linearring>`.
+
+Inherits from
+
+- :ref:`ZOO.Geometry.Collection <api-zoo-geometry-collection>`
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`ZOO.Geometry.Polygon <ZOO.Geometry.Polygon>`
+     - Constructor for a Polygon geometry.   
+   * - :ref:`getArea <getArea>`
+     - Calculated by subtracting the areas of the internal holes from the area of the outer hole.  
+   * - :ref:`containsPoint <containsPoint>`
+     - Test if a point is inside a polygon.  
+   * - :ref:`createRegularPolygon <createRegularPolygon>`
+     - Create a regular polygon around a radius.       
+     
+.. _ZOO.Geometry.Polygon: 
+
+ZOO.Geometry.Polygon	
+  Constructor for a Polygon geometry.  The first ring (*this.component[0]*) is the outer 
+  bounds of the polygon and all subsequent rings (*this.component[1-n]*) are internal holes.
+
+  *Parameters*
+  
+  ``components`` {Array(:ref:`ZOO.Geometry.LinearRing <api-zoo-geometry-linearring>`)}  
+
+.. _getArea:  
+  
+getArea	
+  ::
+  
+    getArea: function()
+
+  Calculated by subtracting the areas of the internal holes from the area of the outer hole.
+
+  *Returns*
+
+  ``{float}`` The area of the geometry  
+  
+.. _containsPoint:    
+  
+containsPoint	
+  ::
+  
+    containsPoint: function(point)
+
+  Test if a point is inside a polygon.  Points on a polygon edge are considered inside.
+
+  *Parameters*
+  
+  ``point`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>`
+
+  *Returns*
+
+  ``{Boolean | Number}`` The point is inside the polygon.  Returns 1 if the point is on an edge.  Returns boolean otherwise.  
+
+.. _createRegularPolygon:      
+  
+createRegularPolygon	
+  ::
+  
+    ZOO.Geometry.Polygon.createRegularPolygon = function( origin,
+    	                                                  radius,
+                                                          sides,
+    	                                                  rotation	)
+
+  Create a regular polygon around a radius.  Useful for creating circles and the like.
+
+  *Parameters*
+  
+  | ``origin`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` center of polygon.
+  | ``radius {Float}`` distance to vertex, in map units.
+  | ``sides {Integer}`` Number of sides.  20 approximates a circle.
+  | ``rotation {Float}`` original angle of rotation, in degrees.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-surface.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-surface.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry-surface.txt	(revision 672)
@@ -0,0 +1,10 @@
+.. _api-zoo-geometry-surface:
+
+ZOO.Geometry.Surface
+====================
+
+Surface geometry class.
+
+Inherits from
+
+- :ref:`ZOO.Geometry <api-zoo-geometry>`
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-geometry.txt	(revision 672)
@@ -0,0 +1,173 @@
+.. _api-zoo-geometry:
+
+ZOO.Geometry
+============
+
+A Geometry is a description of a geographic object.
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`id <id>`
+     - {String} A unique identifier for this geometry.
+   * - :ref:`parent <parent>`
+     - {ZOO.Geometry}This is set when a Geometry is added as component of another geometry
+   * - :ref:`bounds <bounds>`
+     - {ZOO.Bounds} The bounds of this geometry
+
+Functions	
+---------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Geometry <ZOO.Geometry>`
+     - Creates a geometry object.
+   * - :ref:`destroy <destroy>`
+     - nullify references to prevent circular references and memory leaks
+   * - :ref:`clone <clone>`
+     - Create a clone of this vector feature.
+   * - :ref:`extendBounds <extendBounds>`
+     - Moves the feature and redraws it at its new location
+   * - :ref:`clearBounds <clearBounds>`
+     - Nullify this components bounds and that of its parent as well.
+   * - :ref:`getBounds <getBounds>`
+     - Get the bounds for this Geometry.
+   * - :ref:`calculateBounds <calculateBounds>`
+     - Recalculate the bounds for the geometry.
+   * - :ref:`toString <toString>`
+     - Returns the Well-Known Text representation of a geometry
+   * - :ref:`ZOO.Geometry.fromWKT <ZOO.Geometry.fromWKT>`
+     - Generate a geometry given a Well-Known Text string.   
+   
+     
+**Properties**
+       
+.. _id: 
+
+id	
+  ``{String}`` A unique identifier for this geometry.
+  
+.. _parent:  
+  
+parent	
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` This is set when a Geometry is added as component of another geometry
+  
+.. _bounds:    
+  
+bounds	
+  :ref:`{ZOO.Bounds} <api-zoo-bounds>` The bounds of this geometry
+
+**Functions**
+       
+.. _ZOO.Geometry: 
+
+ZOO.Geometry	
+  Creates a geometry object.
+  
+.. _destroy:   
+  
+destroy	
+  ::
+  
+    destroy: function()
+
+  Destroy this geometry.
+  
+.. _clone:     
+  
+clone	
+  ::
+  
+    clone: function()
+
+  Create a clone of this geometry.  Does not set any non-standard properties of the cloned geometry.
+  
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` An exact clone of this geometry.  
+  
+.. _extendBounds:       
+  
+extendBounds	
+  ::
+  
+    extendBounds: function(newBounds)
+
+  Extend the existing bounds to include the new bounds.  If geometry's bounds is not yet set, 
+  then set a new Bounds.
+  
+  *Parameters*
+  
+  ``newBounds``	:ref:`{ZOO.Bounds} <api-zoo-bounds>`
+  
+.. _clearBounds:         
+  
+clearBounds	
+  ::
+  
+    clearBounds: function()
+
+  Nullify this components bounds and that of its parent as well. 
+  
+.. _getBounds:           
+  
+getBounds	
+  ::
+  
+    getBounds: function()
+
+  Get the bounds for this Geometry.  If bounds is not set, it is calculated again, this 
+  makes queries faster.
+  
+  *Returns*
+
+  ``newBounds``	:ref:`{ZOO.Bounds} <api-zoo-bounds>`
+  
+.. _calculateBounds:             
+  
+calculateBounds	
+  ::
+  
+    calculateBounds: function()
+
+  Recalculate the bounds for the geometry. 
+  
+.. _toString:               
+  
+toString	
+  ::
+  
+    toString: function()
+
+  Returns the Well-Known Text representation of a geometry
+  
+  *Returns*
+
+  ``{String}`` Well-Known Text  
+  
+.. _ZOO.Geometry.fromWKT:                 
+  
+ZOO.Geometry.fromWKT	
+  ::
+  
+    ZOO.Geometry.fromWKT = function(wkt)
+
+  Generate a geometry given a Well-Known Text string.
+  
+  *Parameters*
+  
+  ``wkt	{String}`` A string representing the geometry in Well-Known Text.
+
+  *Returns*
+
+  :ref:`{ZOO.Geometry} <api-zoo-geometry>` A geometry of the appropriate class.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-process.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-process.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-process.txt	(revision 672)
@@ -0,0 +1,149 @@
+.. _api-zoo-process:
+
+ZOO.Process
+===========
+
+Used to query OGC WPS process defined by its URL and its identifier.  Useful for chaining localhost process.
+
+Properties and Functions	
+------------------------
+
+.. list-table::
+   :widths: 15 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION   
+   * - :ref:`schemaLocation <schemaLocation>`
+     - {String} Schema location for a particular minor version. 
+   * - :ref:`namespaces <namespaces>`
+     - {Object} Mapping of namespace aliases to namespace URIs.
+   * - :ref:`url <url>`
+     - {String} The OGC's Web PRocessing Service URL, default is http://localhost/zoo.
+   * - :ref:`identifier <identifier>`
+     - {String} Process identifier in the OGC's Web Processing Service. 
+   * - :ref:`ZOO.Process <ZOO.Process>`
+     - Create a new Process 
+   * - :ref:`Execute <Execute>`
+     - Query the OGC's Web PRocessing Servcie to Execute the process.
+   * - :ref:`buildInput <buildInput>`
+     - Object containing methods to build WPS inputs. 
+   * - :ref:`buildInput.complex <buildInput.complex>`
+     - Given an E4XElement representing the WPS complex data input.   
+   * - :ref:`buildInput.reference <buildInput.reference>`
+     - Given an E4XElement representing the WPS reference input.
+   * - :ref:`buildInput.literal <buildInput.literal>`
+     - Given an E4XElement representing the WPS literal data input.
+   * - :ref:`buildDataInputsNode <buildDataInputsNode>`
+     - Method to build the WPS DataInputs element.     
+     
+.. _schemaLocation: 
+
+schemaLocation	
+  ``{String}`` Schema location for a particular minor version.
+  
+.. _namespaces:   
+  
+namespaces	
+  ``{Object}`` Mapping of namespace aliases to namespace URIs.
+  
+.. _url:     
+  
+url	
+  ``{String}`` The OGC's Web PRocessing Service URL, default is http://localhost/zoo.
+  
+.. _identifier:       
+  
+identifier	
+  ``{String}`` Process identifier in the OGC's Web Processing Service.
+  
+.. _ZOO.Process:         
+  
+ZOO.Process	
+  Create a new Process
+
+  *Parameters*
+  
+  | ``url {String}`` The OGC's Web Processing Service URL.
+  | ``identifier {String}`` The process identifier in the OGC's Web Processing Service.  
+
+.. _Execute:           
+  
+Execute	
+  ::
+  
+    Execute: function(inputs)
+
+  Query the OGC's Web PRocessing Servcie to Execute the process.
+
+  *Parameters*
+  
+  ``inputs {Object}``
+  
+  *Returns*
+
+  ``{String}`` The OGC's Web processing Service XML response.  The result needs to be interpreted. 
+  
+.. _buildInput:             
+  
+buildInput	
+  Object containing methods to build WPS inputs.
+  
+.. _buildInput.complex:               
+  
+buildInput.complex	
+  Given an E4XElement representing the WPS complex data input.
+
+  *Parameters*
+  
+  | ``identifier {String}`` the input indetifier
+  | ``data {Object}`` A WPS complex data input.
+
+  *Returns*
+
+  ``{E4XElement}`` A WPS Input node.
+  
+.. _buildInput.reference:                 
+  
+buildInput.reference	
+  Given an E4XElement representing the WPS reference input.
+
+  *Parameters*
+  
+  | ``identifier {String}`` the input indetifier
+  | ``data {Object}`` A WPS reference input.
+
+  *Returns*
+
+  ``{E4XElement}`` A WPS Input node.  
+  
+.. _buildInput.literal:                   
+  
+buildInput.literal	
+  Given an E4XElement representing the WPS literal data input.
+
+  *Parameters*
+  
+  | ``identifier {String}`` the input indetifier
+  | ``data {Object}`` A WPS literal data input.
+
+  *Returns*
+
+  ``{E4XElement}`` The WPS Input node.  
+  
+.. _buildDataInputsNode:                     
+  
+buildDataInputsNode	
+  ::
+  
+    buildDataInputsNode:function(inputs)
+
+  Method to build the WPS DataInputs element.
+
+  *Parameters*
+  
+  ``inputs {Object}``
+  
+  *Returns*
+
+  ``{E4XElement}`` The WPS DataInputs node for Execute query.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-projection.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-projection.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-projection.txt	(revision 672)
@@ -0,0 +1,153 @@
+.. _api-zoo-projection:
+
+ZOO.Projection
+==============
+
+Class for coordinate transforms between coordinate systems.
+
+Properties	
+----------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`proj <proj>`
+     - {Number} Proj4js.Proj instance.
+   * - :ref:`projCode <projCode>`
+     - {String} 
+       
+Functions	
+---------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`ZOO.Projection <ZOO.Projection>`
+     - This class offers several methods for interacting with a wrapped zoo-pro4js projection object.
+   * - :ref:`getCode <getCode>`
+     - Get the string SRS code.
+   * - :ref:`getUnits <getUnits>`
+     - Get the units string for the projection -- returns null if zoo-proj4js is not available.
+   * - :ref:`toString <toString>`
+     - Convert projection to string (getCode wrapper).
+   * - :ref:`equals <equals>`
+     - Test equality of two projection instances.   
+   * - :ref:`destroy <destroy>`
+     - Destroy projection object.
+   * - :ref:`transform <transform>`
+     - Transform a point coordinate from one projection to another.       
+
+**Properties**
+
+.. _proj:   
+
+proj	
+  ``{Object}`` Proj4js.Proj instance.
+  
+.. _projCode:     
+  
+projCode	
+  ``{String}``
+
+**Functions**
+
+.. _ZOO.Projection:     
+
+ZOO.Projection	
+  This class offers several methods for interacting with a wrapped zoo-pro4js projection object.
+
+  *Parameters*
+  
+  | ``projCode {String}`` A string identifying the Well Known Identifier for the projection.
+  | ``options {Object}`` An optional object to set additional properties.
+
+  *Returns*
+
+  :ref:`{ZOO.Projection} <api-zoo-projection>` A projection object.
+  
+.. _getCode:     
+
+getCode	
+  ::
+  
+    getCode: function()
+
+  Get the string SRS code.
+  
+  *Returns*
+
+  ``{String}`` The SRS code. 
+  
+.. _getUnits:       
+
+getUnits	
+  ::
+  
+    getUnits: function()
+
+  Get the units string for the projection -- returns null if zoo-proj4js is not available.
+
+  *Returns*
+
+  ``{String}`` The units abbreviation.
+  
+.. _toString:       
+
+toString	
+  ::
+  
+    toString: function()
+
+  Convert projection to string (getCode wrapper).
+  
+  *Returns*
+
+  ``{String}`` The projection code.  
+  
+.. _equals:         
+  
+equals	
+  ::
+  
+    equals: function(projection)
+
+  Test equality of two projection instances.  Determines equality based soley on the projection code.
+
+  *Returns*
+
+  ``{Boolean}`` The two projections are equivalent. 
+  
+.. _destroy:           
+  
+destroy	
+  ::
+  
+    destroy: function()
+
+  Destroy projection object. 
+  
+.. _transform:             
+  
+transform	
+  ::
+  
+    ZOO.Projection.transform = function(point,source,dest)
+
+  Transform a point coordinate from one projection to another.  Note that the input point is 
+  transformed in place.
+  
+  *Parameters*
+  
+  | ``point {{ZOO.Geometry.Point> | Object}`` An object with x and y properties representing coordinates in those dimensions.
+  | ``sourceProj {ZOO.Projection}`` Source map coordinate system
+  | ``destProj {ZOO.Projection}`` Destination map coordinate system
+
+  *Returns*
+  
+  ``point {object}`` A transformed coordinate.  The original point is modified.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-request.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-request.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-request.txt	(revision 672)
@@ -0,0 +1,49 @@
+.. _api-zoo-request:
+
+ZOO.Request
+===========
+
+Contains convenience methods for working with ZOORequest which replace XMLHttpRequest.
+
+Functions
+---------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`GET <GET>`
+     - Send an HTTP GET request.
+   * - :ref:`POST <POST>`
+     - Send an HTTP POST request. 
+     
+.. _GET:
+
+GET	
+  Send an HTTP GET request.
+
+  *Parameters*
+  
+  | ``url {String}`` The URL to request.
+  | ``params {Object}`` Params to add to the url
+
+  *Returns*
+
+  ``{String}`` Request result.
+  
+.. _POST:
+
+POST	
+  Send an HTTP POST request.
+
+  *Parameters*
+  
+  | ``url {String}`` The URL to request.
+  | ``body {String}`` The request's body to send.
+  | ``headers {Object}`` A key-value object of headers to push to the request's head
+
+  *Returns*
+
+  ``{String}`` Request result.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-string.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-string.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo-string.txt	(revision 672)
@@ -0,0 +1,147 @@
+.. _api-zoo-string:
+
+ZOO.String
+==========
+
+Contains convenience methods for string manipulation:
+
+Functions and Properties
+------------------------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`startsWith <startsWith>`
+     - Test whether a string starts with another string.
+   * - :ref:`contains <contains>`
+     - Test whether a string contains another string.  
+   * - :ref:`trim <trim>` 
+     - Removes leading and trailing whitespace characters from a string.
+   * - :ref:`camelize <camelize>`
+     - Camel-case a hyphenated string.    
+   * - :ref:`tokenRegEx <tokenRegEx>`
+     - Used to find tokens in a string.     
+   * - :ref:`numberRegEx <numberRegEx>` 
+     - Used to test strings as numbers.
+   * - :ref:`isNumeric <isNumeric>`
+     - Determine whether a string contains only a numeric value. 
+   * - :ref:`numericIf <numericIf>`
+     - Converts a string that appears to be a numeric value into a number.        
+
+.. _startsWith:
+
+startsWith
+  ::
+  
+    startsWith: function(str,sub)
+
+  Test whether a string starts with another string.
+
+  *Parameters*
+  
+  | ``str {String}`` The string to test.
+  | ``sub {Sring}`` The substring to look for.
+
+  *Returns*
+
+  ``{Boolean}`` The first string starts with the second.
+  
+.. _contains:
+
+contains	
+  ::
+  
+    contains: function(str,sub)
+
+  Test whether a string contains another string.
+
+  *Parameters*
+  
+  | ``str {String}`` The string to test.
+  | ``sub {String}`` The substring to look for.
+
+  *Returns*
+
+  ``{Boolean}`` The first string contains the second.
+  
+.. _trim:
+
+trim	
+  ::
+  
+    trim: function(str)
+
+  Removes leading and trailing whitespace characters from a string.
+
+  *Parameters*
+  
+  ``str	{String}`` The (potentially) space-padded string. This string is not modified.
+
+  *Returns*
+
+  ``{String}`` A trimmed version of the string with all leading and trailing spaces removed.
+
+.. _camelize:
+
+camelize	
+  ::
+  
+    camelize: function(str)
+
+  Camel-case a hyphenated string. Ex. "chicken-head" becomes "chickenHead", and "-chicken-head" becomes "ChickenHead".
+
+  *Parameters*
+  
+  ``str	{String}`` The string to be camelized.  The original is not modified.
+
+  *Returns*
+
+  ``{String}`` The string, camelized  
+  
+.. _tokenRegEx:  
+  
+tokenRegEx	
+  Used to find tokens in a string.  Examples: *${a}, ${a.b.c}, ${a-b}, ${5}*
+  
+.. _numberRegEx:    
+  
+numberRegEx	
+  Used to test strings as numbers.
+  
+.. _isNumeric:  
+  
+isNumeric	
+  ::
+  
+    isNumeric: function(value)
+
+  Determine whether a string contains only a numeric value.
+
+  *Examples*
+
+  ::
+  
+    ZOO.String.isNumeric("6.02e23") // true
+    ZOO.String.isNumeric("12 dozen") // false
+    ZOO.String.isNumeric("4") // true
+    ZOO.String.isNumeric(" 4 ") // false
+
+  *Returns*
+
+  ``{Boolean}`` String contains only a number. 
+  
+.. _numericIf:  
+
+numericIf	
+  ::
+  
+    numericIf: function(value)
+
+  Converts a string that appears to be a numeric value into a number.
+
+  *Returns*
+  
+  ``{Number|String}`` a Number if the passed value is a number, a String otherwise.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/api/zoo.txt	(revision 672)
@@ -0,0 +1,188 @@
+.. _api-zoo:
+
+ZOO
+===
+
+The following constants and functions are available for the ZOO class:
+
+Constants
+---------
+
+.. list-table::
+   :widths: 30 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`SERVICE_ACCEPTED <service_accepted>`
+     - {Integer} used for 
+   * - :ref:`SERVICE_STARTED <service_started>`
+     - {Integer} used for   
+   * - :ref:`SERVICE_PAUSED <service_paused>` 
+     - {Integer} used for 
+   * - :ref:`SERVICE_SUCCEEDED <service_succeeded>`
+     - {Integer} used for      
+   * - :ref:`SERVICE_FAILED <service_failed>`
+     - {Integer} used for        
+
+Functions
+---------
+
+.. list-table::
+   :widths: 12 50
+   :header-rows: 1
+
+   * - NAME
+     - DESCRIPTION
+   * - :ref:`removeItem <removeItem>`
+     - Remove an object from an array.   
+   * - :ref:`indexOf <indexOf>` 
+     - 
+   * - :ref:`extend <extend>` 
+     - Copy all properties of a source object to a destination object.  
+   * - :ref:`rad <rad>`  
+     -     
+   * - :ref:`distVincenty <distVincenty>`
+     - Given two objects representing points with geographic coordinates, 
+       this calculates the distance between those points on the surface of an  
+       ellipsoid. 
+   * - :ref:`Class <Class>` 
+     - Method used to create ZOO classes. 
+   * - :ref:`UpdateStatus <UpdateStatus>`
+     - Method used to update the status of the process      
+
+**Constants**
+
+.. _service_accepted:
+
+SERVICE_ACCEPTED	
+  ``{Integer}`` used for
+  
+.. _service_started:
+
+SERVICE_STARTED
+  ``{Integer}`` used for
+  
+.. _service_paused:  
+
+SERVICE_PAUSED	
+  ``{Integer}`` used for
+  
+.. _service_succeeded:  
+
+SERVICE_SUCCEEDED
+  ``{Integer}`` used for
+  
+.. _service_failed:    
+  
+SERVICE_FAILED	
+  ``{Integer}`` used for
+
+**Functions**
+
+.. _removeItem:
+
+removeItem	
+  ::
+  
+    removeItem: function(array,item)
+  
+  Remove an object from an array.  Iterates through the array to find the item, then removes it.
+  
+  *Parameters*
+  
+  | ``array {Array}``
+  | ``item {Object}``
+  
+  *Returns*
+   
+  ``{Array}`` A reference to the array
+  
+.. _indexOf:
+
+indexOf	
+  ::
+  
+    indexOf: function(array,obj)
+
+  *Parameters*
+   
+  | ``array {Array}``
+  | ``obj {Object}``
+
+  *Returns*
+
+  ``{Integer}`` The index at, which the first object was found in the array.  If not found, returns -1.
+
+.. _extend:
+
+extend
+  ::
+  
+    extend: function(destination,source)
+
+  Copy all properties of a source object to a destination object.  Modifies the passed in destination object.  
+  Any properties on the source object that are set to undefined will not be (re)set on the destination object.
+
+  *Parameters*
+  
+  | ``destination {Object}`` The object that will be modified
+  | ``source {Object}`` The object with properties to be set on the destination
+
+  *Returns*
+
+  ``{Object}`` The destination object.
+  
+.. _rad:  
+  
+rad	
+  ::
+  
+    rad: function(x)
+
+  *Parameters*
+  
+  | ``x {Float}``
+
+  *Returns*
+
+  ``{Float}``
+
+.. _distVincenty:
+
+distVincenty
+  ::
+
+    distVincenty: function(p1,p2)
+
+  Given two objects representing points with geographic coordinates, this calculates the distance between 
+  those points on the surface of an ellipsoid.
+
+  *Parameters:*
+
+  | ``p1`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` (or any object with both .x, .y properties)
+  | ``p2`` :ref:`{ZOO.Geometry.Point} <api-zoo-geometry-point>` (or any object with both .x, .y properties)
+
+.. _Class:
+
+Class	
+  ::
+  
+    Class: function()
+
+  Method used to create ZOO classes.  Includes support for multiple inheritance.
+  
+.. _UpdateStatus:  
+  
+UpdateStatus	
+  ::
+  
+    UpdateStatus: function(env,value)
+
+  Method used to update the status of the process
+
+  *Parameters*
+  
+  | ``env {Object}`` The environment object
+  | ``value {Float}`` The status value between 0 to 100
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/client/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/client/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/client/index.txt	(revision 672)
@@ -0,0 +1,12 @@
+.. _client:
+
+ZOO-Client Documentation
+========================
+
+The following sections will assist you with the ZOO-Client:
+
+.. toctree::
+   :maxdepth: 2
+   
+   introduction
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/client/introduction.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/client/introduction.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/client/introduction.txt	(revision 672)
@@ -0,0 +1,235 @@
+.. _services-howtos:
+
+How To Use ZOO-Client
+=========================
+
+:Authors: Nicolas Bozon, Luca Delucchi, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Id$
+
+ZOO-Client is a client-side Javascript API which ease the
+use and integration of WPS in your web applications.
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+Requirements
+----------------------
+
+The ZOO-Client is depending on various Javscript libraries, they are
+axhaustively listed bellow:
+ * `jQuery <http://www.jquery.com/>`__
+ * `x2js <https://code.google.com/p/x2js/>`__
+ * `requirejs <http://requirejs.org/>`__
+ * `Hogan.js <http://twitter.github.io/hogan.js/>`__
+ * `query-string <https://github.com/sindresorhus/query-string>`__
+
+Compile mustache templates
+**************************
+
+For being able to use the ZOO-Client API from your web appplication
+you will need to compile the mustache templates files located in the
+tpl directory. This compilation process imply that you have setup
+`node.js <http://nodejs.org/>`__ on your computer. 
+
+::
+
+    sudo npm install hogan
+    hulk zoo-client/lib/tpl/*mustache > \
+        zoo-client/lib/js/wps-client/payloads.js
+
+.. Note:: the Hogan version used to compile the template should be the
+    same as the one used from your web application, in other case you
+    may face compatibility issue.
+
+Build the API documentation
+***************************
+
+You can build the ZOO-Client API documentation by using jsDoc, to
+build the docuementation use the following command:
+
+::
+
+    npm install jsdoc
+    ~/node_modules/.bin/jsdoc zoo-client/lib/js/wps-client/* -p
+
+This will build the documentation in a directory named `out` in your
+current working directory.
+
+Create your first application
+-----------------------------
+
+For this first application, we will suppose that you have setup a
+directory named `zoo-client-demo` accessible from your server by using
+`http://localhost/zoo-client-demo`. In this directory, you should have
+the following subdirectories:
+
+:: 
+
+    assets
+    assets/js
+    assets/js/lib
+    assets/js/lib/hogan
+    assets/js/lib/jquery
+    assets/js/lib/query-string
+    assets/js/lib/xml2json
+    assets/js/lib/zoo
+    assets/tpl
+
+You will need to copy your node_modules javascript files copied in the
+`hogan` and `query-string` directories. First, you wil need to install
+query-string.
+
+:: 
+
+    npm install query-string
+
+Then you will copy `query-string.js` and `hogan-3.0.2.js` files in
+your `zoo-client-demo` web directory. Those files are located in your
+`~/node_modules` directory.
+
+For other libraries, you will need to download them from their
+official web sites and uncompress them in the corresponding
+directories.
+
+Loading the modules from your web application
+*********************************************
+
+Before using the ZOO-Client, you will first have to include the
+javascript files from your web page. With the use of requirejs you
+will need only one line in your HTML page to include everything at
+once. This line will look like the following:
+
+::
+
+    <script data-main="assets/js/first" src="assets/js/lib/require.js"></script>
+
+In this example, we suppose that you have created a `first.js` file
+in the `assets/js` directory containing your main application
+code. First, you define there the required JavaScript libraries and
+potentially their configuration, then you can add any relevant code.
+
+.. code-block:: javascript
+    :linenos:
+
+    requirejs.config({
+        baseUrl: 'assets/js',
+        paths: {
+            jquery: 'lib/jquery/jquery-1.11.0.min',
+            hogan: 'lib/hogan/hogan-3.0.2',
+            xml2json: 'lib/xml2json/xml2json.min',
+            queryString: 'lib/query-string/query-string',
+            wpsPayloads: 'lib/zoo/payloads',
+            wpsPayload: 'lib/zoo/wps-payload',
+            utils: 'lib/zoo/utils',
+            zoo: 'lib/zoo/zoo',
+            domReady: 'lib/domReady',
+            app: 'first-app',
+        },
+        shim: {
+            wpsPayloads: {
+                deps: ['hogan'],
+            },
+            wpsPayload: {
+                deps: ['wpsPayloads'],
+                exports: 'wpsPayload',
+            },
+            hogan: {
+                exports: 'Hogan',
+            },
+            xml2json: {
+              exports: "X2JS",
+            },
+            queryString: {
+                exports: 'queryString',
+            },
+        },
+    });
+    
+    requirejs.config({ 
+        config: {
+            app: {
+                url: '/cgi-bin/zoo_loader.cgi',
+                delay: 2000,
+            }
+        } 
+    });
+    
+    require(['domReady', 'app'], function(domReady, app) {
+        domReady(function() {
+            app.initialize();
+        });
+    });
+
+On line 2, you define the url where your files are located on the web
+server, in `assets/js`. From line 3 to 14, you define the JavaScript
+files to be loaded. From line 15 to 21, you configure the dependencies
+and exported symbols. From line 35 to 42, you configure your main
+application.
+
+In this application, we use the `domReady
+<http://github.com/requirejs/domReady>`__ module to call the
+`initialize` function defined in the `app` module, which is defined in
+the `first-app.js` file as defined on line 13.
+
+
+
+.. code-block:: javascript
+    :linenos:
+
+    define([
+        'module','zoo','wpsPayload'
+    ], function(module, ZooProcess, wpsPayload) {
+        
+        var myZooObject = new ZooProcess({
+            url: module.config().url,
+            delay: module.config().delay,
+        });
+        
+        var initialize = function() {
+            self = this;        
+            myZooObject.getCapabilities({
+               type: 'POST',
+                 success: function(data){
+                         console.log(data);
+                }
+            });
+
+            myZooObject.describeProcess({
+                type: 'POST',
+                identifier: "all",
+                success: function(data){
+                    console.log(data);
+                }
+            });
+
+           myZooObject.execute({
+               identifier: "Buffer",
+               dataInputs: [{"identifier":"InputPolygon","href":"XXX","mimeType":"text/xml"}],
+               dataOutputs: [{"identifier":"Result","mimeType":"application/json","type":"raw"}],
+               type: 'POST',
+               success: function(data) {
+                    console.log(data);
+               },
+               error: function(data){
+                    console.log(data);
+               }
+            });
+        }
+    
+        // Return public methods
+        return {
+            initialize: initialize
+        };
+    
+    });
+
+On line 5 you create a "global" `ZooProcess` instance named
+`myZooObject`, you set the `url` and `delay` to the values defined in
+`first.js` on line 35. From line 10 to 40,  you define a simple
+`initialize` function which will invoke the `getCapabilities` (line
+12 to 18), `describeProcess` (from line 20 to 26) and `execute` (from
+line 28 to 39) methods. For each you define a callback function which
+will simply display the resulting data in the browser's console.
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/community/developer.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/community/developer.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/community/developer.txt	(revision 672)
@@ -0,0 +1,99 @@
+.. _community_developer:
+
+ZOO-Project Committer Guildlines
+================================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+Election to SVN Commit Access
+-----------------------------
+
+Permission for SVN commit access shall be provided to new developers only if accepted by the ZOO-Project Project Steering Committee. A proposal should be written to the PSC for new committers and voted. 
+
+Removal of SVN commit access should be handled by the same process.
+
+The new committer should have demonstrated commitment to ZOO-Project and knowledge of the ZOO-Project source code and processes to the committee's satisfaction, usually by reporting bugs, submitting patches, and/or actively participating in the ZOO-Project mailing list(s).
+
+The new committer should also be prepared to support any new feature or changes that he/she commits to the ZOO-Project source tree in future releases, or to find someone to which to delegate responsibility for them if he/she stops being available to support the portions of code that he/she is responsible for.
+
+All committers should also be a member of the zoo-discuss mailing list so they can stay informed on policies, technical developments and release preparation.
+
+New commiters are responsible for having read, and understood this
+document.
+
+Committer Tracking
+------------------
+
+A list of all project committers will be kept in the main zoo-project directory (called COMMITTERS) listing for each SVN committer:
+
+    * Userid: the id that will appear in the SVN logs for this person.
+    * Full name: the users actual name.
+    * Email address: A current email address at which the committer can be reached. It may be altered in normal ways to make it harder to auto-harvest.
+
+SVN Administrator
+-----------------
+
+One member of the Project Steering Committee will be designed the SVN Administrator. That person will be responsible for giving SVN commit access to folks, updating the COMMITTERS file, and other SVN related management. That person will need login access on the SVN server of course.
+
+Initially Gérald Fenoy will be the SVN Adminstrator. 
+
+SVN Commit Practices
+--------------------
+
+The following are considered good SVN commit practices for the ZOO-Project project.
+
+   * Use meaningful descriptions for SVN commit log entries.
+   * Add a bug reference like "(#1234)" at the end of SVN commit log entries when committing changes related to a ticket in Trac. The '#' character enables Trac to create a hyperlink from the changeset to the mentionned ticket.
+   * After commiting changes related to a ticket in Trac, write the tree and revision in which it was fixed in the ticket description. Such as "Fixed in trunk (r12345) and in branches/1.7 (r12346)". The 'r' character enables Trac to create a hyperlink from the ticket to the changeset.
+   * Changes should not be committed in stable branches without a corresponding bug id. Any change worth pushing into the stable version is worth a bug entry.
+   * Never commit new features to a stable branch without permission of the PSC or release manager. Normally only fixes should go into stable branches.
+   * New features go in the main development trunk.
+   * Only bug fixes should be committed to the code during pre-release code freeze, without permission from the PSC or release manager. 
+   * Significant changes to the main development version should be discussed on the zoo-discuss list before you make them, and larger changes will require a to be discussed and approved on zoo-psc list by the PSC.
+   * Do not create new branches without the approval of the PSC. Release managers are assumed to have permission to create a branch.
+   * All source code in SVN should be in Unix text format as opposed to DOS text mode.
+   * When committing new features or significant changes to existing source code, the committer should take reasonable measures to insure that the source code continues to build and work on the most commonly supported platforms (currently Linux and Windows), either by testing on those platforms directly, running Buildbot tests, or by getting help from other developers working on those platforms. If new files or library dependencies are added, then the configure.in, Makefile.in, Makefile.vc and related documentations should be kept up to date. 
+
+Legal
+-----
+
+Committers are the front line gatekeepers to keep the code base clear of improperly contributed code. It is important to the ZOO-Project users, developers and the OSGeo foundation to avoid contributing any code to the project without it being clearly licensed under the project license.
+
+Generally speaking the key issues are that those providing code to be included in the repository understand that the code will be released under the MIT/X license, and that the person providing the code has the right to contribute the code. For the commiter themselves understanding about the license is hopefully clear. For other contributors, the commiter should verify the understanding unless the commiter is very comfortable that the contributor understands the license (for instance frequent contributors).
+
+If the contribution was developed on behalf of an employer (on work time, as part of a work project, etc) then it is important that an appropriate representative of the employer understand that the code will be contributed under the MIT/X license. The arrangement should be cleared with an authorized supervisor/manager, etc.
+
+The code should be developed by the contributor, or the code should be from a source which can be rightfully contributed such as from the public domain, or from an open source project under a compatible license.
+
+All unusual situations need to be discussed and/or documented.
+
+Committers should adhere to the following guidelines, and may be personally legally liable for improperly contributing code to the source repository:
+
+   * Make sure the contributor (and possibly employer) is aware of the contribution terms.
+   * Code coming from a source other than the contributor (such as adapted from another project) should be clearly marked as to the original source, copyright holders, license terms and so forth. This information can be in the file headers, but should also be added to the project licensing file if not exactly matching normal project licensing (zoo-project/zoo-kernel/LICENSE).
+   * Existing copyright headers and license text should never be stripped from a file. If a copyright holder wishes to give up copyright they must do so in writing to the foundation before copyright messages are removed. If license terms are changed it has to be by agreement (written in email is ok) of the copyright holders.
+   * Code with licenses requiring credit, or disclosure to users should be added to /trunk/zoo-project/zoo-kernel/LICENSE.
+   * When substantial contributions are added to a file (such as substantial patches) the author/contributor should be added to the list of copyright holders for the file.
+   * If there is uncertainty about whether a change it proper to contribute to the code base, please seek more information from the project steering committee, or the foundation legal counsel. 
+
+Bootstrapping
+------------
+
+The following existing commiters will be considered authorized ZOO-Project committers as long as they each review the commiter guidelines, and agree to adhere to them. The SVN administrator will be responsible for checking with each person.
+
+   * David SAGGIORATO (aka david)
+   * Gérald FENOY (aka djay)
+   * Jeff MCKENNA (aka jmckenna)
+   * Angelos TZOTSOS (aka kalxas)
+   * Luca DELUCCHI (aka lucadelu)
+   * Nicolas BOZON (aka nbozon)
+   * Markus NETELER (aka neteler)
+   * Marco NEGRETTI (aka nmarco)
+   * Knut LANDMARK (aka knut)
+   * René-Luc D'HONT (aka reluc)
+   * Trevor CLARKE (aka tclarke) 
Index: /branches/PublicaMundi_David_integration_01-devel/docs/community/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/community/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/community/index.txt	(revision 672)
@@ -0,0 +1,14 @@
+.. _community:
+
+ZOO Community
+=============
+
+The following sections will help you interact with the ZOO community.
+
+.. toctree::
+   :maxdepth: 2
+   
+   developer
+   mailinglist
+   irc
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/community/irc.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/community/irc.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/community/irc.txt	(revision 672)
@@ -0,0 +1,59 @@
+.. _community-irc:
+
+IRC Chat
+========
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna, Luca Delucchi
+:Last Updated: $Date$
+
+Some of the development of the ZOO-Project is coordinated through IRC. This page
+describes how you log on to chat, ask questions, and hack around with the
+developers.
+
+Server and Channel Information
+------------------------------
+
+::
+
+  Server: irc.freenode.net
+  Channel: #zoo-project
+
+Why IRC?
+--------
+
+IRC is a primary medium where Open Source GIS hackers congregate, collaborate,
+and hack. It makes it easy to communicate things like compilation issues,
+where immediate, iterative feedback allows folks to make a lot of progress.
+Something that might take days of heavily-quoted emails through a mailinglist
+might only take fifteen minutes on IRC.
+
+IRC is a great way to coordinate on-line meetings. The ZOO PSC conducts their
+monthly meetings through IRC.
+
+How do I join?
+--------------
+
+- `Chatzilla <http://chatzilla.hacksrus.com/>`__ is
+  probably the easiest way to get going. Chatzilla works with Mozilla or
+  Firefox, and once you have it installed, you can log on to the channel by
+  pointing your browser at::
+
+    irc://irc.freenode.net/#zoo-project
+
+- There are many other IRC clients available. `This page
+  <http://tikiwiki.org/ConnectingToIrc>`__ provides a good listing for many
+  different platforms.
+  
+- You can also connect to IRC directly in your Web browser without a client:
+
+  - goto http://webchat.freenode.net/
+  - enter a nickname (usually your first initial plus your last name)
+  - in "Channels" enter: zoo-project
+  - Connect!
+
+IRC logs
+-----------
+
+It is possible to see the logs (history) of ZOO-Project IRC channel
+`here <http://svn.zoo-project.org/irc/>`_
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/community/mailinglist.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/community/mailinglist.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/community/mailinglist.txt	(revision 672)
@@ -0,0 +1,28 @@
+.. _community-mailinglist:
+
+Mailing Lists
+=============
+
+ZOO-Discuss
+-----------
+
+The ``zoo-discuss`` list is your main source of support for the ZOO-Project.
+
+- **Subscribing to zoo-discuss**
+
+  To subscribe to the zoo-discuss listserv visit
+  http://lists.osgeo.org/cgi-bin/mailman/listinfo/zoo-discuss. You can later change
+  your subscription information or leave the list at this website.
+
+- **Submitting Questions to zoo-discuss**
+
+  To submit questions to the zoo-discuss listserv, first join the list by
+  following the subscription procedure above. Then post questions to the list by
+  sending an email message to zoo-discuss@lists.osgeo.org.
+
+- **Searching the Archives**
+
+  All zoo-discuss archives are located in
+  http://lists.osgeo.org/pipermail/zoo-discuss/.
+
+.. Searching the archives is best done with `Nabble <http://zoo-discuss.1049523.n5.nabble.com/>`_.:
Index: /branches/PublicaMundi_David_integration_01-devel/docs/conf.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/conf.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/conf.py	(revision 672)
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+#
+# ZOO Project documentation build configuration file, created by
+# sphinx-quickstart on Tue Mar 08 12:11:20 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'ZOO Project'
+copyright = u'2011, Nicolas Bozon, Gérald Fenoy, Jeff McKenna'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.4'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+html_theme_options = {
+    "rightsidebar": "true",
+    "headbgcolor": "#ffffff",
+    "bgcolor": "#ffffff",
+    "textcolor": "#333333",
+    "linkcolor": "#fc9326",
+    "visitedlinkcolor": "#fc9326",    
+    "sidebarbgcolor": "white",
+    "relbarbgcolor": "#ffa500"    
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = "ZOO Project " + release + " documentation"
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+html_short_title = "ZOO Docs"
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = 
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = "favicon.ico"
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+'**': ['globaltoc.html', 'sourcelink.html', 'searchbox.html'],
+"index":["indexsidebar.html",'searchbox.html']}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+html_show_copyright = False
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'ZOOProjectdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'ZOOProject.tex', u'ZOO Project Documentation',
+   u'Nicolas Bozon, Gérald Fenoy, Jeff McKenna', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+latex_logo = './_static/images/zoo-banner-large.png'
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+latex_preamble = '\setcounter{tocdepth}{3}'
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'zooproject', u'ZOO Project Documentation',
+     [u'Nicolas Bozon, Gérald Fenoy, Jeff McKenna'], 1)
+]
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'ZOO Project'
+epub_author = u'Nicolas Bozon, Gérald Fenoy, Jeff McKenna'
+epub_publisher = u'Nicolas Bozon, Gérald Fenoy, Jeff McKenna'
+epub_copyright = u'2011, Nicolas Bozon, Gérald Fenoy, Jeff McKenna'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+epub_scheme = 'URL'
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+epub_identifier = 'http://zoo-project.org'
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
Index: /branches/PublicaMundi_David_integration_01-devel/docs/development/documentation.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/development/documentation.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/development/documentation.txt	(revision 672)
@@ -0,0 +1,179 @@
+.. _documentation_development:
+
+Documentation Development Guide
+===============================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+
+License
+-----------------
+
+The ZOO-Project documentation is released under the `Creative Commons Attribution-ShareAlike 4.0 International Public License <https://creativecommons.org/licenses/by-sa/4.0/legalcode>`__ (CC-BY-SA). This license must be kept when editing or creating a new documentation file.
+
+.. image:: ../../_static/images/by-sa.png
+   :target: https://creativecommons.org/licenses/by-sa/4.0/legalcode/
+   :height: 31px
+   :width: 88px
+
+
+Background
+----------
+
+The current structure of the ZOO Project documentation process is for
+developers with :ref:`SVN <svn>` commit access to maintain their documents
+in reStructuredText format, and therefore all documents live in the
+/docs directory in SVN.  The `Sphinx <http://sphinx.pocoo.org/>`__ documentation generator is
+used to convert the reStructuredText files to html, and the live
+website is then updated on an hourly basis.
+
+reStructuredText Reference Guides
+---------------------------------
+
+- Docutils `Quick reStructuredText <http://docutils.sourceforge.net/docs/user/rst/quickref.html>`__
+- Docutils `reStructuredText Directives <http://docutils.sourceforge.net/docs/ref/rst/directives.html>`__
+- Sphinx's `reStructuredText Primer <http://sphinx.pocoo.org/rest.html>`__
+- search Sphinx's `mailing list <http://groups.google.com/group/sphinx-dev>`__
+
+reStructuredText Formatting
+---------------------------
+
+- All text should be hard breaks at or around the 80 column mark, just as
+  the source code.
+
+Installing and Using Sphinx for rst-html Generation
+---------------------------------------------------
+
+.. note::
+   
+    You can browse the versions of the Sphinx packages `here <http://pypi.python.org/pypi?%3Aaction=index>`__,
+    and then install the exact version such as:
+        
+    ::
+        
+        easy_install Sphinx==1.0.7
+
+
+**On Windows:**
+
+#. install `Python 2.X <http://www.python.org/>`__
+#. download `setuptools <http://pypi.python.org/pypi/setuptools#windows>`__
+#. make sure that the ``C:/Python2X/Scripts`` directory is your path
+#. execute the following at commandline:
+
+   ::
+
+       easy_install Sphinx
+
+   ...you should see message: "Finished processing dependencies for Sphinx"
+
+   .. note::
+   
+      Make sure you install Sphinx 1.0 or more recent.  See note above.
+      
+#. install `MiKTeX <http://miktex.org>`__ if you want to build pdfs
+      
+#. checkout the /docs directory from SVN, such as:
+
+   ::
+  
+       svn checkout http://svn.zoo-project.org/svn/trunk zoo-project
+      
+#. inside the /docs directory, execute:
+
+   ::
+
+       make html
+
+   or
+
+   ::
+
+       make latex
+
+   the HTML output will be written to the _build/html sub-directory.
+
+**On Linux:**
+
+#. make sure you have the Python dev and setuptools packages installed.
+   On Ubuntu:
+
+   ::
+
+       sudo apt-get install python-dev
+       sudo apt-get install python-setuptools
+
+#. install sphinx using easy_install:
+
+   ::
+
+       sudo easy_install Sphinx
+       
+   .. note::
+    
+      Make sure you install Sphinx 1.0 or more recent.  See note above.  
+      
+#. checkout the /docs directory from SVN, such as:
+
+   ::
+  
+       svn checkout http://svn.zoo-project.org/svn/trunk zoo-project      
+
+#. to process the docs, from the ZOO /docs directory, run:
+
+   ::
+
+       make html
+
+   or
+
+   ::
+
+       make latex
+
+   the HTML output will be written to the build/html sub-directory.
+
+.. note::
+
+    If there are more than one translation, the above commands will automatically
+    build all translations.
+
+
+**On Mac OS X:**
+
+#. install sphinx using easy_install:
+
+   ::
+
+       sudo easy_install Sphinx
+       
+   .. note::
+   
+      Make sure you install Sphinx 1.0 or more recent.  See note above.        
+
+#. install `MacTex <http://www.tug.org/mactex/2009/>`__ if you want to build pdfs
+
+#. checkout the /docs directory from SVN, such as:
+
+   ::
+  
+       svn checkout http://svn.zoo-project.org/svn/trunk zoo-project
+
+#. to process the docs, from the ZOO /docs directory, run:
+
+   ::
+
+       make html
+
+   or
+
+   ::
+
+       make latex
+
+   the HTML output will be written to the build/html sub-directory.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/index.txt	(revision 672)
@@ -0,0 +1,85 @@
+.. _home:
+
+ZOO 1.5 Documentation
+=====================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+Quick Links
+===========
+
+..   csv-table:: Quick Links
+
+    :ref:`kernel`,:ref:`services`,:ref:`api`
+    :ref:`kernel-installation`,:ref:`community`,`Search mailing list <http://zoo-discuss.1049523.n5.nabble.com/>`__
+    :ref:`documentation_development`,:ref:`workshop-foss4g-2014`
+
+.. note::
+    The entire documentation is also available as a single
+    `PDF document <./ZOOProject.pdf>`__ |image|  and `ePub document <./ZOOProject.epub>`__
+
+About ZOO Documentation
+=======================
+
+ZOO Documentation is a collaborative process; once users contribute documentation
+through the ZOO Wiki, the Documentation Committee will then review the contributions
+to add them into the official docs.  The committee is currently composed of:
+
+::
+
+  Nicolas Bozon (nicolas.bozon at gmail.com)
+  Gérald Fenoy (gerald.fenoy at geolabs.fr)
+  Jeff McKenna (jmckenna at gatewaygeomatics.com)
+  
+A special thank to the ZOO-Project sponsors and knwoledge partners for their support.
+  
+The committee would like to thank ``Venkatesh Raghavan`` for his help on promoting ZOO Workshop in many places.
+
+The committee would like to thank ``Hirofumi Hayashi`` and ``Daisuke Yoshida`` for their help and japanese translation effort for the ZOO-Project Worshop 2010.
+  
+The committee would also like to thank the early contributors to the documentation: ``Luca Delucchi``, ``René-Luc D'Hont``,  ``Angelos Tzotsos`` and ``Guillaume Sueur``.
+
+License
+=======================
+
+The ZOO-Project documentation is released under the
+`Creative Commons Attribution-ShareAlike 4.0 International Public License <https://creativecommons.org/licenses/by-sa/4.0/legalcode>`__
+(CC-BY-SA). This license must be kept when editing or creating a new documentation file.
+
+.. image:: ./_static/images/by-sa.png
+   :target: https://creativecommons.org/licenses/by-sa/4.0/legalcode/
+   :height: 31px
+   :width: 88px
+
+
+ZOO Wiki
+========
+
+Users wishing to contribute steps and documents should use the
+`ZOO Wiki <http://www.zoo-project.org/trac>`__.  
+
+Official Documentation
+======================
+
+This section contains the official ZOO Project documentation.
+    
+.. |image| image:: _static/images/pdf.png
+   :height: 15
+   :width: 15
+   :alt: PDF icon
+   :target: /ZOOProject.pdf
+
+.. toctree::
+   :maxdepth: 3
+   
+   kernel/index
+   services/index
+   api/index
+   client/index
+   workshop/2014/index
+   community/index
+   development/documentation
+
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/index.txt	(revision 672)
@@ -0,0 +1,16 @@
+.. _kernel:
+
+ZOO Kernel Documentation
+========================
+
+The following sections will assist you with the ZOO Kernel:
+
+.. toctree::
+   :maxdepth: 2
+   
+   introduction
+   installation
+   mapserver
+   orfeotoolbox
+   sagagis
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-centos.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-centos.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-centos.txt	(revision 672)
@@ -0,0 +1,168 @@
+.. _kernel-installation-centos:
+
+CentOS
+======
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+.. note::
+   This documentation was created thanks to Guillaume Sueur from Neogeo Technologies which took time to test 
+   installing the ZOO-Kernel on a CentOS 5.5 environment.
+
+Requirements
+------------
+
+Install some standard tools to be able to run ZOO-Kernel on your platform :
+
+::
+
+  yum install apache2
+  yum install build-essentials
+  yum install gcc-c++
+  yum install zlib-devel
+  yum install libxml2-devel
+  yum install bison
+  yum install openssl 
+  yum install python-devel
+  yum install subversion
+
+Compile then install FastCGI library from source
+
+::
+
+  wget http://www.fastcgi.com/dist/fcgi.tar.gz
+  tar xzf fcgi-2.4.0.tar.gz 
+  ./configure
+  make
+  make install
+  echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
+  ldconfig
+
+Compile then install the autoconf tools :
+
+::
+
+  wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
+  tar xzf autoconf-latest.tar.gz
+  ./configure --prefix=/usr
+  make 
+  make install
+
+Compile then install the flex tool :
+
+::
+
+  wget http://downloads.sourceforge.net/project/flex/flex/flex-2.5.35/flex-2.5.35.tar.gz?r=http%3A%2F%2Fflex.sourceforge.net%2F&ts=1292529005&use_mirror=switch
+  tar xzf flex-2.5.35.tar.gz
+  cd flex-2.5.35
+  ./configure --prefix=/usr
+  make
+  make install
+
+Using the curl provided in the CentOS distribution will produce a ZOO-Kernel unable to run any 
+Service. Indeed, some segmentation faults occur when trying to run ``Execute`` requests on the ZOO-Kernel, 
+compiling the ZOO-Kernel setting ``USE_GDB`` flag in the ``CFLAGS`` of your ``Makefile`` will let you run 
+ZOO-Kernel from gdb and be able to get more information on what is going wrong with your ZOO-Kernel. 
+Doing this we can figure out that code on `line 173 <http://zoo-project.org/trac/browser/trunk/zoo-kernel/ulinet.c#L173>`__ 
+and `line 175 <http://zoo-project.org/trac/browser/trunk/zoo-kernel/ulinet.c#L175>`__ have to be commented in the 
+``ulinet.c`` file to get a ZOO-Kernel working using the curl available in CentOS (curl version 7.15.5). 
+If you don't apply the modification, you will get an error from a gdb session pointing 
+segfault in ``Curl_cookie_clearall``.
+
+You can optionally compile then install curl from source :
+
+::
+
+  wget http://curl.haxx.se/download/curl-7.21.3.tar.bz2
+  tar xjf curl-7.21.3.tar.bz2
+  cd curl-7.21.3
+  ./configure --prefix=/usr
+  make
+  make install
+
+Compile then install Python :
+
+::
+ 
+  wget http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tar.bz2
+  tar xjf Python-2.6.6.tar.bz2
+  cd Python-2.6.6
+  ./configure
+  make
+  make install
+
+Compile then install your own GDAL library :
+
+::
+
+  wget http://download.osgeo.org/gdal/gdal-1.7.3.tar.gz
+  tar xzf gdal-1.7.3.tar.gz
+  cd gdal-1.7.3
+  ./configure  # add your options here
+  make
+  make install
+
+Install the Sun JAVA SDK into ``/usr/share`` then use the following command to ensure that the ``libjvm.so`` 
+will be found at runtime from any context.
+
+::
+
+  echo /usr/share/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386/client/ >> /etc/ld.so.conf.d/jvm.conf
+  ldconfig
+
+Compile ZOO-Kernel and ZOO-Services
+-----------------------------------
+
+Compile then install ZOO-Kernel and your first ZOO-Services.
+
+First of all, compile the cgic library providen in the SVN source tree:
+
+::
+
+  svn co http://svn.zoo-project.org/svn/trunk zoo-project
+  cd zoo-project/thirds/cgic206
+  make
+
+Compile then install ZOO-Kernel.
+
+::
+
+  cd ../../zoo-kernel
+  ./configure --with-java=/usr/share/jdk1.6.0_23/ --with-python
+  make zoo_loader.cgi
+  cp main.cfg /var/www/cgi-bin/
+  cp  zoo_loader.cgi /var/www/cgi-bin/
+
+Compile then deploy your first ZOO-ServicesProviders (simple HelloPy, line 1 and 2, and the OGR base-vect-ops 
+ServiceProvider, line 3 to 6):
+
+::
+
+  cp ../zoo-services/hello-py/cgi-env/*.zcfg /var/www/cgi-bin/
+  cp ../zoo-services/hello-py/test_service.py /var/www/cgi-bin/
+  cd ../ogr/base-vect-ops/
+  make
+  cp ./cgi-env/* /var/www/cgi-bin/
+  vi /var/www/cgi-bin/main.cfg --> set your own informations here
+
+To ensure that the ``libjvm.so`` will be found from apache, please restart it :
+
+::
+
+  /etc/init.d/httpd restart
+
+Testing your ZOO-Kernel
+-----------------------
+
+Test your ZOO-Kernel from command line:
+
+::
+
+  cd /var/www/cgi-bin
+  ./zoo_loader.cgi "request=Execute&service=WPS&version=1.0.0&Identifier=HelloPy&DataInputs=a=Djay"
+  ./zoo_loader.cgi "request=Execute&service=WPS&version=1.0.0&Identifier=Buffer&DataInputs=BufferDistance=1@datat
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-debian.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-debian.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-debian.txt	(revision 672)
@@ -0,0 +1,253 @@
+.. _kernel-installation-debian:
+
+Debian / Ubuntu
+===============
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna, Luca Delucchi
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+.. note::
+   An Ubuntu 10.4 with ZOO virtual image is available at http://www.zoo-project.org/Ubuntu10.4_ZOO.zip
+   (root: ZOO.test)
+
+Ubuntu 12.04 dependencies
+--------------------------------------
+
+- install default dependencies
+
+::
+
+  sudo apt-get install flex bison libfcgi-dev libxml2 libxml2-dev curl openssl autoconf apache2 python-software-properties subversion libmozjs185-dev python-dev build-essential
+
+- add ubuntugis repository to obtain the newer GIS libraries
+
+::
+
+  sudo add-apt-repository ppa:ubuntugis/ppa
+  sudo apt-get update
+
+
+- install geographic library
+
+::
+
+  sudo apt-get install libgdal1-dev
+
+- download ZOO  source
+
+Debian 7.0 dependencies
+--------------------------------------
+
+- install dependencies
+
+::
+
+  apt-get install flex bison libfcgi-dev libxml2 libxml2-dev curl openssl autoconf apache2 python-software-properties subversion python-dev libgdal1-dev build-essential libmozjs185-dev
+
+
+Installation Workflow
+--------------------------------------
+
+.. note :: In the following lines you will find ``as administrator user`` note,
+	   on Ubuntu you have to add ``sudo`` at the beginning of line, on Debian
+	   you can use ``su -c COMMAND``)
+
+::
+
+  svn checkout http://svn.zoo-project.org/svn/trunk zoo-project
+
+- install cgic from packages
+
+::
+
+  cd zoo-project/thirds/cgic206/
+
+- compile
+
+::
+
+  make
+
+- if you want use Mapserver (optional) for WMS, WFS and WCS output read :ref:`mapserver`
+
+- go to kernel path
+
+::
+
+  cd ../../zoo-project/zoo-kernel/
+
+- create configure file
+
+::
+
+  autoconf
+
+- run configure
+
+::
+
+  ./configure --with-js --with-python
+
+.. note:: For PHP, you must make sure to compile PHP with `--enable-embed <http://www.zoo-project.org/trac/wiki/ZooKernel/Embed/PHP#ConfigureandInstallPHPEmbedlibrary>`__.
+
+.. note:: To use MapServer add the option ``--with-mapserver=/path/to/mapserver/source`` 
+
+- compile
+
+::
+
+  make
+
+- copy necessary files into your cgi-bin (as administrator user)
+
+
+::
+
+  cp main.cfg /usr/lib/cgi-bin
+  cp zoo_loader.cgi /usr/lib/cgi-bin
+
+- install ZOO ServiceProvider, in this case we try Python service (as administrator user)
+
+::
+
+  cp ../zoo-services/hello-py/cgi-env/*.zcfg /usr/lib/cgi-bin
+  cp ../zoo-services/hello-py/*.py /usr/lib/cgi-bin/
+
+- change some information in the main.cfg (as administrator user)
+
+::
+
+  nano /usr/lib/cgi-bin/main.cfg
+  - serverAddress = http://127.0.0.1
+
+
+- try the installation
+
+  - http://127.0.0.1/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=GetCapabilities&Version=1.0.0
+  - http://127.0.0.1/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=DescribeProcess&Version=1.0.0&Identifier=HelloPy
+  - http://127.0.0.1/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=Execute&Version=1.0.0&Identifier=HelloPy&DataInputs=a=myname
+
+.. note::
+   If you have some problem in the execute request using Python service, add the following to ``main.cfg``: 
+
+   ::
+   
+     [env]
+     PYTHONPATH=<YOUR_PYTHONPATH>
+
+
+Rewrite rule configuration
+-----------------------------
+
+- for better readability and fully functional ZOO Kernel, you have to modify the default
+  Apache configuration in order to be able to use the http://localhost/zoo/ url directly.
+  Run (as administrator user)
+
+::
+
+    nano /usr/lib/cgi-bin/main.cfg
+    - serverAddress = http://localhost/zoo
+
+- first, please create a ``zoo`` directory in ``/var/www/`` which is used by Apache as the
+  DocumentRoot (as administrator user)
+
+::
+
+  mkdir /var/www/zoo
+
+- Then, please edit the ``/etc/apache2/sites-available/default`` configuration file and add the following
+  lines after the Directory block related to /var/www directory (as administrator user)
+
+::
+
+  <Directory /var/www/zoo/>
+      Options Indexes FollowSymLinks MultiViews
+      AllowOverride All
+      Order allow,deny
+      allow from all
+  </Directory>
+
+- now create a small .htaccess file in the ``/var/www/zoo`` containing the following lines (as administrator user)
+
+::
+
+  RewriteEngine on
+  RewriteRule call/(.*)/(.*) /cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=$1&DataInputs=sid=$2&RawDataOutput=Result [L,QSA]
+  RewriteRule (.*)/(.*) /cgi-bin/zoo_loader.cgi?metapath=$1 [L,QSA]
+  RewriteRule (.*) /cgi-bin/zoo_loader.cgi [L,QSA]
+
+
+- for this last file to be taken into account by Apache, you must activate the
+  rewrite Apache module by copying a load file as bellow (as administrator user)
+
+::
+
+  cp /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/
+
+- or using the a2enmod tool this way (as administrator user)
+
+::
+
+  a2enmod rewrite
+
+- now you should be able to access the ZOO Kernel using a simplified by restarting
+  your Apache Web server (as administrator user)
+
+::
+  /etc/init.d/apache2 restart
+
+- now you can try:
+
+  - http://localhost/zoo/?Service=WPS&Request=GetCapabilities&Version=1.0.0
+  - http://localhost/zoo/?Service=WPS&Request=DescribeProcess&Version=1.0.0&Identifier=HelloPy
+  - http://localhost/zoo/?Service=WPS&Request=Execute&Version=1.0.0&Identifier=HelloPy&DataInputs=a=myname
+
+.. _mapserver:
+
+Compile MapServer
+------------------
+
+- install MapServer dependencies (as administrator user)
+
+::
+
+  apt-get install git libfreetype6-dev libproj-dev libkml-dev libcairo-dev libxml2-dev libgd2-xpm-dev libxslt1-dev
+
+- extract MapServer from git repository
+
+::
+
+  git clone https://github.com/mapserver/mapserver.git
+  cd mapserver
+  git checkout branch-6-2
+  git pull
+
+- now compile MapServer
+
+::
+
+  ./configure --with-ogr --with-gdal --with-wfsclient --with-wmsclient --with-tiff --with-jpeg --with-gd --with-wcs --with-sos --with-xml2-config --with-wfs --with-fastcgi --with-proj --with-cairo --with-kml=yes --with-xslt --with-threads --with-geos
+  make
+
+- now install MapServer (as administrator user)
+
+::
+
+  make install
+
+- now add path to libraries path (as administrator user)
+
+::
+
+  nano /etc/ld.so.conf.d/mapserver.conf
+  - /usr/local/lib/
+
+- run as administrator
+
+::
+
+  ldconfig
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-mac.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-mac.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-mac.txt	(revision 672)
@@ -0,0 +1,191 @@
+.. _kernel-installation-mac:
+
+Mac OS X
+========
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+Using the Installer
+-------------------
+
+1. To install a default build of the ZOO-Project on your Mac OS X computer use the `installer <http://www.zoo-project.org/trac/raw-attachment/wiki/ZooDocumentation/ZOOKernel/MacOSX_installation/ZOO-Project-Installer.pkg>`__.
+
+   .. note::
+      The installer assumes that you are using the distributed Apache2 version that comes with your Mac.  The installer will
+      place ZOO-Kernel and ZOO-Services into your cgi-bin at ``/Library/WebServer/CGI-Executables``, and the zoo-demo folder
+      will be placed within your document root at ``/Library/WebServer/Documents``
+
+2. Make sure that your Apache server is running, and then access the ZOO Project Demo at:
+
+      http://localhost/zoo-demo/spatialtools.html
+      
+3. To add additional services, please follow the following intructions to compile your own ZOO Project instance.
+
+Compiling from Source
+---------------------
+
+1. Install `Xcode <http://developer.apple.com/technologies/tools/>`__.
+
+2. Before you start downloading the ZOO-Project source code, you'll need to install some tools required to 
+   compile ZOO-Kernel properly.
+
+   First of all install PROJ, GEOS and GDAL frameworks from `here <http://www.kyngchaos.com/software/frameworks>`__.
+
+   At this step, you should get the following directories on your local hard drive :
+
+   ::
+   
+     /Library/Frameworks/PROJ.framework
+     /Library/Frameworks/GEOS.framework
+     /Library/Frameworks/GDAL.framework
+
+3. Then, create a ``src`` directory and inside that directory download the `gettext source code <http://www.gnu.org/software/gettext/#TOCdownloading>`__ and uncompress it.
+
+   now, compile gettext with the following commands to produce a universal binary :
+
+   ::
+   
+     cd gettext-0.18.1.1
+     CFLAGS="-O -g -arch i386 -arch ppc -arch x86_64"  \
+       LDFLAGS="-arch i386 -arch ppc -arch x86_64"   ./configure
+     make
+     sudo make install
+
+4. Compile and install your ZOO-Kernel
+
+   - Download source from SVN, and use the following command to compile libcgic :
+
+     ::
+     
+       svn co http://svn.zoo-project.org/svn/trunk zoo
+       cd zoo/thirds/cgic206
+       make
+
+   - If you produced the ``libcgic.a`` file, you can run ``autoconf`` and then ``configure`` from zoo-kernel directory.
+
+     ::
+     
+       cd zoo/zoo-kernel
+       autoconf
+       ./configure --with-python --with-java=macos \
+          --with-gdal-config=/Library/Frameworks/GDAL.framework/Versions/1.8/Programs/gdal-config
+
+     Obviously, if you don't need Python or Java support then you should remove the corresponding configure option.
+
+     .. note:: 
+        Note that we used the --with-java=macos configure option. Due to the generic location of the JDK on all 
+        Mac OS X platforms, you don't have to provide its full path.
+
+   - Now, run the following commands to compile and deploy your ZOO-Kernel on your Apache server :
+
+     ::
+     
+       make
+       cp zoo_loader.cgi main.cfg /Library/WebServer/CGI-Executables
+
+     You should be ready to request your ZOO-Kernel installation using the following link :  http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS .
+
+     If everything is ok, you can follow the next steps to deploy new Services Providers.
+     
+     .. note::
+        If you are using your own libs (not the default libs on your system) then you must take care to create
+        universal versions of those libs, as the ZOO-Kernel will try to create a universal binary.  If you are
+        not following this advice, you might receive compile errors of ``symbol(s) not found for architecture ppc`` or ``file was built for 
+        unsupported file format which is not the architecture being linked (ppc)``.
+     
+Deploy the OGR Services Provider
+--------------------------------
+
+Requirements
+************
+
+Before your try to use any service, please set the correct path in the ``main.cfg`` for tmpPath and tmpUrl.
+
+You can use the following setup :
+
+::
+
+  tmpPath = /Library/WebServer/Documents/tmp
+  tmpUrl = ../../tmp
+
+Obviously you'll then need to create this directory, using the following command :
+
+::
+
+  mkdir /Library/WebServer/Documents/tmp
+
+C Version
+*********
+
+To compile the base-vect-ops ServicesProvider you'll need to edit the Makefile in *zoo/zoo-services/ogr/base-vect-ops/* 
+directory. Add "-I/Library//Frameworks/GEOS.framework/Versions/3/Headers/" to the CFLAGS value on the first line. 
+To compile, add GDAL framework to the PATH environmenet variable, to ensure that gdal-config tool will be found, 
+run make and then copy cgi-env files in the /Library/WebServer/CGI-Executables directory.
+
+::
+
+  cd zoo/zoo-services/ogr/base-vect-ops/
+  export PATH=$PATH:/Library/Frameworks/GDAL.framework/Versions/1.7/Programs/
+  make
+  cp cgi-env/* /Library/WebServer/CGI-Executables
+
+You can test using this `url <http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Buffer&DataInputs=BufferDistance=1@datatype=interger;InputPolygon=Reference@xlink:href=http%3A%2F%2Fwww.zoo-project.org%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID%3Dstates.15>`__ 
+if everything is ok with your setup.
+
+Python Version
+**************
+
+**Requirements**
+
+First of all run python from a Terminal.app and try the following import from the python interpreter :
+
+::
+
+  import osgeo.ogr
+  import libxml2
+
+If you get an issue when importing the libxml2 module from your python interpreter then that means you 
+need to install the Python support for the libxml2 library which is already installed on your Mac OS X environment. 
+To accomplish this, you have first to determine what version of libxml2 is installed on your platform, using the following command:
+
+xml2-config --version
+
+Download the source corresponding to your version (i.e. on 10.6.6 you get 2.7.3) from the libxml2  
+`download page <ftp://xmlsoft.org/libxml2/>`__ into your ``src`` directory then uncompress it.
+
+Use the following command to install the python support :
+
+::
+
+  cd src/libxml2-2.7.3/python/
+  python setup.py install
+
+**Deploy OGR Python Services Provider**
+
+- Now copy the ``zoo-services/ogt/base-vect-ops/cgi-env`` files into ``/Library/WebServer/CGI-Executables``.
+
+You can test using this `url <http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=BufferPy&DataInputs=BufferDistance=1@datatype=interger;InputPolygon=Reference@xlink:href=http%3A%2F%2Fwww.zoo-project.org%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID%3Dstates.15>`__ 
+if everything is ok with your setup.
+
+Test using Local Demo Page
+--------------------------
+
+- Download the `OpenLayers <http://openlayers.org>`__ library and uncompress it in your personal Sites directory 
+  (located in your home directory). 
+  
+- Rename the OpenLayers directory as openlayers. 
+
+- Download this `zip archive <http://www.zoo-project.org/trac/raw-attachment/wiki/ZooDocumentation/ZOOKernel/MacOSX_installation/zoo-demo.zip>`__ 
+  and then uncompress it in your personal Sites directory. 
+  
+- Load your local demo pages using urls similar to the following (replacing MyUserName by your MacOS user name) :
+
+    *  http://localhost/~MyUserName/zoo-demo/spatialtools.html
+    *  http://localhost/~MyUserName/zoo-demo/spatialtools-py.html 
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-opensuse.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-opensuse.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-opensuse.txt	(revision 672)
@@ -0,0 +1,67 @@
+.. _kernel-installation-opensuse:
+
+OpenSUSE
+========
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+Zoo-Kernel is maintained as a package in `OpenSUSE Build Service (OBS) <https://build.opensuse.org/package/show?package=zoo-kernel&project=Application%3AGeo>`__. 
+This way, rpm's are provided for all versions of openSUSE Linux (11.2, 11.3, 11.4, Factory).
+
+Stable Releases
+---------------
+
+For installing Zoo-Kernel in openSUSE there are 3 ways available:
+
+One Click Installer
+*******************
+
+One-click installer that can be found  `here <http://software.opensuse.org/search?q=zoo-kernel&baseproject=openSUSE%3A11.4&lang=en&exclude_debug=true>`__. 
+For openSUSE 11.4 this is the direct `link <http://software.opensuse.org/ymp/Application:Geo/openSUSE_11.4/zoo-kernel.ymp?base=openSUSE%3A11.4&query=zoo-kernel>`__.
+
+Yast Software Manager using a GUI
+*********************************
+
+The `Application:Geo <http://download.opensuse.org/repositories/Application:/Geo/>`__ repository has to be added 
+to the Software Repositories and then Zoo-kernel can be found in Software Management through search.
+
+Command line (as root for openSUSE 11.4)
+****************************************
+
+::
+
+  zypper ar http://download.opensuse.org/repositories/Application:/Geo/openSUSE_11.4/
+  zypper refresh
+  zypper install zoo-kernel
+
+Unstable Version
+----------------
+
+The latest development version of ZOO-Kernel can be found in OBS under the project `home:tzotsos <https://build.opensuse.org/project/show?project=home%3Atzotsos>`__. 
+ZOO-Kernel packages are maintained and tested there before being released to the Application:Geo repository.
+
+Installation methods are identical as the stable version. Make sure to use `this <http://download.opensuse.org/repositories/home:/tzotsos/>`__ repository instead.
+
+Command line installation (as root for openSUSE 11.4)
+*****************************************************
+
+::
+
+  zypper ar http://download.opensuse.org/repositories/home:/tzotsos/openSUSE_11.4/
+  zypper refresh
+  zypper install zoo-kernel
+  zypper install zoo-kernel-grass-bridge
+
+Additionally, there is the option of adding the zoo-wps-grass-bridge package. This option will automatically install grass7 (svn trunk).
+
+Try the Installation
+--------------------
+
+- http://localhost/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=GetCapabilities&Version=1.0.0
+- http://localhost/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=DescribeProcess&Version=1.0.0&Identifier=HelloPy
+- http://localhost/cgi-bin/zoo_loader.cgi?ServiceProvider=&metapath=&Service=WPS&Request=Execute&Version=1.0.0&Identifier=HelloPy&DataInputs=a=myname
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-prerequisites.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-prerequisites.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-prerequisites.txt	(revision 672)
@@ -0,0 +1,76 @@
+.. _kernel-installation-prereq:
+
+Prerequisites
+=============
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna, Luca Delucchi
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+Obtaining the ZOO Kernel Source
+-------------------------------
+
+.. _svn:
+
+Use the following command to get the ZOO Kernel source code through Subversion:
+
+::
+
+  svn checkout http://svn.zoo-project.org/svn/trunk zoo-project
+
+For users which get a developer account, use the following:
+
+::
+
+  sed "s:\[tunnels\]:\[tunnels\]\nzoosvn = /usr/bin/ssh -p 1046:g" -i ~/.subversion/config
+  svn co svn+zoosvn://svn.zoo-project.org/var/svn/repos/trunk zoo-project
+
+The first line of the instruction above defines a specific tunnel to access the svn server through 
+the SSH protocol. Indeed, the ZOO SVN server listens on the 1046 (1024+22) port rather than the default one (22).
+
+Prerequisites
+-------------
+
+The following libraries are required on your system before you can install the ZOO Kernel:
+
+- autoconf (  http://www.gnu.org/software/autoconf/ ) 
+- cgic (  http://www.boutell.com/cgic )
+- cURL (  http://curl.haxx.se )
+- FastCGI (  http://www.fastcgi.com )
+- Flex & Bison (  http://flex.sourceforge.net/  http://www.gnu.org/software/bison/ )
+- libxml2 (  http://xmlsoft.org )
+- OpenSSL (  http://www.openssl.org )
+- Python (  http://www.python.org )
+
+Optional libraries include:
+
+- MapServer (optional for WMS, WFS and WCS output) ( http://mapserver.org )
+- PHP Embedded (optional) (  http://www.php.net )
+- Java SDK (optional) (  http://java.sun.com )
+- SpiderMonkey (optional) (  http://www.mozilla.org/js/spidermonkey/ ) 
+
+Compile libcgic
+---------------
+
+The first step is to compile libcgic from the ``zoo-project/thirds`` directory. For such a task, please use 
+the following command:
+
+::
+
+  cd thirds/cgic206
+  make
+
+Make sure that a ``libcgic.a`` is created in your ``zoo-project/thirds/cgic206`` directory. If yes, then 
+you can go to the next step.
+
+On Windows, rather than using the make command, please use:
+
+::
+
+  nmake /f makefile.vc. 
+  
+.. warning::
+   If you don't compile libcgic first, and try to compile the ZOO Kernel, you will get an error such as *cannot find -lcgic*
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-unix.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-unix.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-unix.txt	(revision 672)
@@ -0,0 +1,233 @@
+.. _kernel-installation-unix:
+
+Unix
+====
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna, Luca Delucchi
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+.. note::
+   You must be sure to perform the :ref:`prerequisite steps <kernel-installation-prereq>` before following this page.
+
+For the impatient
+-----------------
+
+To build the ``zoo_loader.cgi`` CGI program with the default options, cd to the directory 
+where you extracted the ZOO Kernel source code package and use the following commands:
+
+::
+
+  $ cd zoo-kernel
+  $ autoconf  
+  $ ./configure
+  $ make
+
+Unless something went wrong, you should have executables in the current directory for the ``zoo_loader.cgi`` 
+CGI program. You can copy the ``zoo_loader.cgi`` program and the ``main.cfg`` file to your HTTP server's CGI 
+directory and start using it.
+
+At this step your ZOO-Kernel should work. Nevertheless, don't forget to correct the main.cfg settings 
+to set ``tmpPath`` and ``tmpUrl`` to fit your web server configuration.
+
+Configure Options
+-----------------
+
+Here is the list of available options as returned by *./configure --help*:
+
+::
+
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-gdal-config=FILE specify an alternative gdal-config file
+  --with-xml2config=FILE  specify an alternative xml2-config file
+  --with-mapserver=PATH   specify the path for MapServer compiled source tree
+  --with-python=PATH      To enable python support or specify an alternative
+                          directory for python installation, disabled by
+                          default
+  --with-pyvers=NUM       To use a specific python version
+  --with-php=PATH         To enable php support or specify an alternative
+                          directory for php installation, disabled by default
+  --with-perl=PATH        To enable perl support or specify an alternative
+                          directory for perl installation, disabled by default
+  --with-java=PATH        To enable java support, specify a JDK_HOME,
+                          disabled by default
+  --with-js=PATH          specify --with-js=path-to-js to enable js support,
+                          specify --with-js on linux debian like, js support
+                          is disabled by default
+
+All the options are described in more details below.
+
+(Required) GDAL Support
+***********************
+
+If your gdal-config program is not found in your PATH then you can use the 
+``--with-gdal-config`` option to specify its location. For instance, let's suppose that your gdal-config 
+was installed in /usr/local/bin and this directory is not in your PATH, then you can use 
+the following command:
+
+::
+
+  $ ./configure --with-gdal-config=/usr/local/bin/gdal-config
+
+(Required) XML2 Support
+***********************
+
+If your xml2-config program is not found in your PATH then you can use the 
+``--with-xml2config`` option to specify its location. For instance, let's suppose that 
+your xml2-config was installed in /usr/local/bin and this directory is not in your PATH, 
+then you can use the following command:
+
+::
+
+  $ ./configure --with-xml2config=/usr/local/bin/xml2-config
+
+(Optional) MapServer Support
+*****************************
+
+If you want to activate the WMS, WFS and WCS outputs using MapServer then you will have
+to use the ``--with-mapserver`` option. You have to set the path to your ``mapserver-config``
+locate in the source code of MapServer as following command:
+
+::
+
+  $ ./configure --with-mapserver=/path/to/your/mapserver_config/
+
+(Optional) Python Support
+*************************
+
+If you want to activate Python support for the ZOO Kernel then you will have to use the 
+``--with-python`` option. If your python-config program is found in your PATH then you 
+don't have to specify the path where Python was installed, such as:
+
+::
+
+  $ ./configure --with-python
+
+This assumes that python-config is found in your PATH.
+
+In the case that your python-config is not found in your PATH, then you can specify the Python 
+installation directory you are using. For instance, let's suppose that you installed 
+Python in /usr/local, then you can use the following command:
+
+::
+
+  $ ./configure --with-python=/usr/local
+
+This assumes that /usr/local/bin/python-config exists.
+
+(Optional) Python Version
+*************************
+
+If you want use a specific version of Python you will have to use the ``--with-pyvers``
+option. You can specify a Python version as:
+
+::
+
+  $ ./configure --with-pyvers=2.6
+
+
+(Optional) PHP Support
+**********************
+
+To be able to activate PHP support for the ZOO Kernel you'll need to get a local PHP Embedded 
+installation; for more information about the required configure options when compiling PHP you 
+can refer to this page :
+
+     http://zoo-project.org/trac/wiki/ZooKernel/Embed/PHP
+
+If you want to activate the PHP support for the ZOO Kernel then you will have to use the 
+``--with-php`` option. If your php-config program is found in your PATH then you don't have 
+to specify the path where PHP was installed, then you can use the following commnd:
+
+::
+
+  $ ./configure --with-php
+
+This assumes that php-config is found in your PATH.
+
+In the case that your php-config is not found in your PATH, then you can specify the PHP installation 
+directory you are using. For instance, let's suppose that you installed PHP in /usr/local, 
+then you can use the following command:
+
+::
+
+  $ ./configure --with-php=/usr/local
+
+This assumes that /usr/local/bin/php-config exists.
+
+(Optional) Perl Support
+***********************
+
+If you want to activate Perl support for the ZOO Kernel then you will have to use the 
+``--with-perl`` option. If you do not set any value to this option, then the perl program will 
+be searched in your PATH. So in such a case, you can use the following command:
+
+::
+
+  $ ./configure --with-perl 
+
+This assumes that perl is found in your PATH.
+
+In the other case, for custom Perl installations, you can set the installation directory. For instance, 
+let's suppose that you installed Perl in /usr/local and /usr/local/bin is not in your PATH, 
+then you can use the following command:
+
+::
+
+  $ ./configure --with-perl=/usr/local
+
+This assumes that /usr/local/bin/perl exists.
+
+(Optional) Java Support
+***********************
+
+If you want to activate Java support for the ZOO Kernel then you will have to use the 
+``--with-java`` option and set the installation path of your Java SDK. For instance, 
+let's suppose that your Java SDK was installed in the /usr/lib/jvm/java-6-sun-1.6.0.22/ directory, 
+then you can use the following command:
+
+::
+
+  $ ./configure --with-java=/usr/lib/jvm/java-6-sun-1.6.0.22/
+
+This assumes that the include/linux and jre/lib/i386/client/ subdirectories exist in 
+/usr/lib/jvm/java-6-sun-1.6.0.22/, include/linux contains the jni.h headers file and 
+jre/lib/i386/client/ contains the libjvm.so file.
+
+.. note:: 
+   With Mac OS X you only have to set ``macos`` as the value for the ``--with-java`` option 
+   to activate Java support. For example:
+
+   ::
+
+     $ ./configure --with-java=macos
+
+(Optional) JavaScript Support
+*****************************
+
+If you want to activate JavaScript support for the ZOO Kernel then you will have to use 
+the ``--with-js`` option. If you are using a "Debian-like" GNU/Linux distribution then 
+dpkg will be used to detect if the required packages are installed and you don't have to 
+specify anything here, so you can use the following command:
+
+::
+
+  $ ./configure --with-js 
+
+This assumes that js_api.h and libmozjs.so are found in default directories.
+
+If you have a custom installation of SpiderMonkey or you are not using a Debian packaging 
+system, then you'll have to specify the directory where you installed it. For 
+instance, let's suppose that you installed your SpiderMonkey in /usr, then you'll 
+have to use the following command:
+
+::
+
+  $ ./configure --with-js=/usr
+
+This assumes that the /usr/include/js exists and contains the js_api.h headers file and 
+/usr/lib contains libmozjs.so file.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-windows.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-windows.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/install-windows.txt	(revision 672)
@@ -0,0 +1,175 @@
+.. _kernel-installation-windows:
+
+Windows
+=======
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 2
+    :backlinks: top
+
+Using OSGeo4W
+-------------
+
+Install OSGeo4W
+***************
+
+Download the OSGeo4W installer from  http://trac.osgeo.org/osgeo4w/, and install it with all the dependencies needed by your 
+services (GDAL/OGR for example). The following libs are required: FastCGI, libxml, Python, cURL.
+
+Install other tools and libraries
+*********************************
+
+After installing OSGeo4W on your platform you'll need more GNU tools and libraries. `This package <http://www.zoo-project.org/dl/tool-win32.zip>`__ 
+contains full dependencies required to compile on WIN32 platform and this one contains `full runtime dependencies to place <http://www.zoo-project.org/dl/zoo-runtime.zip>`__ 
+in your c:\OSGeo4W\bin.
+
+Download and Install ZOO Kernel
+*******************************
+
+Download the `binary version <http://www.zoo-project.org/dl/zoo_loader.cgi>`__  of the ZOO Kernel for WIN32 then place it in the 
+``C:\OSGeo4W\bin`` directory. Don't forget to place a ``main.cfg`` file in the same directory, you can use a modified copy of 
+`this file <http://www.zoo-project.org/trac/browser/trunk/zoo-kernel/main.cfg>`__.
+
+Deploy ZOO Services Providers
+*****************************
+
+Your can use the binary version of the OGR Services Provider available from `here <http://www.zoo-project.org/dl/zoo-services-win32.zip>`__. 
+Then place the two libraries with their respective .zcfg files in your local ``C:\OSGeo4W\bin`` directory.
+
+Testing
+*******
+
+Now you should be able to query your local ZOO Kernel. 
+
+Compiling Using Your Own Libraries
+----------------------------------
+
+.. note::
+   You must be sure to perform the :ref:`prerequisite steps <kernel-installation-prereq>` before compiling the ZOO Kernel.
+
+The following steps are for use with the Microsoft Visual Studio compiler (and tested with MSVC 2008).
+
+1. Make sure the gnuwin32 tools ``bison.exe`` and ``flex.exe`` are found in your path.  You can download the GNUwin32 tools `here <http://www.zoo-project.org/dl/tool-win32.zip>`__.
+
+2. Modify the file ``zoo-project\zoo-kernel\nmake.opt`` to point to your local libraries.  You can find a modified nmake.opt that points to local libs `here <http://www.zoo-project.org/trac/attachment/ticket/27/nmake.opt>`__. 
+   You can also find a modified ``zoo-project\zoo-kernel\makefile.vc`` file `here <http://www.zoo-project.org/trac/attachment/ticket/27/makefile.vc>`__.
+   
+3. Execute:
+
+   ::
+   
+     nmake /f makefile.vc
+     
+4. A file ``zoo_loader.cgi`` should be created.  Note that if another file named ``zoo_loader.cgi.manifest`` is also created, you
+   will have to run another command:
+   
+   ::
+   
+     nmake /f makefile.vc embed-manifest
+     
+5. Copy the files ``zoo_loader.cgi`` and ``main.cfg`` into your cgi-bin directory.
+
+6. Using the command prompt, test the zoo-kernel by executing the following command:
+
+   ::
+   
+     D:\ms4w\Apache\cgi-bin> zoo_loader.cgi
+     
+   which should display a message such as:
+   
+   ::
+   
+     Content-Type: text/xml; charset=utf-8
+     Status: 200 OK
+     
+     <?xml version="1.0" encoding="utf-8"?>
+     <ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd" xml:lang="en-US" version="1.1.0">
+       <ows:Exception exceptionCode="MissingParameterValue">
+         <ows:ExceptionText>Parameter &lt;request&gt; was not specified</ows:ExceptionText>
+       </ows:Exception>
+     </ows:ExceptionReport>
+     
+7. Edit the file ``cgi-bin/main.cfg`` so that it contains values describing your WPS service.  An example of such 
+   a file running on Windows is:
+   
+   ::
+   
+     [main]
+     encoding = utf-8
+     version = 1.0.0
+     serverAddress = http://localhost/
+     lang = en-CA
+     tmpPath=/ms4w/tmp/ms_tmp/
+     tmpUrl = /ms_tmp/
+     
+     [identification]
+     title = The Zoo WPS Development Server
+     abstract = Development version of ZooWPS. See http://www.zoo-project.org
+     fees = None
+     accessConstraints = none
+     keywords = WPS,GIS,buffer
+     
+     [provider]
+     providerName=Gateway Geomatics
+     providerSite=http://www.gatewaygeomatics.com
+     individualName=Jeff McKenna
+     positionName=Director
+     role=Dev
+     adressDeliveryPoint=1101 Blue Rocks Road
+     addressCity=Lunenburg
+     addressAdministrativeArea=False
+     addressPostalCode=B0J 2C0
+     addressCountry=ca
+     addressElectronicMailAddress=info@gatewaygeomatics.com
+     phoneVoice=False
+     phoneFacsimile=False
+     
+8. Open a web browser window, and execute a GetCapababilites request on your WPS service: http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS
+
+   The response should be displayed in your browser, such as:
+   
+   ::
+   
+     <wps:Capabilities xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_response.xsd" service="WPS" xml:lang="en-US" version="1.0.0">
+     <ows:ServiceIdentification>
+       <ows:Title>The Zoo WPS Development Server</ows:Title>
+       <ows:Abstract>
+         Development version of ZooWPS. See http://www.zoo-project.org
+       </ows:Abstract>
+       <ows:Keywords>
+         <ows:Keyword>WPS</ows:Keyword>
+         <ows:Keyword>GIS</ows:Keyword>
+         <ows:Keyword>buffer</ows:Keyword>
+       </ows:Keywords>
+       <ows:ServiceType>WPS</ows:ServiceType>
+       <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
+       ...
+       
+Optionally Compile Individual Services
+**************************************
+
+An example could be the ``OGR base-vect-ops`` provider in the ``zoo-project\zoo-services\ogr\base-vect-ops`` directory.  
+
+1. Edit the makefile.vc located in that directory, and execute:
+
+   ::
+   
+     nmake /f makefile.vc
+     
+   Inside that same directory, the file ``cgi-env\ogr_service.zo`` should be created.
+   
+2. Copy all of the files inside ``zoo-services\ogr\base-vect-ops\cgi-env`` into your cgi-bin directory
+
+3. Test this service provider through the following URL:
+
+   http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Buffer&DataInputs=BufferDistance=1@datatype=interger;InputPolygon=Reference@xlink:href=http%3A%2F%2Fwww.zoo-project.org%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID%3Dstates.15
+   
+   The response displayed in your browser should contain:
+   
+   ::
+   
+     <wps:ProcessSucceeded>Service "Buffer" run successfully.</wps:ProcessSucceeded>
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/installation.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/installation.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/installation.txt	(revision 672)
@@ -0,0 +1,22 @@
+.. _kernel-installation:
+
+Installation
+============
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+This page provides documentation on how to compile then install the ZOO Kernel on Unix, Windows, and Mac OS X platforms.
+
+.. toctree::
+   :maxdepth: 2
+   
+   install-prerequisites
+   install-unix
+   install-opensuse
+   install-centos
+   install-debian
+   install-windows
+   install-mac
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/introduction.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/introduction.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/introduction.txt	(revision 672)
@@ -0,0 +1,52 @@
+.. _kernel-introduction:
+
+Introduction
+============
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+ZOO Kernel is the heart of the ZOO. It is a powerful server-side C Kernel which makes 
+it possible to manage and chain Web services, by loading dynamic libraries and handling 
+them as on-demand Web services. The ZOO Kernel is written in the C language, but supports 
+several common programming languages in order to connect to numerous libraries and models.
+
+Using ZOO Kernel as a Web Processing Platform
+---------------------------------------------
+
+ZOO Kernel works with Apache and can communicate with cartographic engines and Web mapping 
+clients. It simply adds the WPS support to your spatial data infrastructure and your 
+Web mapping application!
+
+.. note::
+   If you'd like some background on the WPS standard, head to: http://www.opengeospatial.org/standards/wps
+
+Supported Languages
+-------------------
+
+ZOO Kernel supports the following programming languages, and let's you use them to create 
+new ZOO Services from new or existing code:
+
+============ =================== ========================= ============
+**Language** **ServiceProvider** **DataStructure**         **Return**
+------------ ------------------- ------------------------- ------------
+C / C++      Shared Library      maps* M 	           integer
+Fortran      Shared Library      CHARACTER*(1024) M(10,30) integer
+Java 	     Class File 	 `HashMap`_ 	           integer
+Python 	     Module File 	 `dictionary`_ 	           integer
+PHP 	     Script File 	 `Array`_ 	           integer
+Perl 	     Script File 		                   integer
+JavaScript   Script file 	 `Object`_ or Array	   Array/Object 
+============ =================== ========================= ============
+
+.. _`HashMap`: http://download.oracle.com/javase/6/docs/api/java/util/HashMap.html
+.. _`dictionary`: http://docs.python.org/tutorial/datastructures.html#dictionaries
+.. _`Array`: http://php.net/manual/language.types.array.php
+.. _`Object`: http://www.json.org/
+
+ZOO Kernel is a WPS Espresso Machine
+------------------------------------
+
+.. image:: ../_static/images/zoo_kernel_scheme.png
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/mapserver.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/mapserver.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/mapserver.txt	(revision 672)
@@ -0,0 +1,264 @@
+.. _kernel-mapserver:
+    
+How To Use the Internal MapServer W*S support
+=============================================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$ 
+
+The key idea of the MapServer W*S support implementation is that it
+doesn't require to change a single line of the service source code to
+activate the automatic publication of your result as WMS/WFS or WCS
+ressource. You simply need to modify the ``zcfg`` file corresponding
+to your service to make it working.
+
+Here is an overview of the way to install the MapServer W*S support, the
+configuration required and the internal mechanisms. 
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+How to make it working ?
+------------------------
+
+Requirement
+**************
+
+   * last ZOO-Kernel trunk version
+   * MapServer version >= 6.0.1
+
+Installation steps
+********************
+
+First download lastest zoo-kernel directory available on the svn, do that from the directory of your previous checkout (so where zoo-api, zoo-services and zoo-kernel directories are available), we will use ``<PREV_SVN_CO>`` here for this directory:
+
+.. code-block:: guess
+
+    cd <PREV_SVN_CO>
+    svn checkout http://svn.zoo-project.org/svn/trunk/zoo-kernel zoo-kernel-ms
+
+Uncompress the MapServer archive (ie. ``mapserver-6.0.1.tar.bz2``) into ``/tmp/zoo-ms-src``, then compile MapServer using the following command:
+
+.. code-block:: guess
+
+     cd /tmp/zoo-ms-src/mapserver-6.0.1
+     ./configure --with-ogr=/usr/bin/gdal-config --with-gdal=/usr/bin/gdal-config \
+                    --with-proj --with-curl --with-sos --with-wfsclient --with-wmsclient \
+                    --with-wcs --with-wfs --with-postgis --with-kml=yes --with-geos \
+                    --with-xml --with-xslt --with-threads --with-cairo
+     make
+     cp mapserv /usr/lib/cgi-bin
+
+Autotools was updated to add the ``--with-mapserver`` configure option. From your ZOO-Project SVN trunk directory, compile the ZOO-Kernel using the following command:
+
+.. code-block:: guess
+
+     cd zoo-kernel-ms
+     autoconf
+     ./configure --with-python --with-mapserver=/tmp/zoo-ms-src/mapserver-6.0.1
+     make
+     cp zoo_loader.cgi /usr/lib/cgi-bin
+
+Configuration steps
+*************************
+
+Main configuration file
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following content to your ``/usr/lib/cgi-bin/main.cfg`` file
+ in the ``[main]`` section:
+
+.. code-block:: guess
+
+      dataPath = /var/www/temp/
+      mapserverAddress=http://localhost/cgi-bin/mapserv
+
+The ``dataPath`` directory should exists and be writable by apache user. In this directory, a ``symbols.sym`` file have to be present, containing the following:
+
+.. code-block:: guess
+
+      SYMBOLSET
+      SYMBOL
+        NAME "circle"
+        TYPE ellipse
+        FILLED true
+        POINTS
+          1 1
+        END
+      END
+      END
+
+Only one symbol definition is required with any name, used for WMS service output.
+
+Now, your ZOO-Kernel get the MapServer support ready to be used. Note that if you don't add the ``mapserverAddress`` then it imply the ZOO-Kernel will segfault (checking ``NULL`` value should correct this behavior).
+
+Here you can optionally add a ``msOgcVersion`` parameter to specify which version of the OGC WebService you want to use for each services. For example, if you want to force to version 1.0.0, you can set the following in the ``[main]`` section of your ``main.cfg`` file:
+
+.. code-block:: guess
+
+     msOgcVersion=1.0.0
+
+Service configuration file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To activate MapServer WebServices output for a service, you have to add a specific parameter in the ``<Default>`` or ``<Supported>`` block: ``useMapserver``. This can take the value true or should not appear. If true, it means that the output result is an OGR / GDAL compatible datasource and you want it to be outputted as an OGC web server instance (WMS/WFS/WCS).
+
+You get an optional parameter, to use a custom MapServer style block (used for vector datasource only): msStyle. For example:
+
+.. code-block:: guess
+
+     msStyle = STYLE COLOR 125 0 105 OUTLINECOLOR 0 0 0 WIDTH 3 END
+
+You get the same optional parameter ``msOgcVersion`` as for the ``main.cfg``. This will specify that this is the specific protocol version the service want to use (so you may set also locally to service rather than globally).
+
+When you add useMapserver option to an output ``<Default>`` or ``<Supported>`` block, then you have to know what are the sensible mimeType:
+
+   * text/xml: will imply that the output data will be accessible through a WFS GetFeature request (default protocol version 1.1.0)
+   * image/tiff: will imply that the output data will be accessible through a WCS GetCoverage request (default protocol version 2.0.0)
+   * any other mimeType coupled with useMapserver option: will imply that the output data will be accessible trhough a WMS GetMap request (you have to limit yourself to what your MapServer installation support, GetCapabilities? request give information of supported output mimeType) (default protocol version 1.3.0) 
+
+How does it work ?
+---------------------
+
+Whatever your service return as default output ``mimeType``, this one will be used when one output including the ``useMapserver`` option was found.
+
+So if you get the following ``<Default>`` and ``<Supported>`` blocks in the ZOO Configuration File of your service:
+
+.. code-block:: guess
+
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = image/png
+     useMapserver = true
+    </Supported>
+
+It means that per default, your service return GML 3.1 Feature. When the client request for ``mimeType=image/png``, then the ZOO-Kernel will detect that this ``mimeType`` get the ``useMapServer`` option set to true so it will:
+
+    1) execute the service using the ``<Default>`` block definition (this should be understandable by GDAL/OGR)
+
+    2) store the result of the service on disk (in the ``[main]`` > ``dataPath`` directory)
+
+    3) write a Mapfile (in the ``[main]`` > ``dataPath`` directory) using the MapServer C-API to setup both WMS and WFS services.
+
+.. Note:: even if you don't ask for this, the resulting Mapfile includes both configuration for WMS and WFS in case of Vector datasource.
+
+If your service output a raster file, then the behavior is quite the same except that the ZOO-Kernel will setup both WMS and WCS services for the result of the service. Here you cannot define your own style. Nevertheless, when one band raster is returned then the ZOO-Kernel can use its own default style definitions to classify the raster using equivalent intervals (you can easily see that in the outputed Mapfile), this classification is specific to WMS protocol. You should add a ``msClassify`` parameter and set it to ``true`` in your output ComplexData ``<Default>`` or ``<Supported>`` node to activate this classification.
+Special note for client implementers
+
+Note that depending on the request, the ZOO-Kernel can return a location header.
+
+Differente request types:
+
+    * ResponseDocument=XXXX@asReference=true - in this case, the Kernel will return the GetMap/GetFeature/GetCoverage request in KVP in the href of the result.
+    * ResponseDocument=XXXX@asReference=false - in this case, the Kernel will return the result he get using the GetMap/GetFeature/GetCoverage request in KVP used for the href in previous case.
+    * RawDataOutput=XXXX@asReference=true/false - in this case, the Kernel will return the GetMap/GetFeature/GetCoverage request in KVP in the specific location header, which imply that the browser should follow and request MapServer directly. 
+
+Simple sample use cases
+-----------------------
+
+Consider the existing BufferPy service from zoo-services/ogr-base-vect-ops-py. Set the following content to your local BufferPy.zcfg file in the Result output definition, then copy it to /usr/lib/cgi-bin/:
+
+.. code-block:: guess
+
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     useMapserver = true
+    </Default>
+    <Supported>
+     mimeType = image/png
+     useMapserver = true
+     asReference = true
+     msStyle = STYLE COLOR 125 0 105 OUTLINECOLOR 0 0 0 WIDTH 3 END
+    </Supported>
+    <Supported>
+     mimeType = image/tif
+     useMapserver = true
+     asReference = true
+     msStyle = STYLE COLOR 125 0 105 OUTLINECOLOR 0 0 0 WIDTH 3 END
+    </Supported>
+    <Supported>
+     mimeType = application/vnd.google-earth.kmz
+     useMapserver = true
+     asReference = true
+     msStyle = STYLE COLOR 125 0 105 OUTLINECOLOR 0 0 0 WIDTH 3 END
+    </Supported>
+
+This modifications make your service ready to return result as WMS GetMap or WFS GetFeature requests. Note that some bug occurs locally using the application/vnd.google-earth.kmz output.
+Raster
+
+Using the following simple service code we get a service capable to output any kind of internet files (useful for testing this functionality):
+
+.. code-block:: guess
+
+    import zoo
+    def HelloPy(conf,inputs,outputs):
+            outputs["Result"]["value"]=inputs["a"]["value"]
+            return zoo.SERVICE_SUCCEEDED
+
+Define the ``[Result]`` output in your ``HelloPy.zcfg`` file with the following ComplexData block content:
+
+.. code-block:: guess
+
+    <Default>
+     mimeType = image/png
+     useMapServer = true
+    </Default>
+    <Supported>
+     mimeType = image/tiff
+     useMapServer = true
+    </Supported>
+    <Supported>
+     mimeType = text/xml
+     useMapServer = true
+    </Supported>
+
+It means that the default output ``mimeType`` is ``image/png``, so a WMS GetMap request will be returned, or the resulting ``image/tiff`` will be returned as WCS GetCoverage request.
+
+With this simple service you can test the new capabilities to output result as WebServices for each mimeTypes. Note, that you'll probably get wrong ``mimeType``, as the default was set to ``image/png``.
+
+There is a support for Zipped ShapeFile but I doubt it is really
+useful. Anyway, as it is present you can test it easily by passing a
+zip file in ``xlink:href`` for the ``a`` value of the ``HelloPy``
+service.
+
+Testings
+***********
+
+Using the simple ``HelloPy`` service code, you can use the following urls, note it supposes that you get an available http://localhost/data/data.zip file containing a ShapeFile and a http://localhost/data/demo.tif:
+
+Test 1: Accessing a remote Zipped Shapefile as WFS GetFeatures Request
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: guess
+
+     http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=HelloPy&DataInputs=a=Reference@xlink:href=http://localhost/data/data.zip&ResponseDocument=Result@asReference=true@mimetype=text/xml
+
+Test 2: Accessing a remote Zipped Shapefile as WMS GetMap Request
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: guess
+
+     http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=HelloPy&DataInputs=a=Reference@xlink:href=http://localhost/data/data.zip&ResponseDocument=Result@asReference=true@mimetype=image/png
+
+Test 3: Accessing a remote tiff as WMS GetMap Request:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: guess
+
+     http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=HelloPy&DataInputs=a=Reference@xlink:href=http://localhost/data/data.tiff&ResponseDocument=Result@asReference=true@mimetype=image/png
+
+Test 4: Accessing a remote tiff as WCS GetMap Request:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: guess
+
+     http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=HelloPy&DataInputs=a=Reference@xlink:href=http://localhost/data/data.tiff&ResponseDocument=Result@asReference=true@mimetype=image/tiff
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/orfeotoolbox.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/orfeotoolbox.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/orfeotoolbox.txt	(revision 672)
@@ -0,0 +1,121 @@
+.. _kernel-orfeotoolbox:
+    
+How To Use the Orfeo Toolbox support
+=============================================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$ 
+
+The key idea of the ZOO `Orfeo Toolbox <http://orfeo-toolbox.org/otb/>`_  support implementation is to take advantage of the `OTB Applications <http://orfeo-toolbox.org/otb/otb-applications.html>`_ by using them directly as ZOO WPS Services, without any modifications.  
+
+Here is an overview of the installation procedure and the required configuration to activate the OTB support in ZOO-Project. 
+
+.. Note:: These installation steps were successfully tested on Ubuntu 14.4 LTS 
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+How to make it working ?
+------------------------
+
+Requirements
+**************
+
+   * latest `ZOO-Kernel <http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-kernel>`_ trunk version
+   * Orfeo Toolbox (`OTB 4.2.1 <http://orfeo-toolbox.org/otb/>`_ )
+   * Insight Segmentation and Registration Toolkit  (`ITK-4.7 <http://itk.org/ITK/resources/software.html/>`_ )
+
+Installation steps
+********************
+
+.. Note:: For OTB and ITK, the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS must first be set to ``-fPIC``
+
+Download lastest ZOO-Kernel code from SVN.
+
+.. code-block:: guess
+
+    svn checkout http://svn.zoo-project.org/svn/trunk/zoo-kernel zoo-kernel
+
+Then compile ZOO-Kernel using the needed configuration options as shown bellow:
+
+.. code-block:: guess
+
+     cd zoo-kernel
+     autoconf
+     ./configure  --with-otb=/usr/local --with-itk=/usr/local --with-itk-version=4.7 
+     make
+     cp zoo_loader.cgi /usr/lib/cgi-bin
+
+Configuration steps
+*************************
+
+Main configuration file
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following content to your ``/usr/lib/cgi-bin/main.cfg`` file 
+in the ``[env]`` section:
+
+.. code-block:: guess
+
+       ITK_AUTOLOAD_PATH=/usr/local/lib/otb/applications
+
+Services configuration file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The build of the `otb2zcfg  <http://zoo-project.org/trac/browser/trunk/thirds/otb2zcfg>`_ utility is required to activate the available OTB Applications as WPS services. This can be done using the following command: 
+
+.. code-block:: guess
+	
+	 mkdir build
+	 cd build
+	 ccmake ..
+	 make
+	
+Run the following command to generate all the needed zcfg files for the available OTB Application:
+
+.. code-block:: guess
+	
+	 mkdir zcfgs
+	 cd zcfgs
+	 export ITK_AUTOLOAD_PATH=/your/path/to/otb/applications
+	 ../build/otb2zcfg
+         mkdir /location/to/your/cgi-bin/OTB
+	 cp *zcfg /location/to/your/cgi-bin/OTB
+	
+.. warning 
+
+     The ITK_AUTOLOAD_PATH environment variable is required in the [env] section of your main.cfg.
+
+Test the ZOO OTB support
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Once done, OTB Applications should be listed as available WPS Services when runing a GetCapabilities request
+
+.. code-block:: guess 
+
+        http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS 
+
+Each OTB Service can then be described individually using the DescribeProcess request, as for example:
+
+.. code-block:: guess
+
+   http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=OTB.BandMath
+
+And executed according to your needs, as for the following example executing OTB.BandMath with the OTB sample data as input
+
+.. code-block:: guess
+
+   http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=OTB.BandMath&DataInputs=il=Reference@xlink:href=http://hg.orfeo-toolbox.org/OTB-Data/raw-file/ca154074b282/Examples/verySmallFSATSW.tif;il=Reference@xlink:href=http://hg.orfeo-toolbox.org/OTB-Data/raw-file/ca154074b282/Examples/verySmallFSATSW_nir.tif;out=float;exp=im1b3*cos%28im1b1%29,im1b2*cos%28im1b1%29,im1b1*cos%28im1b1%29&RawDataOutput=out@mimeType=image/png
+
+When executing OTB applications as WPS Services, it is also possible to check the OTB process status, using the usual ZOO GetStatus request.
+
+
+
+    
+
+
+
+
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/kernel/sagagis.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/kernel/sagagis.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/kernel/sagagis.txt	(revision 672)
@@ -0,0 +1,91 @@
+.. _kernel-sagagis:
+    
+How To Use the SAGA-GIS support
+=============================================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$ 
+
+The key idea of the ZOO `SAGA GIS <http://saga-gis.org/>`_  support implementation is to take advantage of the `SAGA-GIS Modules <http://www.saga-gis.org/saga_module_doc/2.1.4/index.html>`_ by using them directly as ZOO-Services, without any modifications.  
+
+Here is an overview of the installation procedure and the required configuration to activate the SAGA-GIS support in ZOO-Project. 
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+How to make it working ?
+------------------------
+
+Requirements
+**************
+
+   * latest `ZOO-Kernel <http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-kernel>`_ trunk version
+   * SAGA-GIS (`SAGA-GIS 2.1.4 <http://saga-gis.org/>`_ )
+   * libLAS-1.2  (`LibLAS-1.2 <https://github.com/libLAS/libLAS-1.2>`_ )
+
+Installation steps
+********************
+
+Download lastest ZOO-Kernel code from SVN.
+
+.. code-block:: guess
+
+    svn checkout http://svn.zoo-project.org/svn/trunk/zoo-kernel zoo-kernel
+
+Then compile ZOO-Kernel using the needed configuration options as shown bellow:
+
+.. code-block:: guess
+
+     cd zoo-kernel
+     autoconf
+     ./configure  --with-saga=/usr/local/
+     make
+     cp zoo_loader.cgi /usr/lib/cgi-bin
+
+Configuration steps
+*************************
+
+Services configuration file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Building the `saga2zcfg  <http://zoo-project.org/trac/browser/trunk/thirds/otb2zcfg>`_ utility is required to activate the available SAGA-GIS Modules as WPS Services. This can be done using the following command: 
+
+.. code-block:: guess
+	
+	cd thirds/saga2zcfg
+	 make
+	
+Run the following command to generate all the needed zcfg files for the available SAGA-GIS Modules:
+
+.. code-block:: guess
+	
+	 mkdir zcfgs
+	 cd zcfgs
+	 ../saga2zcfg
+         mkdir /location/to/your/cgi-bin/SAGA
+	 cp *zcfg /location/to/your/cgi-bin/SAGA
+	
+Test the ZOO SAGA support
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Once done, SAGA-GIS Modules should be listed as available WPS Services when runing a GetCapabilities request
+
+.. code-block:: guess 
+
+        http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS 
+
+Each SAGA-GIS Service can then be described individually using the DescribeProcess request, as for example:
+
+.. code-block:: guess
+
+   http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=SAGA.garden_fractals.1
+
+And executed according to your needs, as for the following example
+executing SAGA.garden_fractals.1 with no optional parameter
+
+.. code-block:: guess
+
+   http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=SAGA.garden_fractals.1&DataInputs=&ResponseDocument=RESULT@mimeType=application/json@asReference=true
+
+When executing SAGA-GIS Modules as WPS Services, it is also possible to check its ongoing status, using the usual asynchronous Execute requests and polling the ZOO GetStatus request.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/make.bat
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/make.bat	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/make.bat	(revision 672)
@@ -0,0 +1,170 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ZOOProject.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ZOOProject.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/debug.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/debug.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/debug.txt	(revision 672)
@@ -0,0 +1,97 @@
+.. _services-debug:
+
+How To Debug ZOO Services
+=========================
+
+:Authors: Luca Delucchi
+:Last Updated: $Date$
+
+There are different ways to debug your services, the most used solutions are via web
+or via command line.
+
+Web
+----
+
+Using the web request you can see any problem in the log file of Apache.
+
+On Unix system the log file is usually in ``/var/log/apache2`` and the relevant file
+is ``error_log``. A simple way to read the file is to use the ``tail`` command,
+it permits to see the update of the file for each request ::
+
+  tail -f /var/log/apache2/error_log
+
+If the log is not clear enough you can add some more debug information to your code. You have to write
+to standard error.
+
+Python
+********
+Using Python, you can for example do this
+
+.. code-block:: python
+
+  import sys
+  
+  #add this line when you want see an own message
+  sys.stderr.write("My message")
+
+.. _web_javascript:
+
+Javascript
+************
+
+You can user ``alert`` to print a string to standard error:
+
+.. code-block:: javascript
+
+  // add this line when you want see an own message
+  alert('My message')
+  // you can debug value of inputs, outputs or conf
+  alert(inputs["S"]["value"])
+
+.. note:: If you try to pass an object it will only return ``[object Object]``
+
+Command line
+--------------
+
+It is possible to use the ZOO kernel ``zoo_loader.cgi`` also from command line.
+This is really useful to debug in a deeper way your service:
+
+.. code-block:: bash
+
+  # in order to use it you have to copy test_service.py and HelloPy.zcfg from
+  # the example services
+  ./zoo_loader.cgi "service=wps&version=1.0.0&request=execute&identifier=HelloPy&datainputs=a=your name&responsedocument=Result"
+
+Working this way you can use the standard debug system of the actual programming language used
+to develop your service.
+
+GDB
+*****
+From command line you can use also the command line tool `GDB <http://www.gnu.org/software/gdb/>`_
+to debug ``zoo_loader.cgi``, you have to run:
+
+.. code-block:: bash
+
+  # launch zoo_loader.cgi from gdb
+  gdb zoo_loader.cgi
+  # now run your request
+  run "service=wps&version=1.0.0&request=execute&identifier=HelloPy&datainputs=a=your name&responsedocument=Result"
+
+At this point you can ask help at the `ZOO mailing list <http://lists.osgeo.org/cgi-bin/mailman/listinfo/zoo-discuss>`_
+copying the result of the command.
+
+Python
+**********
+For Python, you can use ``pdb``, more info at http://docs.python.org/2/library/pdb.html
+
+.. code-block:: python
+
+  import pdb
+  
+  # add this line when you want investigate your code in more detail
+  pdb.set_trace()
+
+Javascript
+************
+
+You can use ``alert`` also to print in the console, more info in the :ref:`web_javascript` web section
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/examples.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/examples.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/examples.txt	(revision 672)
@@ -0,0 +1,45 @@
+.. _services-examples:
+
+Service Examples
+================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+ZOO Services are quite easy to create once you have installed the ZOO Kernel and have 
+chosen code (in the language of your choice) to turn into a ZOO service. Here are some 
+HelloWorlds with links to their corresponding ``.zcfg`` files.
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+GDAL ZOO Service
+----------------
+
+The GDAL ZOO Service is based on  GDAL source code and copyright. This ZOO Service 
+aims to provide some basic raster processing operations to your ZOO Kernel installation. 
+Learn more and read documentation on the official `GDAL website <http://www.gdal.org/>`__.
+
+Implemented functions
+*********************
+
+Gdal_Grid
+    creates regular grid from the scattered data
+
+
+Gdal_Translate
+    converts raster data between different formats
+
+
+OGR ZOO Service
+---------------
+
+The OGR ZOO Service is based on  OGR source code and copyright. This ZOO Service aims 
+to provide some basic vector spatial operations to your ZOO Kernel installation. 
+Learn more and read documentation on the official `OGR website <http://www.gdal.org/ogr/index.html>`__.
+
+Implemented functions
+*********************
+
+Base_Vect_Ops
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/howtos.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/howtos.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/howtos.txt	(revision 672)
@@ -0,0 +1,341 @@
+.. _services-howtos:
+
+How To Setup ZOO Services
+=========================
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna, Luca Delucchi
+:Last Updated: $Date$
+
+ZOO Services are quite easy to create once you have installed the ZOO Kernel and have 
+chosen code (in the language of your choice) to turn into a ZOO service. Here are some 
+HelloWorlds in Python, PHP, Java  and JavaScript with links to their corresponding 
+``.zcfg`` files.
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+Common informations
+----------------------
+
+A ZOO-Service is a couple composed of a ZCFG file and a
+ServiceProvider. This last depend of the programming language but
+should expose at least one function corresponding to the Service. This
+function take three arguments: the main configuration, inputs and
+outputs and return an integer:
+* 3 if the process run sucessfully
+* 4 in case any error occur. In such a case, programmer may add
+detailler message map
+
+Data structures for those arguments depend on the programming
+-UMRlanguage and is detailled below.
+
+.. Note:: The service has to **return 3 if the process run successfully instead it 
+	  return 4** if the process end with an error.
+
+Python
+------
+
+You'll find here information needed to deploy your own Python Services Provider.
+
+Python ZCFG requirements
+************************
+
+.. Note:: For each Service provided by your ZOO Python Services Provider, the ZCFG File 
+          must be named the same as the Python module function name (also the case of
+          characters is important).
+
+The ZCFG file should contain the following :
+
+
+serviceType
+    Python 
+serviceProvider
+    The name of the Python module to use as a ZOO Service Provider. For instance, if your
+    script, located in the same directory as your ZOO Kernel, was named ``my_module.py`` then
+    you should use ``my_module`` (the Python module name) for the serviceProvider value in ZCFG file.
+
+Python Data Structure used
+**************************
+The three parameters of the function are passed to the Python module as dictionaries.
+
+Following you'll find an example for each parameters
+
+Main configuration
+^^^^^^^^^^^^^^^^^^^^^
+Main configuration contains several informations, some of them are really useful to develop your service.
+Following an example ::
+
+  {
+  'main': {'lang': 'en-UK',
+	   'language': 'en-US',
+	   'encoding': 'utf-8',
+	   'dataPath': '/var/www/tmp',
+	   'tmpPath': '/var/www/tmp',
+	   'version': '1.0.0',
+	   'mapserverAddress': 'http://localhost/cgi-bin/mapserv',
+	   'isSoap': 'false',
+	   'tmpUrl': 'http://localhost/tmp/',
+	   'serverAddress': 'http://localhost/zoo'
+	  },
+  'identification': {'keywords': 'WPS,GIS',
+		     'abstract': 'WPS services for testing ZOO',
+		     'fees': 'None',
+		     'accessConstraints': 'none',
+		     'title': 'testing services'
+		    },
+  'lenv': {'status': '0',
+	   'soap': 'false',
+	   'cwd': '/usr/lib/cgi-bin',
+	   'sid': '24709'
+	  },
+  'env': {'DISPLAY': 'localhost:0'},
+  'provider': {'addressCountry': 'it',
+	       'positionName': 'Developer',
+	       'providerName': 'Name of provider',
+	       'addressAdministrativeArea': 'False',
+	       'phoneVoice': 'False',
+	       'addressCity': 'City',
+	       'providerSite': 'http://www.your.site',
+	       'addressPostalCode': '38122',
+	       'role': 'Developer',
+	       'addressDeliveryPoint': 'False',
+	       'phoneFacsimile': 'False', 
+	       'addressElectronicMailAddress': 'your@email.com',
+	       'individualName': 'Your Name'
+	      }
+  }
+
+Inputs
+^^^^^^^^^^^^
+The inputs are somethings like this ::
+
+  {
+  'variable_name': {'minOccurs': '1',
+		    'DataType': 'string',
+		    'value': 'this_is_the_value',
+		    'maxOccurs': '1',
+		    'inRequest': 'true'
+		   }
+  }
+
+The access to the value you have to require for the ``value`` parameter, something like this ::
+
+  yourVariable = inputs['variable_name']['value']
+
+Outputs
+^^^^^^^^^^^^^
+The outputs data as a structure really similar to the inputs one ::
+
+  {
+  'result': {'DataType': 'string',
+	     'inRequest': 'true',
+	    }
+  }
+
+There is no ``'value'`` parameter before you assign it ::
+
+  inputs['result']['value'] = yourOutputDataVariable
+
+The return statement has to be an integer: corresponding to the service status code.
+
+To add a message for the wrong result you can add the massage to ``conf["lenv"]["message"]``,
+for example:
+
+.. code-block:: python
+
+  conf["lenv"]["message"] = 'Your module return an error'
+
+Sample ZOO Python Services Provider
+***********************************
+
+The following code represents a simple ZOO Python Services Provider which provides only one 
+Service, the HelloPy one.
+
+.. code-block:: python
+
+  import zoo
+  import sys
+  def HelloPy(conf,inputs,outputs):
+     outputs["Result"]["value"]="Hello "+inputs["a"]["value"]+" from Python World !"
+     return zoo.SERVICE_SUCCEEDED
+
+PHP
+---
+
+ZOO-API
+*******
+
+The ZOO-API for the PHP language is automatically available from your
+service code. Tthe following functions are defined in the ZOO-API:
+
+int zoo_SERVICE_SUCCEEDED()
+    return the value of SERVICE_SUCCEEDED
+int zoo_SERVICE_FAILED()
+    return the value of SERVICE_FAILED
+string zoo_Translate(string a)
+    return the translated string (using the "zoo-service" `textdomain
+    <http://www.gnu.org/software/libc/manual/html_node/Locating-gettext-catalog.html#index-textdomain>`__)
+
+void zoo_UpdateStatus(Array conf,string message,int pourcent)
+    update the status of the running service
+
+PHP ZCFG requirements
+**********************************
+
+The ZCFG file should contain the following :
+
+serviceType
+    PHP 
+serviceProvider
+    The name of the php script (ie. service.php) to use as a ZOO Service Provider.
+
+PHP Data Structure used
+********************************
+
+The three parameters are passed to the PHP function as 
+`Arrays <php.net/manual/language.types.array.php>`__.
+
+Sample ZOO PHP Services Provider
+******************************************
+
+.. code-block:: php
+
+  <?
+  function HelloPHP(&$main_conf,&$inputs,&$outputs){
+     $tmp="Hello ".$inputs[S][value]." from PHP world !";
+     $outputs["Result"]["value"]=zoo_Translate($tmp);
+     return zoo_SERVICE_SUCCEEDED();
+  }
+  ?>
+
+Java
+----
+
+Specifically for the Java support, you may add the following two
+sections to your ``main.cfg`` file:
+
+:[javaxx]:
+   This section is used to pass -XX:* parameters to the JVM  created by the
+   ZOO-Kernel to handle your ZOO-Service (see `ref. 1
+   <http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#BehavioralOptions>`__
+   or `ref. 2
+   <http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning>`__
+   for sample available). 
+   For each map ``a = b`` available in the ``[javaxx]`` section, the
+   option ``-XX:a=b`` will be passed to the JVM. In case of a map ``a =
+   minus`` (respectively ``a=plus``) then the option ``-XX:-a``
+   (respectivelly ``-XX:+a``) will be passed.
+:[javax]:
+   The section is used to pass -X* options to the JVM (see
+   `ref. <http://docs.oracle.com/cd/E22289_01/html/821-1274/configuring-the-default-jvm-and-java-arguments.html>`__). For
+   each map ``a = b`` available in the ``[javax]`` section, the option
+   ``-Xab`` will be passed to the JVM (ie. set ``mx=2G`` to pass
+   ``-Xmx2G``).
+
+ZOO-API
+*******
+
+Before you build your first ZOO-Service implemented in Java, it is
+recommended that you first build the ZOO class of the Java ZOO-API.
+
+.. Note:: You should build ZOO-Kernel prior to follow this instructions.
+
+To build the ZOO.class of the ZOO-API for Java, use the following
+command:
+
+.. code-block:: guess
+
+  cd zoo-api/java
+  make
+  cp ZOO.class libZOO.so /usr/lib/cgi-bin
+
+.. Note:: running the previous commands will require that both
+          ``javac`` and ``javah`` are in your PATH.
+
+Java ZCFG requirements
+**********************************
+
+.. Note:: For each Service provided by your ZOO Java Services Provider
+          (your corresponding Java class), the ZCFG File should have
+          the name of the Java public method corresponding to the
+          service (case-sensitive).
+
+The ZCFG file should contain the following :
+
+serviceType
+    Java 
+serviceProvider
+    The name of the Java class to use as a ZOO Service Provider. For instance, if your
+    java class, located in the same directory as your ZOO-Kernel, was
+    named ``HelloJava.class`` then you should use ``HelloJava``.
+
+Java Data Structure used
+********************************
+
+The three parameters are passed to the Java function as 
+`java.util.HashMap <http://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html>`__.
+
+Sample ZOO Java Services Provider
+******************************************
+
+.. code-block:: java
+
+  import java.util.*;
+  public class HelloJava {
+    public static int HelloWorldJava(HashMap conf,HashMap inputs, HashMap outputs) {
+       HashMap hm1 = new HashMap();
+       hm1.put("dataType","string");
+       HashMap tmp=(HashMap)(inputs.get("S"));
+       java.lang.String v=tmp.get("value").toString();
+       hm1.put("value","Hello "+v+" from JAVA WOrld !");
+       outputs.put("Result",hm1);
+       System.err.println("Hello from JAVA WOrld !");
+       return ZOO.SERVICE_SUCCEEDED;
+    }
+  }
+
+Javascript
+----------
+
+ZOO API
+*********
+
+If you need to use :ref:`ZOO API <api>` in your service, you have first to copy ``zoo-api.js``
+and ``zoo-proj4js.js`` where your services are located (for example in Unix system probably in
+``/usr/lib/cgi-bin/``
+
+Javascript ZCFG requirements
+**********************************
+
+.. Note:: For each Service provided by your ZOO Javascript Services Provider, the ZCFG File 
+          must be named the same as the Javascript function name (also the case of
+          characters is important).
+
+The ZCFG file should contain the following :
+
+serviceType
+    JS 
+serviceProvider
+    The name of the JavaScript file to use as a ZOO Service Provider. For instance, if your
+    script, located in the same directory as your ZOO Kernel, was named ``my_module.js`` then
+    you should use ``my_module.js``.
+
+
+Javascript Data Structure used
+********************************
+
+The three parameters of the function are passed to the JavaScript function as Object.
+
+Sample ZOO Javascript Services Provider
+******************************************
+
+.. code-block:: javascript
+
+  function hellojs(conf,inputs,outputs){
+     outputs=new Array();
+     outputs={};
+     outputs["result"]["value"]="Hello "+inputs["S"]["value"]+" from JS World !";
+     return Array(3,outputs);
+  }
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/index.txt	(revision 672)
@@ -0,0 +1,17 @@
+.. _services:
+
+ZOO Services Documentation
+==========================
+
+The following sections will assist you with ZOO Services:
+
+.. toctree::
+   :maxdepth: 2
+   
+   introduction
+   zcfg-reference
+   process-profiles
+   howtos
+   status
+   debug
+   examples
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/introduction.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/introduction.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/introduction.txt	(revision 672)
@@ -0,0 +1,30 @@
+.. _services-intro:
+
+Introduction
+============
+
+ZOO Services are example Web services which work with the ZOO :ref:`Kernel <kernel-introduction>`. 
+They are based on various existing Open Source libraries and tend to provide simple Web processing 
+functions such as GIS format conversion, GIS file reprojection, basic spatial operations, 
+basic raster operations...
+
+The available ZOO Services are under development and come without any warranty. They are based 
+on existing code and prove that the :ref:`ZOO Kernel <kernel-introduction>` works with many different 
+codes and languages (please have a look to the ZOO demos!). The ZOO Project team wants to encourage 
+people to use the ZOO Services as a functional basis for Web processing, but above all to provide a 
+source of inspiration to the community for creating new ZOO Services.
+
+What is a ZOO Service?
+----------------------
+
+A ZOO Service is a couple composed of:
+
+- The code you want to turn into a standardized Web service
+- A configuration file (.zcfg) which describes this Web service 
+
+Learn more on configuring ZOO services by reading the :ref:`.zcfg Reference <services-zcfg>`.
+
+Example ZOO Services
+--------------------
+
+See the ZOO Services :ref:`examples page <services-examples>`.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/process-profiles.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/process-profiles.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/process-profiles.txt	(revision 672)
@@ -0,0 +1,188 @@
+.. _process-profiles:
+    
+Process Profiles Registry
+=========================================  
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+Many times, services from the same ServicesProvider share inputs and
+outputs. In such a casse, defining the ZCFG files for each service
+from the same provider may lead to rewrite the same metadata
+informations in different files. 
+
+From `rev. 607 <http://www.zoo-project.org/trac/changeset/607>`__, the
+ZOO-Kernel is able to handle metadata inheritance, it create a
+Registry (before loading any other ZCFG files) containing a set of
+Process Profiles organized in levels depending on their position in
+the hierarchy:
+
+:Concept: the higher level in the hierarchy, concepts are basically
+   txt files containing an abstract description of a service,
+:Generic: a generic profile can make reference to concepts, it defines
+   inputs and outputs but nor the data format nor the maximum size
+   limitation,
+:Implementation: an implementation profile can inherit from a generic
+   profile and make reference to concepts, it contains all the
+   metadata informations about a service (see
+   `ref. <cfg-reference.html#main-metadata-information>`__).
+
+Both Generic Process Profiles and Process Implementation Profiles are
+created  from ZCFG files, stored in the registry sub-directories
+depending on their level: ``concept``, ``generic`` and
+``implementation``.
+
+To activate the registry, you have to add a ``registry`` key to the
+``[main]`` section of your ``main.cfg`` file, and set its value to the
+directory path used to store the profile ZCFG files.
+
+
+Generic Process Profile
+-----------------------
+
+A Generic Process Profile is a ZCFG file located in the ``generic``
+sub-directory, it defines `main metadata information
+<zcfg-reference.html#main-metadata-information>`__, inputs and outputs
+name, basic metadata and multiplicity. It can make reference to a
+concept by defining a ``concept`` key in the `main metadata
+information <zcfg-reference.html#main-metadata-information>`__ part.
+
+You can find below the `GO.zcfg` file, a typical Generic Process
+Profile for Generic Geographic Operation, taking one InputPolygon
+input parameter and returning a result named Result, it make reference
+to the ``GOC`` concept:
+
+.. code-block:: none
+   :linenos:
+   
+   [GO]
+    Title = Geographic Operation
+    Abstract = Geographic Operation on exactly one input, returning one output
+    concept = GOC
+    level = generic
+    statusSupported = true
+    storeSupported = true
+    <DataInputs>
+     [InputPolygon]
+      Title = the geographic data
+      Abstract = the geographic data to run geographipc operation
+      minOccurs = 1
+      maxOccurs = 1
+    </DataInputs>
+    <DataOutputs>
+     [Result]
+      Title = the resulting data
+      Abstract = the resulting data after processing the operation
+    </DataOutputs>  
+
+
+.. Note:: if you need to reference more than one concept, you should
+    separate their names with a comma (ie. concept = GO,GB),
+
+Process Implementation Profile
+------------------------------
+
+A Process Implementation Profile is similar to a `ZCFG file
+<zcfg-reference.html>`__ located in the `implementation`
+sub-directory, it defines (or inherit from its parent) all the
+properties of a `Generic Process Profile <#generic-process-profile>`__
+and specify `Data Format <zcfg-reference.html#type-of-data-nodes>`__
+for both inputs and outputs. It can make reference to a concept by
+defining a ``concept`` key in the `main metadata information
+<zcfg-reference.html#main-metadata-information>`__ part.
+
+You can find below the `VectorOperation.zcfg` file, a typical Process
+Implementation Profile for Vector Geographic Operation, it inherit
+from the `GP generic profile <#generic-process-profile>`__:
+
+.. code-block:: none
+   :linenos:
+   
+   [VectorOperation]
+    Title = Vector Geographic Operation
+    Abstract = Apply a Vector Geographic Operation on a features collection and return the resulting features collection
+    extend = GO
+    level = profile
+    <DataInputs>
+     [InputPolygon]
+      Title = the vector data
+      Abstract = the vector data to run geographic operation
+      <ComplexData>
+       <Default>
+        mimeType = text/xml
+        encoding = UTF-8
+        schema = http://fooa/gml/3.1.0/polygon.xsd
+       </Default>
+       <Supported>
+        mimeType = application/json
+        encoding = UTF-8
+        extension = js
+       </Supported>
+    </DataInputs>
+    <DataOutputs>
+     [Result]
+      Title = the resulting data
+      Abstract = the resulting geographic data after processing the operation
+      <ComplexData>
+       <Default>
+        mimeType = text/xml
+        encoding = UTF-8
+        schema = http://fooa/gml/3.1.0/polygon.xsd
+       </Default>
+       <Supported>
+        mimeType = application/json
+        encoding = UTF-8
+        extension = js
+       </Supported>
+      </ComplexData>
+    </DataOutputs>  
+
+
+ZCFG inheritance
+----------------------------------
+
+For the ZCFG files at the service level, you can inherit the metadata
+from a Process Implementation Profile available in the registry. As
+before, you simply need to add a ``extend`` key refering the ZCFG you
+want to inherit from and a ``level`` key taking the `ìmplementation``
+value to your main metadata informations.
+
+So, for example, the original `ConvexHull.zcfg
+<http://www.zoo-project.org/trac/browser/trunk/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/ConvexHull.zcfg?rev=491>`__
+may be rewritten as:
+
+.. code-block:: none
+   :linenos:
+   
+   [ConvexHull]
+    Title = Compute convex hull.
+    Abstract = Return a feature collection that represents the convex hull of each geometry from the input collection.
+    serviceProvider = ogr_service.zo
+    serviceType = C
+    extend = VectorOperation
+    level = implementation
+
+Now, suppose that your service is able to return the result in KML
+format, then you may write the following:
+
+.. code-block:: none
+   :linenos:
+   
+   [ConvexHull]
+    Title = Compute convex hull.
+    Abstract = Return a feature collection that represents the convex hull of each geometry from the input collection.
+    serviceProvider = ogr_service.zo
+    serviceType = C
+    extend = VectorOperation
+    level = implementation
+    <DataOutputs>
+     [Result]
+        <Supported>
+         mimeType = application/vnd.google-earth.kml+xml
+         encoding = utf-8
+        </Supported>
+    </DataOutputs>
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/status.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/status.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/status.txt	(revision 672)
@@ -0,0 +1,43 @@
+.. _services-status:
+
+How To Use ZOO Status Service
+===============================
+
+:Authors: Luca Delucchi
+:Last Updated: $Date$
+
+*ZOO Status Service* is a utility of ZOO-Project to return the
+completion percent of your service.
+
+Install ZOO Status Service
+-----------------------------
+
+To install the ``ZOO Status Service`` you have to move in 
+``/path/to/zoo/source/zoo-services/utils/status/`` and compile the source
+running the ``make`` command.
+If no errors are returned during compilation you can copy the content of ``cgi-env``
+to ``/usr/lib/cgi-bin/`` or where you have your ``zoo_loader.cgi`` working with this
+command (you need administration right):
+
+::
+
+   cp /path/to/zoo/source/zoo-services/utils/status/cgi-env/*{zcfg,zo,py} /usr/lib/cgi-bin
+
+With this command you copy the code to permit to ``ZOO Status Service`` and some
+example processes about how it works.
+
+Now you have to add these two lines to ``main.cfg`` :
+
+::
+
+  rewriteUrl=call
+  dataPath=/var/www/data
+
+Here you define the path where the service is able to find the xsl file, specified in the dataPath
+parameter. You also tell the ZOO Kernel that you want to use the `rewriteUrl <../kernel/install-debian.html#rewrite-rule-configuration>`_.
+
+The last operation is to copy the ``updateStatus.xsl`` to ``dataPath`` directory as follow:
+
+::
+
+   cp /path/to/zoo/source/zoo-services/utils/status/cgi-env/*{xsl} /var/www/data
Index: /branches/PublicaMundi_David_integration_01-devel/docs/services/zcfg-reference.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/services/zcfg-reference.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/services/zcfg-reference.txt	(revision 672)
@@ -0,0 +1,308 @@
+.. _services-zcfg:
+    
+ZCFG : the ZOO Service Configuration File
+=========================================  
+
+:Authors: Nicolas Bozon, Gérald Fenoy, Jeff McKenna
+:Last Updated: $Date$ 
+
+.. contents:: Table of Contents
+    :depth: 3
+    :backlinks: top
+
+The ZOO Service configuration file (.zcfg) describes the service and will be parsed by 
+the ZOO Kernel. We will describe here what such a file contains. 
+You can also take a look at the existing examples of ZCFG files in the ``cgi-env`` directory 
+of each services available in the `ZOO-Project SVN source tree <http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-services>`__.
+
+A ZOO Configuration file is divided into three distinct sections :
+
+1. Main Metadata information
+2. List of Inputs metadata information (optional since `rev. 469 <http://zoo-project.org/trac/changeset/469>`__)
+3. List of Outputs metadata information
+
+.. Note:: The ZOO Service Configuration File is case sensitive.
+
+Main Metadata Information
+-------------------------
+
+The fist part in a ZOO Configuration file contains the metadata information relative to the service. 
+Note that the "name of your service" between brackets on the first line has to be the exact same name 
+as the function you defined in your services provider code. In most cases, this name is also the name 
+of the ZCFG file without the "``.zcfg``" extension.
+
+You can see below a description of the main metadata information:
+
+.. code-block:: none
+   :linenos:
+
+   [Name of your service]
+   Title = Title of your service
+   Abstract = Description of your service
+   processVersion = Version number of your service
+   storeSupported = true/false
+   statusSupported = true/false
+   serviceType = the programming language used to implement the service (C/Fortran/Python/Java/PHP/Javascript)
+   serviceProvider = name of your services provider (shared library/Python Module/Java Class/PHP Script/JavaScript script)
+   <MetaData>
+     title = Metadata title of your service
+   </MetaData>
+
+.. Note:: you may add an ``extend`` key in case you use the `Process
+   Profile Registry <process-profiles.html>`__.
+
+List of Inputs
+--------------
+
+The list of inputs contains metadata information of each supported input, and they are grouped using a ``<DataInputs>`` node.
+
+Each input is defined as :
+
+-  a name (between brackets as for the name of the service before)
+- various medata properties (``Title``, ``Abstract``, ``minOccurs``, ``maxOccurs`` and, in case of ComplexData, the optional ``maximumMegabytes``)
+- a Type Of Data node (:ref:`description <typeDataNodes>`)
+
+A typical list of inputs (``<DataInputs>``) look like the following:
+
+.. code-block:: none
+   :linenos:
+   
+   <DataInputs>
+     [Name of the first input]
+       Title = Title of the first input
+       Abstract = Abstract describing the first input
+       minOccurs = Minimum occurence of the first input
+       maxOccurs = Maximum occurence of the first input
+       <Type Of Data Node />
+     [Name of the second input]
+       Title = Title of the second input
+       Abstract = Abstract describing the second input
+       minOccurs = Minimum occurence of the second input
+       maxOccurs = Maximum occurence of the second input
+       <Type Of Data Node />
+   </DataInputs>
+   
+.. Note:: you can add ``<MetaData>`` node as in the main metadata information.
+
+List of Outputs
+---------------
+
+The list of outputs is very similar to a list of inputs except it is specified as a ``<DataOutputs>`` node.
+
+A typical ``<DataOutputs>`` node looks like the following:
+
+.. code-block:: none
+   :linenos:
+   
+   <DataOutputs>
+     [Name of the output]
+       Title = Title of the output
+       Abstract = Description of the output
+       <Type Of Data Node />
+   </DataOutputs>
+
+.. _typeDataNodes:
+
+Type Of Data Nodes
+------------------
+
+In the beginning of this ZCFG introduction, we spoke about "Type Of Data Nodes" to describe the data type of inputs and outputs.
+
+You can define your data as:
+
+- :ref:`LiteralData <LiteralData>`
+- :ref:`BoundingBoxData <BoundingBoxData>`
+- :ref:`ComplexData <ComplexData>`
+
+Except for ``LiteralData``, each *Type Of Data* node must have at least one ``<Default>`` node. Even 
+if empty, it **has to be present**. So, something
+like the following should be present in your ZCFG file:
+
+.. code-block:: guess
+   :linenos:
+
+   <Default />
+
+Otherwise, ZOO-Kernel won't be able to parse your ZCFG correctly.
+
+.. _LiteralData:
+
+LiteralData node
+****************
+
+A ``<LiteralData>`` node contains:
+
+- one (optional) ``AllowedValues`` key containing all value allowed for this input
+- one (optional) ``range`` properties containing the range (``[``, ``]``)
+- one (optional) ``rangeMin`` (``rangeMax``) properties containing the minimum (maximum) value of this range
+- one (optional) ``rangeSpacing`` properties containing the regular distance or spacing between value in this range
+- one (optional) ``rangeClosure`` properties containing the closure type (``c``, ``o``, ``oc``, ``co``)
+- one ``<Default>`` node,
+- zero or more ``<Supported>`` nodes depending on the existence or the number of supported Units Of Measure (UOM), and 
+- a ``dataType`` property. The ``dataType`` property defines the type of literal data, such as a string, an interger and so on 
+  (consult `the complete list <http://www.w3.org/TR/xmlschema-2/#built-in-datatypes>`__ of supported data types). 
+
+``<Default>`` and ``<Supported>`` nodes can contain the ``uom`` property to define which UOM has to be used for 
+this input value.
+
+For input ``<LiteralData>`` nodes, you can add the ``value`` property to the ``<Default>`` node to define a default 
+value for this input. This means that, when your Service will be run, even if the input wasn't defined, this default 
+value will be set as the current value for this input.
+
+A typical ``<LiteralData>`` node, defining a ``float`` data type using meters or degrees for its UOM, looks like the 
+following:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = float
+     <Default>
+       uom = meters
+     </Default>
+     <Supported>
+       uom = feet
+     </Supported>
+   </LiteralData>
+
+
+A typical ``<LiteralData>`` node, defining a ``float`` data type which
+should take values contained in ``[0.0,100.0]``, looks like the following:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = float
+     rangeMin = 0.0
+     rangeMax = 100.0
+     rangeClosure = c
+     <Default />
+   </LiteralData>
+
+Or more simply:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = float
+     range = [0.0,100.0]
+     <Default />
+   </LiteralData>
+
+A typical ``<LiteralData>`` node, defining a ``string`` data type which
+support values ``hillshade``, ``slope``, ``aspect``, ``TRI``, ``TPI``
+and ``roughness``, looks like the following:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = string
+     AllowedValues = hillshade,slope,aspect,TRI,TPI,roughness
+     <Default />
+   </LiteralData>
+
+Properties ``AllowedValues`` and ``range*`` can be conbined with both ``<Default>`` and
+``<Supported>`` nodes in the same was as ``<LiteralData>`` node. For
+instance, the following is supported:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = int
+     <Default>
+       value = 11
+       AllowedValues = -10,-8,-7,-5,-1
+       rangeMin = 0
+       rangeMin = 100
+       rangeClosure = co
+     </Default>
+     <Supported>
+       rangeMin = 200
+       rangeMin = 600
+       rangeClosure = co
+     </Supported>
+     <Supported>
+       rangeMin = 750
+       rangeMin = 990
+       rangeClosure = co
+       rangeSpacing = 10
+     </Supported>
+   </LiteralData>
+
+.. _BoundingBoxData:
+
+BoundingBoxData node
+********************
+
+A ``<BoundingBoxData>`` node contains:
+
+- one ``<Default>`` node with a CRS property defining the default Coordinate Reference Systems (CRS), and 
+- one or more ``<Supported>`` nodes depending on the number of CRS your service supports (note that you can 
+  alternatively use a single ``<Supported>`` node with a comma-separated list of supported CRS).
+
+A typical ``<BoundingBoxData>`` node, for two supported CRS (`EPSG:4326 <http://www.epsg-registry.org/indicio/query?request=GetRepositoryItem&id=urn:ogc:def:crs:EPSG::4326>`__ 
+and `EPSG:3785 <http://www.epsg-registry.org/indicio/query?request=GetRepositoryItem&id=urn:ogc:def:crs:EPSG::3785>`__), 
+looks like the following:
+
+.. code-block:: guess
+   :linenos:
+   
+   <BoundingBoxData>
+     <Default>
+       CRS = urn:ogc:def:crs:EPSG:6.6:4326
+     </Default>
+     <Supported>
+       CRS = urn:ogc:def:crs:EPSG:6.6:4326
+     </Supported>
+     <Supported>
+       CRS = urn:ogc:def:crs:EPSG:6.6:3785
+     </Supported>
+   </BoundingBoxData>
+
+.. _ComplexData:
+
+ComplexData node
+****************
+
+A ComplexData node contains:
+
+- a ``<Default>`` node and 
+- one or more ``<Supported>`` nodes depending on the number of supported formats. A format is made up of this 
+  set of properties : ``mimeType``, ``encoding`` and optionaly ``schema``.
+
+For output ComplexData nodes, you can add the ``extension`` property to define what extension to use to name 
+the file when storing the result is required. Obviously, you'll have to add the ``extension`` property to each 
+supported format (for the ``<Default>`` and ``<Supported>`` nodes). 
+
+You can also add the ``asReference`` property to the ``<Default>`` node to define if the output should be 
+stored on server side per default. 
+
+.. Note:: the client can always modify this behavior by setting ``asReference`` attribute to ``true`` or ``false`` 
+          for this output in the request ``ResponseDocument`` parameter.
+
+You can see below a sample ComplexData node for default ``application/json`` and ``text/xml`` (encoded in UTF-8 
+or base64) mimeTypes support:
+
+.. code-block:: guess
+   :linenos:
+   
+   <ComplexData>
+     <Default>
+       mimeType = application/json
+       encoding = UTF-8
+     </Default>
+     <Supported>
+       mimeType = text/xml
+       encoding = base64
+       schema = http://fooa/gml/3.1.0/polygon.xsd
+     </Supported>
+     <Supported>
+       mimeType = text/xml
+       encoding = UTF-8
+       schema = http://fooa/gml/3.1.0/polygon.xsd
+     </Supported>
+   </ComplexData>
Index: /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/environment.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/environment.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/environment.txt	(revision 672)
@@ -0,0 +1,115 @@
+.. _environment:
+
+Using ZOO from an OSGeoLive virtual machine
+===========================================
+
+Development Environment Description
+-----------------------------------
+
+`OSGeoLive <http://live.osgeo.org/>`__ is a live DVD and virtual machine based on 
+`Xubuntu <http://www.xubuntu.org/>`__  that allows you to try a 
+wide variety of open source geospatial software without installing anything. It is 
+composed entirely of free software and include ZOO 1.0 this year, for testing purpose.
+
+As already said in introduction, an OSGeoLive virtual machine image disk has been 
+installed on your computer, allowing you to use ZOO Kernel in a development environment 
+directly. Using a virtual machine image disk seems to be the simplest way to use 
+ZOO Kernel and to develop ZOO Services locally, as we can ensure that everything 
+requested for compile C Services and run Python Services is available and ready to use. 
+Every ZOO related material and source code have been placed in */home/user/zoows* directory. 
+We will work inside it during this workshop. As the binary version of ZOO Kernel is 
+already compiled and stored in */home/user/zoows/sources/zoo-kernel*, you only have to 
+copy two important files inside the */usr/lib/cgi-bin directory*: *zoo_loader.cgi*
+and the *main.cfg* in order to make ZOO Kernel available, using the following commands:
+
+::
+
+  sudo cp ~/zoows/sources/zoo-kernel/zoo_loader.cgi /usr/lib/cgi-bin
+  sudo cp ~/zoows/sources/zoo-kernel/main.cfg /usr/lib/cgi-bin
+  
+Please note that we will talk about ZOO Kernel or zoo_loader.cgi script without any 
+distinction during this workshop.
+
+The *main.cfg* file contains metadata informations about the identification and provider 
+but also some important settings. The file is composed of various sections, namely *main*,  
+*identification* and *provider* per default. Obviously, you are free to add new sections 
+to the files if you need them for a specific Service. Nevertheless, you have to know 
+that the env section name is used in a specific way. It lets you define environment 
+variables that your Service requires during its runtime. For instance, if your Service 
+requires to access to a X server running on framebuffer, you can add *DISPLAY=:1* line in 
+your env section to take this specificity into account.
+
+Please have a look to this file. Three important parameters are commented below:
+
+serverAddress
+  The url to access to the ZOO Kernel
+
+tmpPath
+  The full path to store temporary files
+
+tmpUrl
+  The url path relative to serverAddress to access temporary directory.
+
+The values of the *main.cfg* file used from the running virtual machine are the following:
+
+::
+
+  serverAddress=http://localhost/zoo
+  tmpPath=/var/www/temp
+  tmpUrl=../temp/
+
+You could have noticed that the *tmpUrl* is a relative url from *serverAddress*, so it must 
+be a directory. Even if ZOO Kernel can be used with the full url of the zoo_loader.cgi 
+script, for  better readability and fully functional ZOO Kernel, you have to modify the 
+default Apache configuration in order to be able to use the http://localhost/zoo/ url 
+directly.
+
+First, please create a zoo directory in the existing */var/www* which is used by Apache as 
+the DirectoryIndex. Then, please edit the */etc/apache2/sites-available/default* configuration 
+file and add the following lines after the Directory block related to */var/www* directory :
+
+::
+
+  <Directory /var/www/zoo/>
+          Options Indexes FollowSymLinks MultiViews
+          AllowOverride All
+          Order allow,deny
+          allow from all
+  </Directory>
+  
+Now create a small *.htaccess* file in the */var/www/zoo* containing the following lines:
+
+::
+
+  RewriteEngine on
+  RewriteRule (.*)/(.*) /cgi-bin/zoo_loader.cgi?metapath=$1 [L,QSA]
+  RewriteRule (.*) /cgi-bin/zoo_loader.cgi [L,QSA]
+
+For this last file to be taken into account by Apache, you must activate the rewrite 
+Apache module by copying a load file as bellow :
+
+::
+
+  sudo cp /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/
+
+Now you should be able to access the ZOO Kernel using a simplified by restarting 
+your Apache Web server :
+
+::
+
+  sudo /etc/init.d/apache2 restart
+  
+Two other softwares form the OSGeoLive environment will be used during this workshop. 
+Geoserver will first be used to provide WFS input data for the ZOO Services we are going 
+to develop. The Geoserver sample dataset (United States polygons) will be passed to our 
+service during section 3. So please start the Geoserver using the corresponding launcher 
+in the Servers folder, as illustrated in the following screenshot :
+
+OpenLayers library is also available on the OSGeoLive virtual machine image disk, and it 
+will be used during section 4, for building a simple WPS client application able to query 
+the newly developed ZOO Services. 
+
+As we planned to use OGR C-API and Python module of the GDAL library, we will need the 
+corresponding header files, libraries and associated files. Hopefully everything was 
+already available per default and so ready to use on the OSGeoLive packaging.
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/index.txt	(revision 672)
@@ -0,0 +1,10 @@
+.. _tutorial:
+
+ZOO Tutorial
+============
+
+.. toctree::
+   :maxdepth: 2
+   
+   introduction
+   environment
Index: /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/introduction.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/introduction.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/tutorial/introduction.txt	(revision 672)
@@ -0,0 +1,97 @@
+.. _tutorialintro:
+
+Introduction
+============
+
+What is ZOO?
+------------
+
+ZOO is a WPS (Web Processing Service) open source project recently released under a MIT/X-11 
+style license. It provides an OGC WPS compliant developer-friendly framework to create and 
+chain WPS Web services. ZOO is made of three parts:
+
+ZOO Kernel
+  A powerful server-side C Kernel which makes it possible to manage and chain Web services 
+  coded in different programming languages. 
+  
+ZOO Services
+  A growing suite of example Web Services based on various open source libraries. 
+  
+ZOO API
+  A server-side JavaScript API able to call and chain the ZOO Services, which makes the 
+  development and chaining processes easier. 
+
+ZOO is designed to make the WPS server-side development easier by providing a powerful system 
+able to understand and execute WPS compliant queries. It supports several programming languages, 
+thus allowing you to create Web Services in your favorite language and from existing code. 
+Further information on the project is available on the 
+`ZOO Project official website <http://www.zoo-project.org/>`__.
+
+How does ZOO work?
+------------------
+
+ZOO is based on a 'WPS Service Kernel' which constitutes the ZOO's core system (aka ZOO Kernel). 
+The latter is able to load dynamic libraries and to handle them as on-demand Web services. 
+The ZOO Kernel is written in C language, but supports several common programming languages 
+for creating ZOO Services.
+
+A :ref:`ZOO Service <services>` is a link composed of a ZOO metadata file (.zcfg) and the code 
+for the corresponding implementation. The metadata file describes all the available functions 
+which can be called using a WPS Exec Request, as well as the desired input/output. Services 
+contain the algorithms and functions, and can now be implemented in C/C++, Fortran, Java, 
+Python, PHP and JavaScript.
+
+:ref:`ZOO Kernel <kernel>` works with Apache and can communicate with cartographic engines 
+and Web mapping clients. It simply adds the WPS support to your spatial data infrastructure 
+and your Web mapping application. It can use every GDAL/OGR supported formats as input data 
+and create suitable vector or raster output for your cartographic engine and/or your 
+web-mapping client application.
+
+What are we going to do in this workshop?
+-----------------------------------------
+
+This workshop aims to present the ZOO Project and its features, and to explain its capabilities 
+regarding the WPS 1.0.0 specification. The participants will learn in 3 hours how to use ZOO 
+Kernel, how to create ZOO Services  and their configuration files and finally how to link 
+the created Service with a client-side webmapping application.
+
+A pre-compiled ZOO 1.0 version is provided inside OSGeoLive, the OSGeo official Live DVD. 
+For the sack of simplicity, an OSGeoLive Virtual Machine image disk is already installed 
+on your computers. This will be used during this workshop, so the participants won't have 
+to compile and install ZOO Kernel manually. Running and testing ZOO Kernel from this 
+OSGeoLive image disk is thus the first step of the workshop, and every participants should 
+get a working ZOO Kernel in less than 30 minutes.
+
+Once ZOO Kernel will be tested from a Web browser using GetCapabilities requests, 
+participants will be invited to create an OGR based ZOO Service Provider aiming to enable 
+simple spatial operations on vector data. Participants will first have to choose whether 
+they will create the service using C or Python language. Every programming step of the ZOO 
+Service Provider and the related Services will be each time detailed in C and Python.
+
+Once the ZOO Services will be ready and callable by ZOO Kernel, participants will finally 
+learn how to use its different functions from an OpenLayers simple application. A sample 
+dataset from Geoserver will be displayed on a simple map using WMS/WFS standards and used as 
+input data by the ZOO Services. Then, some specific selection and execution controls will be 
+added in the JavaScript code in order to execute single and multiple geometries on the displayed 
+polygons.
+
+Once again, the whole procedure will be organized step-by-step and detailed with numerous code 
+snippets and their respective explanations. The instructors will check the ZOO Kernel functioning 
+on each machine and will assist you while coding. Technical questions are of course welcome 
+during the workshop.
+
+Usefull tips for reading
+------------------------
+
+Codes snipets are included in yellow blocks
+
+Code changes are included in grey blocks
+
+Code snipets included in sentences are displayed this way
+
+HTTP and XML Requests are included in blue blocks
+
+
+
+*Let's go !*
+
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/building_blocks_presentation.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/building_blocks_presentation.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/building_blocks_presentation.txt	(revision 672)
@@ -0,0 +1,150 @@
+.. _ogr_base_vect_ops:
+
+*********************************************************
+Building blocks presentation - Using OGR and PgRouting based Web Services 
+*********************************************************
+
+.. contents:: Table of Contents
+    :depth: 5
+    :backlinks: top
+
+Introduction
+============
+
+In this section, you will use basic ZOO-Services : ``Buffer``, 
+``Intersection`` and ``DifferencePy`` which use OGR and psycopg Python modules.
+The intended goal of this section is to present and interact with your new building blocks before chaining them in the next section.
+
+First of all, you should use the following links to access the user
+interfaces and interact with your services, the first one is used to
+access basic spatial-tools demo client interface and  the second to
+access the routing application :
+  * `http://localhost/zoo-ws/spatialtools-py.html <http://localhost/zoo-ws/spatialtools-py.html>`__
+  * `http://localhost/zoo-ws/ <http://localhost/zoo-ws/>`__
+
+Services Provider and configuration files
+=========================================
+
+First you may verify if the ZOO-Services are available from your current setup.
+You can take a look at the ``Buffer.zcfg``, ``Intersection.zcfg`` and 
+``DifferencePy.zcfg`` to get details about parameters.
+As you can see from the ZCFG files, you will use ZOO-Services provided by the 
+``service`` Python service provider. So if you want to modify the Python code
+you will have to edit the corresponding file (so ``service.py``). 
+You are invited to use similar requests as the one used in previous
+sections to learn about each services individually.
+
+The Buffer Service
+=========================
+
+First click on a street then once the street is displayed in blue, click the 
+'Buffer' button on top, you should get similar result as displayed in the following.
+
+.. image:: ./images/Buffer_Level_15.png
+   :width: 650px
+   :align: center
+
+Since version ZOO-Project 1.2.0, you can run automatically some basic tests to 
+make sure that you wrote a correct ZCFG file and your service is validating.
+
+.. note:: the current testing is really simple and should be adapted to each Services 
+    Provider, mainly to define input names.
+
+You can use the following command:
+
+.. code-block:: bash
+    
+    cd /home/user/zoo/testing
+    ./run.sh http://localhost/cgi-bin/zoo_loader.cgi Buffer
+
+
+.. note:: During or after the test run, you can take a look inside the ``tmp`` directory 
+    which contains both the XML requests send to the ZOO Kernel (``*1.xml``) and the 
+    responses it gave (``output*.xml``).
+
+The Intersection Service
+=========================
+
+Using the same client interface as before, once you get a Buffer, you can then 
+select a street intersecting the Buffer geometry to compute intersection by clicking on the Intersection button.
+
+    
+.. image:: ./images/Intersection_Level_15.png
+   :width: 650px
+   :align: center
+
+
+The DifferencePy Service
+=========================
+
+Using the same instructions as for Intersetion, you can get the following result.
+
+.. image:: ./images/Difference_Level_15.png
+   :width: 650px
+   :align: center
+
+
+The Routing and Profile Services
+=========================
+
+First click on the blue flag then place your starting point on the
+map, do the same with the red flag to get the shortest path computed
+by the dedicated service and then display its profile. Note that when
+you pass the mouse over the profile display then you will see its
+corresponding position displayed on the map. You can also click on a
+specific step in your path to get the corresponding line displayed.
+
+.. image:: ./images/Routing_Basic.png
+   :width: 650px
+   :align: center
+
+If you take a look in the file: ``/usr/lib/cgi-bin/routing/do.zcfg``
+you may notice something new in the supported format which is
+reproduced here after. 
+ 
+.. code-block:: guess
+    
+    <Supported>
+     mimeType = image/png
+     asReference = true
+     msStyle = STYLE COLOR 125 0 105 OUTLINECOLOR 0 0 0 WIDTH 3 END
+     useMapServer = true
+     extension = json
+    </Supported>
+
+The ``mimeType`` is defined as ``image/png`` and there is two new
+parameter which are both optional:
+  * ``useMapServer``: which make you able to inform the ZOO-Kernel
+    that it have to use MapServer to publish your result as WMS / WFS or WCS (this last
+    won't be used in this workshop) rather than simply storing the
+    result as a file.
+  * ``msStyle``: which let you define your own MapServer ``STYLE`` block definition.
+
+When you need to access a result many time or for different purpose
+accross other services then it is really useful to ask ZOO-Kernel to
+publish your result as WMS, WFS or WCS.
+
+Note that no modification of the code of the do service was required
+to handle automatic pubilcation of the result as it is a vector format
+supported by OGR, only modification of the zcfg was required.
+
+This routing example is here to illustrate how easy it is to publish
+your result as WMS, WFS or WCS ressource. Indeed, when your routing 
+service was called, ZOO-Kernel published the result as WMS and WFS 
+ressources which was both used first for the UI purpose, the WMS to 
+display the resulting path on the map, the WFS for displaying details 
+about each steps. The WFS protocol is also used as the input value 
+for the profile computation. So, the computation was run once
+and accessed three times for different purposes and from different 
+clients.
+
+For more informations about the MapServer support, please refer to `the
+official  ZOO-Project Documentation <http://zoo-project.org/docs/kernel/mapserver.html>`_.
+
+Conclusion
+========
+
+Now you know this three services, and you get a simple interface to interact 
+with your MapServer WFS and your ZOO-Project WPS Servers, you are ready to use 
+the Services in a different way, by chaining them using the JavaScript ZOO-API to build 
+more complexe and powerfull services.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/first_service.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/first_service.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/first_service.txt	(revision 672)
@@ -0,0 +1,376 @@
+.. _first_service:
+
+*******************************
+Creating your first ZOO Service
+*******************************
+
+.. contents:: Table of Contents
+    :depth: 5
+    :backlinks: top
+
+Introduction
+============
+
+In this part, you will create and publish a simple ZOO-Service named ``Hello`` which 
+will simply return a hello message containing the input value provided. It will be usefull
+to present in deeper details general concept on how ZOO-Kernel works and handles 
+Execute requests.
+
+Service and publication process overview
+========================================
+
+Before starting developing a ZOO Service, you should remember that in 
+ZOO-Project, a Service is a couple made of:
+
+ * a metadata file: a ZOO Service Configuration File (ZCFG) containing metadata 
+   informations about a Service (providing informations about default / supported 
+   inputs and outputs for a Service)
+ * a Services Provider: it depends on the programming language used, but for Python it
+   is a module and for JavaScript a script file.
+
+To publish your Service, which means make your ZOO Kernel aware of its presence,
+you should copy a ZCFG file in the directory where ``zoo_loader.cgi`` is located (in this workshop, ``/usr/lib/cgi-bin``) or in any subdirectory. 
+
+.. warning:: only the ZCFG file is required  for the Service to be considerate as 
+    available. So if you don't get the Service Provider, obviously your Execute 
+    request will fail as we will discuss later.
+
+Before publication, you should store your ongoing work, so you'll start by 
+creating a directory to store the files of your Services Provider:
+
+.. code-block:: none
+    
+    mkdir -p /home/user/zoo-ws/ws_sp/cgi-env
+
+Once the ZCFG and the Python module are both ready, you can publish simply
+by copying the corresponding files in the same directory as the ZOO-Kernel.
+
+Creating your first ZCFG file
+=============================
+
+You will start by creating the ZCFG file for the ``Hello`` Service. Edit the 
+``/home/user/zoo-ws/ws_sp/cgi-env/Hello.zcfg`` file 
+and add the following content:
+
+.. code-block:: none
+    :linenos:
+    
+    [Hello]
+     Title = Return a hello message.
+     Abstract = Create a welcome string.
+     processVersion = 2
+     storeSupported = true
+     statusSupported = true
+     serviceProvider = test_service
+     serviceType = Python
+     <DataInputs>
+      [name]
+       Title = Input string
+       Abstract = The string to insert in the hello message.
+       minOccurs = 1
+       maxOccurs = 1
+       <LiteralData>
+           dataType = string
+           <Default />
+       </LiteralData>
+     </DataInputs>
+     <DataOutputs>
+      [Result]
+       Title = The resulting string
+       Abstract = The hello message containing the input string
+       <LiteralData>
+           dataType = string
+           <Default />
+       </LiteralData>
+     </DataOutputs>
+
+.. note:: the name of the ZCFG file and the name between braket (here ``[Hello]``) 
+    should be the same and correspond to the function name you will define in your 
+    Services provider.
+
+As you can see in the ZOO Service Configuration File presented above it is divided into
+three distinct sections:
+  #. Main Metadata information (from line 2 to 8)
+  #. List of Inputs metadata information (from 9 line to 19)
+  #. List of Outputs metadata information (from line 20 to 28)
+
+You can get more informations about ZCFG from `the reference documentation 
+<http://zoo-project.org/docs/services/zcfg-reference.html>`__.
+
+If you copy the ``Hello.zcfg`` file in the same directory as your ZOO Kernel 
+then you will be able to request for DescribeProcess using the ``Hello`` 
+``Identifier``. The ``Hello`` service should also be listed from Capabilities 
+document.
+
+.. code-block:: none
+   cp /home/user/zoo-ws/ws_sp/cgi-env/Hello.zcfg /usr/lib/cgi-bin
+
+Test requests
+=================
+
+In this section you will tests each WPS requests : GetCapabilities, 
+DescribeProcess and Execute. Note that only GetCapabilities and DescribeProcess
+should work at this step.
+
+Test the GetCapabilities request
+--------------------------------
+
+If you run the ``GetCapabilities`` request:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS
+
+Now, you should find your Hello Service in a ``Process`` node in 
+``ProcessOfferings``:
+
+.. code-block:: xml
+    
+    <wps:Process wps:processVersion="2">
+     <ows:Identifier>Hello</ows:Identifier>
+     <ows:Title>Return a hello message.</ows:Title>
+     <ows:Abstract>Create a welcome string.</ows:Abstract>
+    </wps:Process>
+
+Test the DescribeProcess request
+--------------------------------
+
+You can access the ``ProcessDescription`` of the ``Hello`` service using the 
+following ``DescribeProcess`` request:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=Hello
+
+You should get the following response:
+
+.. code-block:: xml
+    
+    <wps:ProcessDescriptions xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd" service="WPS" version="1.0.0" xml:lang="en-US">
+      <ProcessDescription wps:processVersion="2" storeSupported="true" statusSupported="true">
+        <ows:Identifier>Hello</ows:Identifier>
+        <ows:Title>Return a hello message.</ows:Title>
+        <ows:Abstract>Create a welcome string.</ows:Abstract>
+        <DataInputs>
+          <Input minOccurs="1" maxOccurs="1">
+            <ows:Identifier>name</ows:Identifier>
+            <ows:Title>Input string</ows:Title>
+            <ows:Abstract>The string to insert in the hello message.</ows:Abstract>
+            <LiteralData>
+              <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
+              <ows:AnyValue/>
+            </LiteralData>
+          </Input>
+        </DataInputs>
+        <ProcessOutputs>
+          <Output>
+            <ows:Identifier>Result</ows:Identifier>
+            <ows:Title>The resulting string</ows:Title>
+            <ows:Abstract>The hello message containing the input string</ows:Abstract>
+            <LiteralOutput>
+              <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
+            </LiteralOutput>
+          </Output>
+        </ProcessOutputs>
+      </ProcessDescription>
+    </wps:ProcessDescriptions>
+
+Test the Execute request
+------------------------
+
+Obviously, you cannot run your Service because the Python file was not published
+yet. If you try the following ``Execute`` request:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
+
+You should get an ExceptionReport similar to the one provided in the following, 
+which is normal behavior:
+
+.. code-block:: xml
+
+    <ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd" xml:lang="en-US" version="1.1.0">
+      <ows:Exception exceptionCode="NoApplicableCode">
+        <ows:ExceptionText>Python module test_service cannot be loaded.</ows:ExceptionText>
+      </ows:Exception>
+    </ows:ExceptionReport>
+
+Implementing the Python Service
+================================
+
+General Principles
+------------------
+
+The most important thing you must know when implementing a new ZOO-Services 
+using the Python language is that the function corresponding to your Service 
+returns an integer value representing the status of execution 
+(``SERVICE_FAILED`` [#f1]_ or ``SERVICE_SUCCEEDED`` [#f2]_) and takes three 
+arguments (`Python dictionaries
+<http://docs.python.org/tutorial/datastructures.html#dictionaries>`__): 
+
+  -  ``conf`` : the main environment configuration (corresponding to the main.cfg content) 
+  - ``inputs`` : the requested / default inputs (used to access input values)
+  - ``outputs`` : the requested / default outputs (used to store computation result)
+
+.. note:: when your service return ``SERVICE_FAILED`` you can set 
+    ``conf["lenv"]["message"]`` to add a personalized message in the ExceptionReport 
+    returned by the ZOO Kernel in such case.
+
+You get in the following a sample ``conf`` value based on the ``main.cfg`` file you 
+saw `before <using_zoo_from_osgeolivevm.html#zoo-kernel-configuration>`__.
+
+.. code-block:: javascript
+    :linenos:    
+
+    {
+      "main": {
+        language: "en-US",
+        lang: "fr-FR,ja-JP",
+        version: "1.0.0",
+        encoding: "utf-8",
+        serverAddress: "http://localhost/cgi-bin/zoo_loader.cgi",
+        dataPath: "/var/data",
+        tmpPath: "/var/www/temp",
+        tmpUrl: "../temp",
+        cacheDir: "/var/www/temp/"
+      },
+      "identification": {
+        title: "ZOO-Project Workshop - FOSS4G 2014",
+        keywords: "WPS,GIS,buffer",
+        abstract: "Deploying Web Processing Services using ZOO-Project – Examples of Python based WPS using PgRouting",
+        accessConstraints: "none",
+        fees: "None"
+      },
+      "provider": {
+        positionName: "Developer",
+    	providerName: "ZOO-Project",
+    	addressAdministrativeArea: "Lattes",
+    	addressCountry: "fr",
+    	phoneVoice: "False",
+    	addressPostalCode: "34970",
+    	role: "Dev",
+    	providerSite: "http://www.zoo-project.org",
+    	phoneFacsimile: "False",
+    	addressElectronicMailAddress: "gerald.fenoy@geolabs.fr",
+    	addressCity: "Denver",
+    	individualName: "Gérald FENOY"
+      }
+
+In the following you get a sample outputs value passed to a Python or a JavaScript Service:
+
+.. code-block:: javascript
+    :linenos:    
+
+    {
+      'Result': {
+        'mimeType': 'application/json', 
+	'inRequest': 'true', 
+	'encoding': 'UTF-8'
+      }
+    }
+
+.. note:: the ``inRequest`` value is set internally by the ZOO-Kernel and can be    used to determine from the Service if the key was provided in the request.
+
+ZOO-Project provide a ZOO-API which was originally only available for
+JavaScript services, but thanks to the work of the ZOO-Project
+community, now you have also access to a ZOO-API when using
+the Python language. Thanks to the Python ZOO-API you don't have to remember anymore
+the value of SERVICE_SUCCEDED and SERVICE_FAILED, you
+have the capability to translate any string from your Python service
+by calling the ``_`` function (ie: ``zoo._('My string to
+translate')``) or to update the current status of a running service by
+using the ``update_status`` [#f4]_ function the same way you use it from
+JavaScript or C services.
+
+The Hello Service
+------------------------
+
+You can copy and paste the following into the 
+``/home/user/zoo-ws/ws_sp/cgi-env/test_service.py`` file.
+
+.. code-block:: python
+    
+    import zoo
+    def Hello(conf,inputs,outputs):
+        outputs["Result"]["value"]=\
+		"Hello "+inputs["name"]["value"]+" from the ZOO-Project Python world !"
+        return zoo.SERVICE_SUCCEEDED
+
+Once you finish editing the file, you should copy it in the ``/usr/lib/cgi-bin`` directory: 
+
+.. code-block:: none
+    
+    sudo cp /home/user/zoo-ws/ws_sp/cgi-env/* /usr/lib/cgi-bin
+
+
+Interracting with your service using Execute requests
+=====================================================
+
+Now, you can request for Execute using the following basic url:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
+
+You can request the WPS Server to return a XML WPS Response containing the result of 
+your computation, requesting for ResponseDocument or you can access the data directly
+requesting for RawDataOutput. 
+
+* Sample request using the RawDataOutput parameter:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&RawDataOutput=Result
+
+* Sample request using the default ResponseDocument parameter:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result
+
+When you are using ResponseDocument there is specific attribut you can use to ask 
+the ZOO Kernel to store the result: ``asReference``. You can use the following example:
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result@asReference=true
+
+When computation take long time, the client should request the
+execution of a Service by setting both ``storeExecuteResponse`` and
+``status`` parameter to true to force asynchronous execution. This
+will make the ZOO-Kernel return, without waiting for the Service execution
+completion but after starting another ZOO-Kernel process responsible
+of the Service execution, a ResponseDocument containing a ``statusLocation``
+attribute which can be used to access the status of an ongoing service
+or the result when the process ended [#f3]_.
+
+.. code-block:: none
+    
+    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result&storeExecuteResponse=true&status=true
+
+Conclusion
+==========
+
+Even if this first service was really simple it was useful to illustrate how the 
+ZOO-Kernel fill ``conf``, ``inputs`` and ``outputs`` parameter prior to load 
+and run your function service, how to write a ZCFG file, how to publish a Services 
+Provider by placing the ZCFG and Python files in the same directory as the 
+ZOO-Kernel, then how to interract with your service using both 
+``GetCapabilities``, ``DescribeProcess`` and ``Execute`` requests. We will see 
+in the `next section <building_blocks_presentation.html>`__ how to write similar requests 
+using the XML syntax.
+
+.. rubric:: Footnotes
+
+.. [#f1] ``SERVICE_FAILED=4``
+.. [#f2] ``SERVICE_SUCCEEDED=3``
+.. [#f4] sample use of update_status is available `here <http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-services/utils/status/cgi-env/service.py#L1>`_
+.. [#f3]  To get on-going status url in ``statusLocation``, you'll
+    need to setup the `utils/status
+    <http://www.zoo-project.org/trac/browser/trunk/zoo-project/zoo-services/utils/status>`_
+    Service. If you don't get this service available, the ZOO-Kernel will
+    simply give the url to a flat XML file stored on the server which will
+    contain, at the end of the execution, the result of the Service
+    execution. For more informations please take a look into the
+    reference  `documentation <http://zoo-project.org/docs/services/status.html>`__.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/index.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/index.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/index.txt	(revision 672)
@@ -0,0 +1,70 @@
+.. _workshop-foss4g-2014:
+
+##########################################
+Deploying Web Processing Services using ZOO-Project – Examples of Python based WPS using PgRouting 
+##########################################
+
+:Author:  Gérald Fenoy, Nicolas Bozon, Venkatesh Raghavan
+:Contact: gerald.fenoy at geolabs.fr, nicolas.bozon at gmail.com, venka at osgeo.org
+:Last Updated: $Date$
+
+****************************************
+FOSS4G 2014 Portland
+****************************************
+
+.. image:: ./images/FOSS4G_Ad_200x100_2x.jpg
+   :target: http://2014.foss4g.org/
+   :align: center
+
+**************
+Sponsored By
+**************
+
+.. image:: ../../_static/images/geolabs-logo.png
+   :target: http://www.geolabs.fr/
+
+.. image:: ../../_static/images/apptech-logo.png
+   :target: http://www.apptec.co.jp/
+
+.. image:: ../../_static/images/neogeo-logo.png
+   :target: http://www-neogeo-online.net/
+
+.. image:: ../../_static/images/3liz-logo.png
+   :target: http://www.3liz.com/
+
+.. image:: ../../_static/images/gateway-logo.png
+   :target: http://www.gatewaygeomatics.com/
+
+*******************************************
+Special thanks to our Knowledge Partners
+*******************************************
+
+.. image:: ../../_static/images/ocu-logo.png
+   :target: http://www.osaka-cu.ac.jp/english/
+
+.. image:: ../../_static/images/logo-fem.png
+    :target: http://www.fondazioneedmundmach.it/
+
+.. image:: ../../_static/images/polimi-logo.png
+    :target: http://geomatica.como.polimi.it/
+
+.. image:: ../../_static/images/gucas-logo.png
+    :target: http://www.gucas.ac.cn/gscasenglish/index.aspx
+
+.. image:: ../../_static/images/cumtb-logo.png
+    :target: http://www.cumtb.edu.cn/
+
+.. image:: ../../_static/images/logo-supsi.png
+    :target: http://www.supsi.ch/home.html
+
+****************************
+WorkShop table of content
+****************************
+.. toctree::
+   :maxdepth: 5
+   
+   introduction
+   using_zoo_from_osgeolivevm
+   first_service
+   building_blocks_presentation
+   js_services_chaining
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/introduction.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/introduction.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/introduction.txt	(revision 672)
@@ -0,0 +1,60 @@
+.. _introduction:
+
+**************
+Introduction
+**************
+
+.. contents:: Table of Contents
+    :depth: 5
+    :backlinks: top
+
+What is ZOO ?
+=============
+
+ZOO-Project is a WPS (Web Processing Service) open source project released under a `MIT/X-11 <http://zoo-project.org/trac/wiki/Licence>`__ style license. It provides an OGC WPS compliant developer-friendly framework to create and chain WPS Web services. ZOO is made of three parts:
+
+* `ZOO Kernel <http://zoo-project.org/docs/kernel/index.html#kernel>`__ : A powerful server-side C Kernel which makes it possible to manage and chain Web services coded in different programming languages.
+* `ZOO Services <http://zoo-project.org/docs/services/index.html#services>`__ : A growing suite of example Web Services based on various open source libraries.
+* `ZOO API <http://zoo-project.org/docs/api/index.html#api>`__ : A server-side JavaScript API able to call and chain the ZOO Services, which makes the development and chaining processes easier and faster.
+
+ZOO was designed to make the service creation and deployment easy, by providing a powerful system able to understand and execute WPS compliant queries. It supports seven programming languages, thus allowing you to create Web Services using the one you prefer. It also lets you use an existing code and to turn it as a WPS Service.
+The current supported programming languages are the following:
+
+* C/C++
+* Python
+* Perl
+* Java
+* Fortran
+* PHP
+* JavaScript
+
+More information on the project is available on the  `ZOO-Project official website <http://www.zoo-project.org/>`__ .
+
+How does ZOO works ?
+====================
+
+ZOO is based on a C Kernel which is the ZOO-Project core system (aka ZOO-Kernel). The latter is able to dynamically load libraries and to handle them as on-demand Web services. 
+
+A ZOO-Service is a link composed of a ZOO metadata file (.zcfg) and the code for the corresponding implementation. The metadata file describes the function that can be called using a WPS Execute Request, as well as the supported input/output formats. Service contains the algorithms and functions, and can be implemented using any of the supported languages.
+
+ZOO-Kernel works as CGI through Apache and can communicate with cartographic engines and Web mapping clients. It simply adds the WPS support to your spatial data infrastructure and your webmapping applications. It can use every GDAL/OGR supported formats as input data and create suitable vector or raster output for your cartographic engine and/or your web-mapping client application. 
+
+What are we going to do in this workshop?
+===============================
+
+You will learn how to use ZOO-Kernel and how to create ZOO-Services using the OSGeoLiveDVD 7.9 `iso image <https://sourceforge.net/projects/mapmintvm/files/latest/download?source=files>`_ provided at the begining of this workshop on MapMint USB Sticks. Despite a pre-compiled ZOO 1.3.0 package is provided inside the official OSGeoLive, some optional supports are not available in the default setup and the ZOO-Kernel made available correspond to the 1.4-dev version, so let say the current version. So you will use the binary version of ZOO-Kernel available on the iso image provided. Configuration file and basic ways to use ZOO-Kernel and ZOO-Service will be presented. Then you will be invited to start programming your own simple service using Python language. Some ZOO-Services will be presented and individually tested inside a ready-to-use OpenLayers application. Finally, this services will be chained using the server-side Javascript ZOO-API.
+
+The whole workshop is organized step-by-step and numerous code snippets are available. The instructors will check the ZOO-Kernel is functioning on each machine and will assist you while coding. Technical questions are of course welcome during the workshop.
+
+Usefull tips for reading
+========================
+
+.. code-block:: guess
+
+    this is a code block
+
+.. warning:: This is a warning message.
+
+.. note:: This is an important note.
+
+**Let's go !**
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/js_services_chaining.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/js_services_chaining.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/js_services_chaining.txt	(revision 672)
@@ -0,0 +1,593 @@
+.. _ogr_base_vect_ops:
+
+***************************************************************
+Playing with buildign blocks - Creating JavaScript Web Services
+***************************************************************
+
+.. contents:: Table of Contents
+    :depth: 5
+    :backlinks: top
+
+Introduction
+============
+
+
+This section illustrate how you can use JavaScript on the server-side to chain 
+services together to build new ones. You will create a ZOO Services Provider 
+using the services you seen before and the WFS server using the ZOO-API. The 
+final goal is to query all POIs included in a buffer around a feature and
+to highlight them using a mask around this buffer. The following screenshot show
+you the expected result:
+
+.. image:: ./images/BufferMaskAndRequest_Level_15.png
+   :width: 650px
+   :align: center
+
+For the routing interface result should look like this:
+
+.. image:: ./images/BufferMaskAndRequest_Routing_Level_15.png
+   :width: 650px
+   :align: center
+
+You can decompose the result above in two different ones: the mask around the 
+buffer and the points included in the buffer. So you will create two different 
+Services: one called ``BufferMask`` and another one called ``BufferRequest``.
+
+But before implementing any JavaScript Service, you will get an overview of how
+to use ZOO-API from your ZOO-Project installation in the next section.
+
+As before, you first create a new directory to store files for your new Services 
+Provider:
+
+.. code-block:: guess
+    
+    mkdir -p ~/zoo-ws/jschains/cgi-env/
+
+
+ZOO-API Overview
+================
+
+ZOO-API and ZOO-Kernel JavaScript support make you able to run services 
+implemented in JavaScript on the server side. JavaScript is a popular programing
+language but mostly used on the client side. Let say from a browser, but here it
+is a bit different.
+
+To support JavaScript language ZOO-Kernel use the 
+`SpiderMonkey <https://developer.mozilla.org/en/SpiderMonkey>`__ API to create a
+javascript runtime environment from which it will load your JS file then extract
+the function corresponding to the service to run it using the prefilled
+parameters. The JavaScript runtime environment created by the ZOO-Kernel 
+depend on your setup. If you placed the ``ZOO-api.js`` and ``ZOO-proj4js.js`` in
+the same directory as your ZOO-Kernel it means that your environment will 
+contains ZOO-API and Proj4js which will be loaded before your service. In such case you can access to the Classes defined in the JavaScript ZOO-API 
+to manipulate geographic data, for more informations please refer to the 
+`ZOO-API Documentation <http://zoo-project.org/docs/api/index.html>`__. 
+
+Even if it can be useful to run JavaScript on the server side, you should 
+remember that some basic JavaScript functions you are familiar with does not 
+exist or get a different behavior. For instance the simple ``alert`` 
+function will display messages in apache error logs rather than in a window when
+used from a browser. The ``alert`` function can be used as follow:
+
+.. code-block:: guess
+
+    alert("My alert message");
+
+There is no XMLHttpRequest available in the JavaScript evironement your service 
+will run into. Hopefully, the ZOO-Kernel expose a C function to the JavaScript 
+world named: ``JSRequest``. This function make you able from your JavaScript 
+services to call other WPS services (locally or remotelly) or other kind OGC 
+services such as WFS. When you are using the ZOO-API it is possible to call 
+Services using a ``ZOO.Process`` instance [#f3]_, to parse WPS Responses using 
+``ZOO.Format.WPS`` 
+(cf. `ref <http://zoo-project.org/docs/api/zoo-process.html>`__).
+
+As for Python services you already seen in previous sections, the functions 
+corresponding to a Service should take three arguments: ``conf``, ``inputs`` and
+``outputs`` [#f4]_. Nevertheless, as the ZOO-Kernel is not able to access the 
+values modified [#f5]_ by the Service code, rather than returning an integer as 
+in Python, here you'll need to return both the integer value representing the 
+Status of your Service in a JavaScript Object and the resulting ``outputs`` 
+values as an Object [#f6]_. You can see in the following an example of a JavaScript 
+Service code:
+
+.. code-block:: none
+    
+    function SampleService(conf,inputs,outputs){
+      var resultValue=someComputation(inputs);
+      return
+        {
+            result: ZOO.SERVICE_SUCCEEDED, 
+            outputs: { "Result": { "mimeType": "application/json", "value": resultValue } }
+        };
+    }
+
+Before starting to implement the Services we will need to get our final 
+BufferRequest service, let start with a simplier one.
+
+The Mask Service
+================
+
+In this section you will learn how to create your first JavaScript service which
+will simply return a rectangular mask around a selected feature. To build this 
+mask you will use the Buffer service to create a buffer big enough around a 
+selected geometry to cover a significant part of your map. You can see the 
+expected result in the following screenshot:
+
+.. image:: ./images/Mask_Level_12.png
+   :width: 650px
+   :align: center
+
+As before, you will first start by writting the ZCFG, then you will write the 
+JavaScript source code and finish by publishing your Services Provider.
+
+The ZCFG
+--------
+
+Open a file named 
+``~/zoo-ws/jschains/cgi-env/Mask.zcfg`` 
+with your favorite text editor and add the following content:
+
+.. code-block:: none
+    :linenos:
+    
+    [Mask]
+     Title = Compute mask
+     Abstract = Compute mask around a geometry
+     processVersion = 1
+     storeSupported = true
+     statusSupported = true
+     serviceProvider = foss4gws.js
+     serviceType = JS
+     <DataInputs>
+      [InputData]
+       Title = The feature
+       Abstract = The feature to run the service with
+       minOccurs = 1
+       maxOccurs = 1
+       <ComplexData>
+        <Default>
+        mimeType = text/xml
+        encoding = utf-8
+        </Default>
+       </ComplexData>
+     </DataInputs>
+     <DataOutputs>
+      [Result]
+       Title = The resulting feature
+       Abstract = The feature created by the service.
+       <ComplexOutput>
+         <Default>
+         mimeType = application/json
+         </Default>
+       </ComplexOutput>
+     </DataOutputs>  
+
+Here you simply define one default ``ComplexData`` for both ``inputData`` and
+``Result``: a GML and a GeoJSON respectively [#f7]_.
+ 
+The JavaScript service
+----------------------
+
+As you will have to request the Buffer service many times from your service, you
+will first define a ``Buffer`` function as follow. It uses the ``ZOO.Process`` 
+to request the Buffer service you seen in the previous section.
+
+Open a file named 
+``~/zoo-ws/jschains/cgi-env/foss4gws.js`` and 
+add the following content:
+
+.. code-block:: javascript
+    :linenos:
+    
+    var zoo_url='http://localhost/cgi-bin/zoo_loader.cgi';
+    var mapfile="/var/data/maps/project_WS2014.map";
+    var mapserv_url="http://localhost/cgi-bin/mapserv?map="+mapfile;
+
+    function Buffer(inputData,bDist){
+    
+      // Create all required ZOO.formats
+      var fJ=new ZOO.Format.JSON();
+      var fGJ=new ZOO.Format.GeoJSON();
+      var fWPS=new ZOO.Format.WPS();
+    
+      // Pass the value as json
+      var myInputs = {
+      	  InputPolygon: { type: 'complex', value: fGJ.write(inputData), mimeType: "application/json"}, 
+	  BufferDistance: {type: 'float', "value": bDist }
+      };  
+      var myOutputs= { Result: { type: 'RawDataOutput', "mimeType": "application/json" } };
+      var myProcess = new ZOO.Process(zoo_url,'BufferPy');
+      var myExecuteResult=myProcess.Execute(myInputs,myOutputs);
+    
+      return fGJ.read(myExecuteResult);
+    
+    }
+
+From line 12 to 16, you give a GeoJSON string (created from ``inputData``) for 
+InputPolygon and, on line 15, you set the BufferDistance value to ``bDist``. 
+On line 17, you define Result as a RawDataOutput, so you won'tl have to parse the
+WPS response using the ZOO.Format.WPS.
+
+On line 18, you create a 
+`ZOO.Process <http://zoo-project.org/docs/api/zoo-process.html#zoo-process>`__ 
+instance providing the ZOO-Kernel url and the Service name. Then, on line 19, you
+run the request passing inputs and outputs previously defined (from line 12 to 15). On line 21 you return the GeoJSON red.
+
+Now, you get your ``Buffer`` function, it is time to create your first JavaScript 
+service. So, edit your ``foss4gws.js`` file you created before and add the following content:
+
+.. code-block:: javascript
+    :linenos:
+    
+    function Mask(conf,inputs,outputs){
+      
+      // Create all required ZOO.formats
+      var fGML=new ZOO.Format.GML();
+      var fGJ=new ZOO.Format.GeoJSON();
+    
+      // Read the input GML
+      var inputData=fGML.read(inputs["InputData"]["value"]);
+      
+      // Compute Buffer
+      var bufferResultAsJSON=Buffer(inputData,0.015);
+    
+      // Create the Buffer result BBOX and store its geometry in a ZOO.Feature
+      var bbox = new ZOO.Bounds();
+      var bounds=bufferResultAsJSON[0].geometry.getVertices();
+      for(var t in bounds){
+        bbox.extend(bounds[t]);
+      }
+      var finalG=bbox.toGeometry();
+      var result=new ZOO.Feature(finalG,{"name": "Result1000"});
+      
+      // Return the created feature
+      return {
+          result: ZOO.SERVICE_SUCCEEDED, 
+          outputs: { "Result": { mimeType: "application/json", value: fGJ.write(result) } } 
+      };
+     
+    }
+
+Publish and use your Service
+----------------------------
+
+Now you get both your ZCFG and your service code ready, you need to deploy your 
+new Services Provider using the following command:
+
+.. code-block:: bash
+    
+    sudo cp ~/zoo-ws/jschains/cgi-env/* /usr/lib/cgi-bin
+
+Now you are ready to use your JavaScript service by loading the following `url 
+<http://localhost/zoo-ws/spatialtools.html>`__, click on a street then click on
+the "Mask" button.
+
+BufferMask Service
+==================
+
+In this section you will implement a simple JavaScript service which will be able create
+a hole in the mask you created in `previous section <#mask-service>`__. This service
+will be used to highlight the buffer zone around a selected fature. You get a preview of 
+the expected result in the following screenshot:
+
+.. image:: ./images/BufferMask_Level_15.png
+   :width: 650px
+   :align: center
+
+
+The ZCFG
+--------
+
+Open the file named 
+``~/zoo-ws/jschains/cgi-env/BufferMask.zcfg`` 
+with your favorite text editor and copy / paste the following content:
+
+.. code-block:: none
+    :linenos:
+    
+    [BufferMask]
+     Title = Compute buffer mask
+     Abstract = Compute buffer mask around a geometry
+     processVersion = 1
+     storeSupported = true
+     statusSupported = true
+     serviceProvider = foss4gws.js
+     serviceType = JS
+     <DataInputs>
+      [InputData]
+       Title = The feature
+       Abstract = The feature to run the service with
+       minOccurs = 1
+       maxOccurs = 1
+       <ComplexData>
+        <Default>
+        mimeType = text/xml
+        encoding = utf-8
+        </Default>
+       </ComplexData>
+     </DataInputs>
+     <DataOutputs>
+      [Result]
+       Title = The resulting feature
+       Abstract = The feature created by the service.
+       <ComplexOutput>
+         <Default>
+         mimeType = application/json
+         </Default>
+       </ComplexOutput>
+     </DataOutputs>  
+
+This ZCFG is similar to the previous one. Please, refer to comments in the 
+`previous section <#the-zcfg>`__ for more informations.
+
+The JavaScript service
+----------------------
+
+In this Service you will use same source code (until line 19) you used in the 
+`previous section <#the-javascript-service>`__. Indeed, you should compute the Mask
+as you did before then compute Buffer for creating a hole in the mask (on line 22) to run 
+the Difference service (from line 25 to 40). 
+
+.. code-block:: guess
+    :linenos:
+    
+     function BufferMask(conf,inputs,outputs){
+       
+       // Create all required ZOO.formats
+       var fGML=new ZOO.Format.GML();
+       var fGJ=new ZOO.Format.GeoJSON();
+     
+       // Read the input GML
+       var inputData=fGML.read(inputs["InputData"]["value"]);
+       
+       // Compute Buffer
+       var bufferResultAsJSON=Buffer(inputData,0.015);
+     
+       // Create the Buffer result BBOX 
+       var bbox = new ZOO.Bounds();
+       var bounds=bufferResultAsJSON[0].geometry.getVertices();
+       for(var t in bounds){
+         bbox.extend(bounds[t]);
+       }
+       var finalG=bbox.toGeometry();
+
+      // Compute Buffer standard buffer
+      var bufferResultAsJSON=Buffer(inputData,0.0015);
+    
+      // Request Difference service using Buffer result and features in the BBOX
+      var result=new ZOO.Feature(finalG,{"name": "Result1000"});  
+      var myProcess2 = new ZOO.Process(zoo_url,'DifferencePy');
+      var myInputs2 = {
+          InputEntity1: {
+              type: 'complex', 
+              value: fGJ.write(finalG), 
+              mimeType: "application/json" 
+          }, 
+          InputEntity2: { 
+              type: 'complex', 
+              value: fGJ.write(bufferResultAsJSON), 
+              mimeType: "application/json"
+          }
+      };
+      var myOutputs2= {Result: {type: 'RawDataOutput',  mimeType: "application/json" } };
+      var myExecuteResult4=myProcess2.Execute(myInputs2,myOutputs2);
+
+       // Return the bbox
+       var result=new ZOO.Feature(finalG,{"name": "Result1000"});
+       return {
+           result: ZOO.SERVICE_SUCCEEDED, 
+           outputs: { "Result": {mimeType: "application/json", value: myExecuteResult4 } } 
+       };
+     
+     }
+
+Publish and use your Service
+----------------------------
+
+Now, you can publish your service as you did `before <#publish-your-service>`__. To 
+use your service, please use the following `url 
+<http://localhost/zoo-ws/spatialtools.html>`__.
+
+BufferRequest service
+======================
+
+In this section, you will create a new Service: ``BufferRequest`` which will request 
+POIs included in the Buffer around a selected feature [#f8]_. You will use the ``poi`` 
+layer served as WFS through your local mapserver installation. You can see in the 
+following screenshot the expected result: 
+
+.. image:: ./images/BufferRequest_Level_15.png
+   :width: 650px
+   :align: center
+
+The ZCFG
+--------
+
+Open the file named 
+``~/zoo-ws/jschains/cgi-env/BufferRequest.zcfg`` 
+with your favorite text editor and copy / paste the following content:
+
+.. code-block:: none
+    :linenos:
+    
+    [BufferRequest]
+     Title = Compute buffer request
+     Abstract = Compute buffer request around a geometry
+     processVersion = 1
+     storeSupported = true
+     statusSupported = true
+     serviceProvider = foss4gws.js
+     serviceType = JS
+     <DataInputs>
+      [InputData]
+       Title = The feature
+       Abstract = The feature to run the service with
+       minOccurs = 1
+       maxOccurs = 1
+       <ComplexData>
+        <Default>
+        mimeType = text/xml
+        encoding = utf-8
+        </Default>
+       </ComplexData>
+     </DataInputs>
+     <DataOutputs>
+      [Result]
+       Title = The resulting feature
+       Abstract = The feature created by the service.
+       <ComplexOutput>
+         <Default>
+         mimeType = application/json
+         </Default>
+       </ComplexOutput>
+     </DataOutputs>  
+
+
+The JavaScript code
+-------------------
+
+As in the previous Service, you will compute a buffer around the input feature. But then
+you will request POIs available in the Buffer extent using a WFS request to use them to 
+run ``Intersection`` service using the initial Buffer. The WFS request is useful to limit 
+the number of points to use when requesting the ``Intersection`` Service.
+
+.. code-block:: javascript
+    :linenos:
+    
+    function BufferRequest(conf,inputs,outputs){
+    
+      // Create all required ZOO.formats
+      var fGJ=new ZOO.Format.GeoJSON();
+      var fGML=new ZOO.Format.GML();
+    
+      // Read the input GML
+      var inputData=fGML.read(inputs["InputData"]["value"]);
+    
+      // Compute Buffer
+      var bufferResultAsJSON=Buffer(inputData,0.0015);
+    
+      // Create the Buffer result BBOX 
+      var bbox = new ZOO.Bounds();
+      var bounds=bufferResultAsJSON[0].geometry.getVertices();
+      for(var t in bounds){
+        bbox.extend(bounds[t]);
+      }
+    
+      // Request Intersection service using Buffer result and WFS request using the
+      // BBOX
+      var myProcess2 = new ZOO.Process(zoo_url,'Intersection');
+      var req="&amp;SERVICE=WFS&amp;version=1.0.0&amp;request=GetFeature&amp;typename=poi1";
+      req+="&amp;SRS=EPSG:4326&amp;BBOX=";
+      var myInputs2 = {
+        InputEntity1: { 
+          type: 'complex',  
+          value: fGJ.write(bufferResultAsJSON), 
+          mimeType: "application/json"
+        }, 
+        InputEntity2: { 
+          type: 'complex',  
+          xlink: mapserv_url+req+bbox.left+","+bbox.bottom+","+bbox.right+","+bbox.top, 
+          mimeType: "text/xml" 
+        } 
+      };
+      var myOutputs2= {Result: { type: 'RawDataOutput', "mimeType": "application/json" } };
+      var myExecuteResult4=myProcess2.Execute(myInputs2,myOutputs2);
+    
+      return {
+        result: ZOO.SERVICE_SUCCEEDED, 
+        outputs: [ {name:"Result", mimeType: "application/json", value: myExecuteResult4} ]
+      };
+    
+    }
+
+.. warning:: to take advantage of the ZOO-Kernel cache system, you directly use the WFS
+    request  as ``xlink:href`` rather than value for ``InputEntity2`` (from line 31 to 34) and use ``text/xml`` ``mimeType`` 
+    (on line 40). Indeed, the ZOO-API doesn't use the internal cache mechanisms.
+
+
+Publish and use your Service
+----------------------------
+
+Now, you can publish your service as you did `before <#publish-your-service>`__. To 
+use your service, please use the following `url 
+<http://localhost/zoo-ws/spatialtools.html>`__.
+
+.. note:: You can click on "Buffer Request and Mask"  to get the same result as presented 
+    in  `the initial screenshot <#introduction>`__.
+
+
+Add Union into the chain
+===================================
+
+As you can see in the following screenshot, when using the Buffer
+service using a feature collection containing more than one geometry,
+the result is made of multiple geometries. So, running Buffer service
+on the routing interface will result in multiple buffer:
+
+.. image:: ./images/Buffer_Routing_Level_15.png
+   :width: 650px
+   :align: center
+
+So, to get the same result as you got when selecting a single
+road, you should use Union of geometry (input or the one outputed by the
+``Buffer`` Service). As you are using the JavaScript ZOO-API, you can
+simply update the ``Buffer`` JavaScript function you defined earlier, to
+first call the Union of each geometry avaible in a feature collection
+prior to request (or after requesting) the Buffer Service. Hopefully,
+there is already this Python Service available, its name is
+``UnionOne1``, so you just need to add it in your Service chain.
+
+Here is the final code for the Buffer JavaScript function:
+
+.. code-block:: javascript
+    :linenos:
+    
+    function Buffer(inputData,bDist){
+    
+      // Create all required ZOO.formats
+      var fJ=new ZOO.Format.JSON();
+      var fGJ=new ZOO.Format.GeoJSON();
+      var fWPS=new ZOO.Format.WPS();
+    
+      // Call the UnionOne1 Service
+      var myInputs0 = {
+      	  InputPolygon: { type: 'complex', value: fGJ.write(inputData), mimeType: "application/json"}, 
+	  BufferDistance: {type: 'float', "value": bDist }
+      };  
+      var myOutputs0= { Result: { type: 'RawDataOutput', "mimeType": "application/json" } };
+      var myProcess0 = new ZOO.Process(zoo_url,'UnionOne1');
+      var myExecuteResult0=myProcess0.Execute(myInputs0,myOutputs0);
+
+      // Call the BufferPy Service
+      var myInputs = {
+      	  InputPolygon: { type: 'complex', value: myExecuteResult0, mimeType: "application/json"}, 
+	  BufferDistance: {type: 'float', "value": bDist }
+      };  
+      var myOutputs= { Result: { type: 'RawDataOutput', "mimeType": "application/json" } };
+      var myProcess = new ZOO.Process(zoo_url,'BufferPy');
+      var myExecuteResult=myProcess.Execute(myInputs,myOutputs);
+    
+      return fGJ.read(myExecuteResult);
+    
+    }
+
+   
+Conclusion
+==========
+
+After understanding how basic Geometric Operation Services works, here you built step by step new JavaScript services which reuse the previous ones and combine them in different ways. This was achieved using the ZOO-API, composed by C functions exposed by the ZOO-Kernel to the JavaScript services runtime environement and the JS files which can be optionally installed. 
+
+.. rubric:: Footnotes
+
+.. [#f3] The ``ZOO.Process`` class uses ``JSRequest`` (cf. `ref 
+    <http://zoo-project.org/docs/api/zoo-format-wps.html>`__). You will get example
+    of use `later  <#the-javascript-service>`__.
+.. [#f4] So ``conf``, ``inputs`` and ``outputs`` are simple JavaScript objects, similar 
+    to the Python dictionaries used in the `previous section <ogr_base_vect_ops.html>`__.    
+.. [#f5] Such as ``conf``, ``inputs`` and ``outputs``.
+.. [#f6] You can also return a conf Object if you get any informations updated from your JavaScript service (such as cookie for instance)
+.. [#f7] Using one of the available ``ZOO.formats`` you are also able to support various
+    ``ComplexData`` for both input and output of the service. To simplify the 
+    presentation here, you will use only this default ones.
+.. [#f8] So in the hole you created in the previous section.
Index: /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/using_zoo_from_osgeolivevm.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/using_zoo_from_osgeolivevm.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/docs/workshop/2014/using_zoo_from_osgeolivevm.txt	(revision 672)
@@ -0,0 +1,218 @@
+.. _using_zoo_from_osgeolivevm:
+
+********************************************************************
+Configuration and ZOO-Kernel use
+********************************************************************
+
+.. contents:: Table of Contents
+    :depth: 5
+    :backlinks: top
+
+ZOO-Kernel Configuration
+========================
+
+As already said in introduction, an OSGeoLive Virtual Machine has been booted on your computer, allowing you to use ZOO-Kernel in a development environment directly. 
+
+.. note:: we will use ZOO-Kernel or ``zoo_loader.cgi`` script without any distinction 
+    in this document.
+
+General ZOO-Kernel settings are set in the ``main.cfg`` file located in the same directory as the ZOO-Kernel, so in ``/usr/lib/cgi-bin/``. This informations will be accessible from each services at runtime, so when you wil use Execute requests. You can see a typical ``main.cfg`` content in the following:
+
+.. code-block:: guess
+    :linenos:
+    
+    [headers]
+    X-Powered-By=ZOO-Project@MapMint
+    
+    [main]
+    encoding=utf-8
+    dataPath=/var/data
+    tmpPath=/var/www/temp
+    cacheDir=/var/www/cache
+    version=1.0.0
+    sessPath=/tmp
+    msOgcVersion=1.0.0
+    serverAddress=http://localhost/cgi-bin/mm/zoo_loader.cgi
+    lang=fr-FR,ja-JP
+    language=en-US
+    mapserverAddress=http://localhost/cgi-bin/mapserv.cgi
+    tmpUrl=http://127.0.0.1/temp/
+    
+    [identification]
+    keywords=WPS,GIS,buffer,MapMint,ZOO-Project
+    title=ZOO-Project Workshop - FOSS4G 2014
+    abstract= Deploying Web Processing Services using ZOO-Project – Examples of Python based WPS using PgRouting 
+    accessConstraints=none
+    fees=None
+    
+    [provider]
+    positionName=Developer
+    providerName=GeoLabs SARL
+    addressAdministrativeArea=False
+    addressDeliveryPoint=1280, avenue des Platanes
+    addressCountry=fr
+    phoneVoice=+33467430995
+    addressPostalCode=34970
+    role=Dev
+    providerSite=http://www.geolabs.fr
+    phoneFacsimile=False
+    addressElectronicMailAddress=gerald@geolabs.fr
+    addressCity=Lattes
+    individualName=Gérald FENOY
+    
+
+The ``main.cfg`` file contains metadata informations about the identification and provider but also some important settings. The file is composed of various sections, namely ``[main]``, ``[identification]`` and ``[provider]`` per default. 
+
+From the ``[main]`` section settings are as follow:
+ * ``lang``: the supported languages separated by a coma (the first is the default one),
+ * ``version``: the supported WPS version,
+ * ``encoding``: the default encoding of WPS Responses,
+ * ``serverAddress``: the url to access your ZOO-Kernel instance,
+ * ``dataPath``: the path to store data files (when MapServer support was activated, 
+   this directory is used to store mapfiles and data).
+ * ``tmpPath``: the path to store temporary files (such as ExecuteResponse when 
+   storeExecuteResponse was set to true),
+ * ``tmpUrl``: a url relative to ``serverAddress`` to access the temporary file,
+ * ``cacheDir``: the path to store cached request files [#f1]_ (optional),
+ * ``mapservAddress``: your local MapServer address (optional),
+ * ``msOgcVersion``: the version for all supported OGC Web Services output [#f2]_
+   (optional).
+
+The ``[identification]`` and ``[provider]`` section are specific to OGC metadata and
+should be set [#f3]_.
+
+Obviously, you are free to add new sections to this file if you need
+more [#f8]_. Nevertheless, you have to know 
+that there is some specific names you should use only for specific
+purposes: ``[headers]``, ``[mapserver]``, ``[env]``, ``[lenv]`` and ``[senv]``.
+
+.. warning:: ``[senv]`` and ``[lenv]`` are used / produced on runtime internaly by the ZOO-Kernel and should be defined only from the Service code.
+
+The ``headers`` section is used to define your own HTTP Response
+headers. You may take a look at headers returned by web site such as 
+http://www.zoo-project.org by using curl command line tool for
+instance and notice the specific heder ``X-Powered-By: Zoo-Project@Trac``.
+
+.. warning:: There is no reason to define basic headers such as
+    ``Content-Type`` or ``encoding`` as they will be overwritten at runtime by the
+    ZOO-Kernel.
+
+The ``mapserver`` section is used to store specific mapserver configuration 
+parameters such as `PROJ_LIB` and `GDAL_DATA` or any other you want to be set to 
+make your MapServer working.
+
+.. note:: the ``mapserver`` section is mainly used on WIN32 platform
+
+
+The ``env`` section is used to store specific environment variables you want to be set 
+prior to load your Services Provider and run your Service. A typical example, is when your
+Service requires to access to a X server running on framebuffer, then you will have to 
+set the ``DISPLAY`` environnement variable, in this case you would add 
+``DISPLAY=:1`` line in your ``[env]`` section.
+
+The ``lenv`` is used to store runtime informations automatically set by the 
+ZOO-Kernel before running your service and can be accesses / updated from it:
+ * ``sid`` (r): the service unique identifier, 
+ * ``status`` (rw): the current progress value (value between 0 and 100, percent),
+ * ``cwd`` (r): the current working directory of the ZOO-Kernel,
+ * ``message`` (rw): an error message when returning ``SERVICE_FAILED`` (optional),
+ * ``cookie`` (rw): the cookie your service want to return to the client (for authentication
+   purpose or tracking).
+
+The ``senv`` is used to store session informations on the server
+side. You can then access them automatically from service if the
+server is requested using a valid cookie (as defined in ``lenv >
+cookie``). The ZOO-Kernel will store on disk the values set in the
+``senv`` maps, then load it and dynamically add its content to the one
+available in the ``main.cfg``. The ``senv`` section should contain at
+least:
+ * ``XXX``: the session unique identifier where ``XXX`` is the name included in the 
+    returned cookie.
+
+.. _cookie_example:
+
+For instance, if you get the following in your Service source code [#f4]_ :
+
+.. code-block:: python
+    
+    conf["lenv"]["cookie"]="XXX=XXX1000000; path=/" 
+    conf["senv"]={"XXX": "XXX1000000","login": "demoUser"}
+
+That means that the ZOO-Kernel will create a file ``sess_XXX1000000.cfg`` in the 
+``cacheDir`` and return the specified cookie to the client. Each time the client will 
+request the ZOO-Kernel using the Cookie, it will automatically load the value stored 
+before running your service. You can then easilly access this informations from your 
+service source code. This functionality won't be used in the following presentation.
+
+Testing the ZOO installation with GetCapabilities
+=================================================
+
+Once you have a main.cfg file available in the same directory as your
+ZOO-Kernel, then you can use `GetCapablities`. Indeed, to answer such
+kind of requests, the ZOO-Kernel will simply parse the `main.cfg` file
+(to gather global informations), then parse individually each zcfg
+files (if any) contained in the same directory or in sub-directories
+[#f9]_, then return a well formed `Capabilities` document.
+
+You can request ZOO-Kernel using the following link from your Internet browser: 
+
+http://localhost/cgi-bin/zoo_loader.cgi?Request=GetCapabilities&Service=WPS
+
+You should get a valid Capabilities XML document, looking like the following :
+
+.. image:: ./images/GC.png
+   :width: 650px
+   :align: center
+
+Please note that some Process nodes are returned in the
+ProcessOfferings section, as somes are available already on OSGeoLive
+DVD. You can also run a GetCapabilities request from the command line,
+using the following command:  
+
+.. code-block:: bash
+
+    cd /usr/lib/cgi-bin
+    ./zoo_loader.cgi “request=GetCapabilities&service=WPS” | less
+
+The same result as in your browser will be returned, as shown in the following screenshot: 
+
+.. image:: ./images/GC_CL.png
+   :width: 450px
+   :align: center
+
+Invoking ZOO Kernel from the command line can be helpful during 
+development process of new Services for debugging purpose. If you
+need to simulate POST request from the command line, then you can use
+the following: 
+
+.. code-block:: bash
+
+    cd /usr/lib/cgi-bin
+    # Download the sample GetCapabilities request
+    curl -o /tmp/10_wpsGetCapabilities_request.xml http://schemas.opengis.net/wps/1.0.0/examples/10_wpsGetCapabilities_request.xml
+    # Define required environment settings
+    export REQUEST_METHOD=POST
+    export CONTENT_TYPE=text/xml
+    # Run the request downloaded
+    ./zoo_loader.cgi < /tmp/10_wpsGetCapabilities_request.xml | less
+
+You should have the same result as presented before.
+
+.. rubric:: Footnotes
+
+.. [#f1] when you use GET requests passed through ``xlink:href`` the ZOO-Kernel will
+    execute the request only once, the first time you will ask for this ressource and it will
+    store on disk the result. The next time you will need the same feature, the cached file
+    will be used which make your process running faster. If ``cachedir`` was not 
+    specified in the ``main.cfg`` then ``tmpPath`` value will be used.
+.. [#f2] since version 1.3.0, when MapServer is activated, your service can automatically 
+    return a WMS, WFS or WCS request to expose your data. Your can set here the specific
+    version number you want to use to request your local MapServer setup. It depends 
+    mostly on the client capability to deal with specific OGC Web Services version.
+.. [#f3] since version 1.3.0, when MapServer is activated, the same metadata will be used
+    for setting metadata for OGC Web Services.
+.. [#f8] you can take a quick look into the mapmint ``main.cfg`` file
+    which is available in `/usr/lib/cgi-bin/mm/` directory to have
+    example of sections use.
+.. [#f4] If you're not familiar with ZOO-Project, you can `pass <using_zoo_from_osgeolivevm#testing-the-zoo-installation-with-getcapabilities>`__  this part and come to it after the next section.
+.. [#f9] sub-directories listing is available from `revision 469 <http://zoo-project.org/trac/changeset/469>`__.
Index: /branches/PublicaMundi_David_integration_01-devel/testing/README
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/README	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/README	(revision 672)
@@ -0,0 +1,30 @@
+Please use the following syntaxe:
+
+  ./run.sh <WPSInstance> <ServiceName>
+
+where <WPSInstance> should be the url to a WPS Server and <ServiceName> should 
+be the service name you want to run tests with.
+
+For instance to test the Buffer service on a localhost WPS server, use the 
+following command:
+
+  ./run.sh http://localhost/cgi-bin/zoo_loader.cgi Buffer
+
+
+Important note:  sometimes XML validation failed because xmllint is unable to download
+a file required to validate. In such case, you can use the file /etc/xml/catalog on your
+local machine to use a local copy of the missing file.
+
+For instance, in case xml.xsd can't be downloaded, then you can download a copy using
+this url http://www.w3.org/2001/xml.xsd, store it in /etc/schemas directory and then 
+use the following /etc/xml/catalog file:
+
+<?xml version="1.0"?>
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+<rewriteSystem systemIdStartString="http://www.w3.org/2001/xml.xsd"
+                rewritePrefix="file:///etc/schemas/xml.xsd" />
+</catalog>
+
+Obviously, you can do similar manipulation for the OGC schemas to use local files 
+rather than downloading them for each tests.
Index: /branches/PublicaMundi_David_integration_01-devel/testing/extractExceptionInfo.xsl
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/extractExceptionInfo.xsl	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/extractExceptionInfo.xsl	(revision 672)
@@ -0,0 +1,14 @@
+<?xml version="1.0"  encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+		xmlns:ows="http://www.opengis.net/ows/1.1"
+		xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:output method="text"/>
+
+  <xsl:template match="*/*">
+      <xsl:text>Code: </xsl:text><xsl:value-of select="@exceptionCode" /><xsl:text>, Locator: </xsl:text><xsl:value-of select="@locator" />
+  </xsl:template> 
+
+</xsl:stylesheet>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/extractStatusLocation.xsl
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/extractStatusLocation.xsl	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/extractStatusLocation.xsl	(revision 672)
@@ -0,0 +1,15 @@
+<?xml version="1.0"  encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+		xmlns:ows="http://www.opengis.net/ows/1.1"
+		xmlns:wps="http://www.opengis.net/wps/1.0.0"
+		xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:output method="text"/>
+
+  <xsl:template match="wps:ExecuteResponse">
+    <xsl:value-of select="@statusLocation" />
+  </xsl:template> 
+
+</xsl:stylesheet>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/dp.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/dp.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/dp.xml	(revision 672)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<DescribeProcess xmlns="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsDescribeProcess_request.xsd" service="WPS" version="1.0.0" language="en-US">
+	<ows:Identifier>ServiceName</ows:Identifier>
+</DescribeProcess>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/igml_o.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/igml_o.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/igml_o.xml	(revision 672)
@@ -0,0 +1,19 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputName</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Data>
+<wps:ComplexData mimeType="text/xml"><wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openplans.org/topp http://www.zoo-project.org:8082/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=topp%3Astates http://www.opengis.net/wfs http://www.zoo-project.org:8082/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd"><gml:boundedBy><gml:null>unknown</gml:null></gml:boundedBy><gml:featureMember><topp:states fid="states.15"><topp:the_geom><gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-105.99836,31.393818 -106.212753,31.478128 -106.383041,31.733763 -106.538971,31.786198 -106.614441,31.817728 -106.615578,31.844635 -106.643532,31.895102 -106.633202,31.913998 -106.632057,31.972118 -106.649513,31.980228 -106.623077,32.000988 -106.377846,32.000645 -106.002708,32.001553 -104.921799,32.004269 -104.850563,32.003151 -104.018814,32.007278 -103.980896,32.00589 -103.728973,32.006104 -103.332092,32.004154 -103.057968,32.0019 -103.055191,32.084995 -103.059547,32.51543 -103.048836,32.953533 -103.042603,33.377728 -103.038239,33.565742 -103.032761,33.826088 -103.029144,34.307743 -103.022156,34.745266 -103.02475,34.964718 -103.02565,35.177208 -103.021797,35.623604 -103.022118,35.742287 -103.02356,36.056026 -103.026802,36.491566 -102.996918,36.492344 -102.165222,36.490208 -102.03421,36.492954 -101.620316,36.492004 -101.089668,36.488022 -100.956909,36.489609 -100.549416,36.489449 -100.006866,36.493877 -100.001144,36.492519 -99.997154,36.057549 -99.997726,35.883793 -100,35.618809 -99.994354,35.424572 -99.997185,35.182182 -99.996071,35.030998 -99.998878,34.747185 -99.996094,34.562321 -99.972099,34.561863 -99.94474,34.579571 -99.931908,34.579109 -99.8806,34.548176 -99.860573,34.518627 -99.829933,34.501778 -99.777687,34.443993 -99.684906,34.377445 -99.601448,34.368557 -99.58522,34.384857 -99.57785,34.408913 -99.553864,34.41518 -99.502136,34.404068 -99.479439,34.383522 -99.438377,34.364704 -99.409958,34.369106 -99.394157,34.396744 -99.392792,34.428993 -99.364204,34.450195 -99.323296,34.412708 -99.267174,34.398285 -99.254105,34.368214 -99.20549,34.331993 -99.196304,34.305122 -99.204597,34.255646 -99.190483,34.223736 -99.176155,34.21273 -99.127945,34.201469 -99.07843,34.208359 -99.035217,34.198921 -98.996193,34.209496 -98.952507,34.194565 -98.891342,34.16082 -98.811066,34.145935 -98.778534,34.131962 -98.705292,34.130714 -98.682213,34.149998 -98.66172,34.147038 -98.625992,34.158436 -98.607246,34.151398 -98.576332,34.14193 -98.557579,34.105335 -98.499519,34.066414 -98.448189,34.054375 -98.421341,34.06583 -98.407135,34.082455 -98.390953,34.087231 -98.384254,34.11578 -98.350403,34.14212 -98.320488,34.13942 -98.277,34.122871 -98.172844,34.115368 -98.136864,34.138432 -98.114868,34.148987 -98.094124,34.134556 -98.110687,34.06982 -98.086205,34.005314 -98.055557,33.989799 -98.023491,33.986984 -97.982681,34.001286 -97.950226,33.971161 -97.947754,33.959751 -97.962997,33.94865 -97.950684,33.932518 -97.976128,33.912052 -97.976379,33.902504 -97.954735,33.88348 -97.909065,33.874023 -97.869751,33.855114 -97.852547,33.857071 -97.790207,33.890457 -97.756363,33.932098 -97.729019,33.939293 -97.704262,33.971546 -97.671066,33.988613 -97.600182,33.969437 -97.592354,33.917885 -97.575668,33.902531 -97.554588,33.903904 -97.518204,33.916771 -97.477531,33.907707 -97.462761,33.902382 -97.457062,33.89043 -97.452736,33.836212 -97.410118,33.820709 -97.363319,33.831024 -97.341805,33.861916 -97.314957,33.870392 -97.314087,33.89584 -97.272278,33.872574 -97.263908,33.85873 -97.250687,33.872971 -97.246063,33.894238 -97.211334,33.905689 -97.187767,33.899204 -97.164169,33.863148 -97.168594,33.847794 -97.195015,33.836159 -97.208321,33.819649 -97.189163,33.752769 -97.152473,33.728668 -97.115562,33.725933 -97.0905,33.73167 -97.083466,33.742413 -97.087669,33.807571 -97.050026,33.823448 -97.078247,33.837811 -97.082176,33.851101 -97.0709,33.856728 -97.025597,33.840561 -97.005852,33.850513 -96.987709,33.876423 -96.987862,33.944202 -96.968185,33.937321 -96.936203,33.947849 -96.929565,33.961773 -96.898453,33.950027 -96.882851,33.924591 -96.878937,33.884003 -96.861015,33.861679 -96.844009,33.858032 -96.814117,33.871769 -96.797592,33.869949 -96.748825,33.831738 -96.711678,33.83387 -96.693382,33.847904 -96.677704,33.904324 -96.666237,33.913544 -96.584488,33.896145 -96.614166,33.8629 -96.601196,33.842957 -96.562134,33.82542 -96.510574,33.815685 -96.500748,33.78809 -96.487373,33.77813 -96.419464,33.788326 -96.370819,33.740395 -96.347588,33.705528 -96.316277,33.701801 -96.300789,33.71405 -96.28968,33.761932 -96.278076,33.773388 -96.212547,33.756691 -96.187027,33.758583 -96.168816,33.769356 -96.161316,33.798229 -96.141418,33.82032 -96.154518,33.823944 -96.180725,33.808434 -96.183128,33.815792 -96.169205,33.828983 -96.148964,33.83559 -96.109444,33.829258 -96.091522,33.844578 -96.047974,33.841278 -96.026749,33.856022 -96.014069,33.844208 -96.001793,33.856979 -96.002617,33.87339 -95.994209,33.875378 -95.977394,33.857952 -95.958763,33.86504 -95.943069,33.889973 -95.933075,33.89053 -95.846558,33.841038 -95.825974,33.843025 -95.795479,33.864674 -95.768517,33.851402 -95.764252,33.879005 -95.760696,33.89344 -95.746864,33.903397 -95.699707,33.894825 -95.633492,33.920105 -95.612984,33.920238 -95.61483,33.936691 -95.606071,33.944553 -95.562775,33.936073 -95.546318,33.904034 -95.519577,33.906643 -95.526733,33.897816 -95.547493,33.893158 -95.544037,33.885742 -95.512886,33.897736 -95.498856,33.881718 -95.468124,33.886433 -95.451607,33.865753 -95.33004,33.870918 -95.336227,33.897114 -95.301956,33.886623 -95.28643,33.886902 -95.277351,33.917938 -95.263618,33.8978 -95.250992,33.905022 -95.251289,33.936443 -95.234039,33.964863 -95.148315,33.943546 -95.127968,33.940868 -95.126678,33.917145 -95.119225,33.912281 -95.09536,33.921738 -95.082268,33.918453 -95.089714,33.896915 -95.083603,33.888462 -95.063477,33.917648 -95.063141,33.896694 -95.042862,33.884445 -95.037361,33.866451 -95.012772,33.869946 -94.989281,33.856182 -94.968704,33.866215 -94.959908,33.848076 -94.939888,33.840824 -94.940399,33.815807 -94.918236,33.816196 -94.908546,33.803478 -94.913879,33.789597 -94.881638,33.774963 -94.85788,33.749321 -94.81916,33.749405 -94.803223,33.739582 -94.783508,33.753262 -94.764175,33.752842 -94.782028,33.742268 -94.783157,33.733665 -94.749771,33.736706 -94.762718,33.716797 -94.742111,33.719048 -94.754478,33.707771 -94.741653,33.701267 -94.690987,33.690289 -94.668457,33.696537 -94.655479,33.692291 -94.644325,33.67765 -94.667953,33.671459 -94.669426,33.666061 -94.658539,33.663738 -94.638763,33.670105 -94.631737,33.683899 -94.600945,33.665607 -94.585106,33.678982 -94.578506,33.670471 -94.560722,33.671913 -94.565208,33.663013 -94.585159,33.662132 -94.588387,33.655449 -94.576462,33.652157 -94.545418,33.661621 -94.541931,33.648247 -94.562195,33.64283 -94.562149,33.635536 -94.550194,33.632694 -94.51799,33.643009 -94.525055,33.621021 -94.510559,33.63081 -94.50061,33.623047 -94.476486,33.631966 -94.435913,33.636444 -94.436333,33.616844 -94.451553,33.604347 -94.443329,33.596504 -94.428467,33.597141 -94.40657,33.573486 -94.393417,33.574959 -94.379112,33.593327 -94.370628,33.590042 -94.372307,33.572662 -94.395264,33.560303 -94.370758,33.547684 -94.328751,33.573135 -94.302383,33.556934 -94.29882,33.579853 -94.278984,33.589333 -94.272079,33.584606 -94.274544,33.561737 -94.237236,33.592422 -94.223038,33.58572 -94.235367,33.561535 -94.210884,33.557987 -94.205345,33.585079 -94.159515,33.593773 -94.155167,33.567085 -94.098701,33.572998 -94.086655,33.583954 -94.061432,33.577213 -94.035927,33.555912 -94.036507,33.270325 -94.03875,33.023289 -94.041603,32.882347 -94.040199,32.694813 -94.035233,32.389225 -94.034767,32.199448 -94.035065,31.994513 -94.009888,31.989134 -94.004395,31.977942 -93.977211,31.946159 -93.969986,31.923164 -93.93573,31.909456 -93.917923,31.909702 -93.923462,31.892593 -93.899261,31.894455 -93.892525,31.870066 -93.881264,31.87142 -93.877403,31.850113 -93.864822,31.817272 -93.834328,31.802017 -93.822067,31.774637 -93.831161,31.753281 -93.80999,31.730352 -93.814949,31.712351 -93.808769,31.707565 -93.792267,31.711395 -93.811844,31.674566 -93.806427,31.653767 -93.814728,31.647966 -93.819588,31.618092 -93.835579,31.615189 -93.832619,31.590183 -93.816322,31.57711 -93.810516,31.559063 -93.780128,31.533735 -93.763306,31.530724 -93.747543,31.537718 -93.731659,31.521877 -93.705795,31.520569 -93.718994,31.495403 -93.750435,31.490557 -93.751244,31.4855 -93.726784,31.459475 -93.698418,31.461458 -93.701927,31.446251 -93.687004,31.438131 -93.696129,31.427736 -93.694443,31.415922 -93.687492,31.40613 -93.664017,31.398329 -93.661072,31.372395 -93.634857,31.373827 -93.67704,31.328386 -93.681587,31.312679 -93.656128,31.286671 -93.645592,31.290262 -93.630829,31.273903 -93.616455,31.275805 -93.611877,31.270033 -93.611,31.242188 -93.590546,31.229687 -93.602921,31.199066 -93.593941,31.180199 -93.576942,31.17214 -93.550591,31.190929 -93.528923,31.185774 -93.526932,31.178076 -93.537018,31.17634 -93.528328,31.162943 -93.544189,31.159166 -93.537506,31.132441 -93.528091,31.125925 -93.535088,31.116072 -93.556679,31.109343 -93.559982,31.100536 -93.543121,31.094751 -93.544106,31.082373 -93.516998,31.074671 -93.525742,31.05698 -93.507217,31.038908 -93.547119,31.014141 -93.564941,31.018063 -93.567894,31.012924 -93.570847,30.997271 -93.560951,30.99169 -93.572456,30.976177 -93.548676,30.97019 -93.537338,30.956884 -93.532188,30.960732 -93.52562,30.93582 -93.529984,30.926971 -93.549622,30.924885 -93.546516,30.905334 -93.564476,30.901932 -93.568497,30.886234 -93.560844,30.87188 -93.552803,30.860283 -93.566444,30.845148 -93.555641,30.842342 -93.550682,30.828344 -93.581871,30.80204 -93.585175,30.772184 -93.618454,30.745789 -93.607651,30.73201 -93.61779,30.732548 -93.612411,30.710329 -93.617607,30.686802 -93.659988,30.672859 -93.677971,30.639692 -93.692879,30.640041 -93.684586,30.623425 -93.692696,30.615795 -93.671585,30.597832 -93.69342,30.598835 -93.717812,30.587379 -93.71788,30.568153 -93.735306,30.545517 -93.70546,30.522858 -93.714638,30.505114 -93.707275,30.496241 -93.714851,30.488628 -93.697975,30.470047 -93.703423,30.462513 -93.696571,30.442633 -93.721535,30.43298 -93.742561,30.408823 -93.754944,30.381788 -93.747833,30.367411 -93.759338,30.354145 -93.759178,30.340872 -93.729774,30.304916 -93.699211,30.297388 -93.707359,30.239372 -93.714844,30.220306 -93.704361,30.180861 -93.696167,30.175676 -93.699661,30.150808 -93.683144,30.148232 -93.685959,30.141253 -93.698639,30.141226 -93.696922,30.117929 -93.708382,30.11474 -93.715858,30.095669 -93.712479,30.06052 -93.760201,30.005964 -93.857277,29.990654 -93.856331,29.964602 -93.951767,29.818363 -93.834961,29.67457 -94.065407,29.674076 -94.356995,29.5599 -94.377007,29.55197 -94.682518,29.432905 -94.766548,29.363993 -94.785248,29.383261 -94.681915,29.475111 -94.572693,29.533052 -94.501282,29.517523 -94.469795,29.55678 -94.510811,29.545147 -94.533699,29.553984 -94.564438,29.578999 -94.788086,29.538557 -94.706421,29.658516 -94.700279,29.754568 -94.735725,29.792986 -94.829414,29.759857 -94.887161,29.668539 -94.932587,29.682209 -95.088264,29.80398 -95.040398,29.711578 -94.989334,29.679701 -95.014122,29.559265 -94.911156,29.500334 -94.982811,29.460527 -94.943756,29.464682 -94.952507,29.424234 -94.913445,29.420113 -94.916992,29.447823 -94.891136,29.399324 -94.815353,29.370932 -94.891472,29.393831 -94.898788,29.308775 -94.951134,29.325922 -95.066368,29.195877 -95.160522,29.200031 -95.16478,29.117548 -95.197342,29.105223 -95.248405,28.978392 -95.526581,28.803242 -95.683029,28.726954 -95.671318,28.752682 -95.786354,28.738871 -95.937309,28.690454 -95.956146,28.622673 -95.702148,28.718987 -96.206581,28.488386 -95.991646,28.596424 -95.983749,28.653133 -96.237587,28.571321 -96.239029,28.597116 -96.157471,28.611231 -96.240456,28.634859 -96.151062,28.762672 -96.212173,28.68672 -96.285973,28.661724 -96.270378,28.708981 -96.326157,28.634089 -96.364159,28.617981 -96.391777,28.670252 -96.392731,28.726028 -96.427086,28.712013 -96.449677,28.755035 -96.432259,28.697248 -96.403397,28.719494 -96.418785,28.638664 -96.375397,28.610088 -96.491203,28.556944 -96.437157,28.596991 -96.454384,28.655933 -96.483269,28.598055 -96.511894,28.608181 -96.511734,28.649542 -96.570396,28.636267 -96.570557,28.691841 -96.572212,28.808174 -96.576485,28.690689 -96.591499,28.71736 -96.646515,28.714142 -96.660011,28.679075 -96.606705,28.623634 -96.610344,28.558941 -96.566704,28.574099 -96.48658,28.506222 -96.563194,28.469627 -96.518501,28.460827 -96.476501,28.499454 -96.390724,28.434059 -96.661308,28.306263 -96.702362,28.340197 -96.703812,28.395885 -96.740768,28.403458 -96.787094,28.477507 -96.823875,28.44964 -96.788338,28.446255 -96.759102,28.410912 -96.77536,28.39163 -96.853493,28.404997 -96.788231,28.35247 -96.78627,28.312859 -96.793335,28.271372 -96.777931,28.229349 -96.803688,28.211447 -96.950905,28.114355 -96.91272,28.256798 -96.975304,28.210751 -96.941071,28.186771 -96.975105,28.115046 -97.033615,28.137398 -97.023567,28.199797 -97.131836,28.130426 -97.135414,28.16181 -97.167992,28.15946 -97.157059,28.116381 -97.260284,28.064724 -97.241234,28.048653 -97.270294,28.025932 -97.236214,28.04052 -97.123077,28.054266 -97.026405,28.10775 -97.023804,28.020237 -97.114624,27.915386 -97.195465,27.81222 -97.247025,27.822319 -97.213341,27.83111 -97.283485,27.871145 -97.361046,27.839954 -97.345619,27.873178 -97.479355,27.852962 -97.496681,27.875469 -97.521698,27.863626 -97.499535,27.843243 -97.479813,27.820282 -97.388542,27.831427 -97.396561,27.77084 -97.317795,27.712225 -97.34951,27.715328 -97.320015,27.690634 -97.353363,27.6408 -97.399216,27.633186 -97.347504,27.631439 -97.309212,27.707863 -97.249794,27.688831 -97.331459,27.562321 -97.412262,27.321024 -97.500435,27.319668 -97.507538,27.439215 -97.528381,27.344101 -97.600113,27.300135 -97.750076,27.419666 -97.680008,27.294373 -97.784744,27.28772 -97.548157,27.230207 -97.427216,27.265133 -97.503502,27.081541 -97.478996,26.996508 -97.568565,26.977858 -97.558052,26.846052 -97.495575,26.793781 -97.451698,26.600985 -97.425858,26.518225 -97.474709,26.476805 -97.421188,26.385059 -97.368698,26.35906 -97.353363,26.182449 -97.25312,26.068316 -97.276321,26.002275 -97.213097,26.009068 -97.172226,25.954569 -97.307144,25.965124 -97.304436,25.938663 -97.380989,25.917021 -97.385643,25.845362 -97.434349,25.845198 -97.590088,25.933231 -97.574936,25.954172 -97.612923,25.962002 -97.647972,26.023445 -97.867432,26.060141 -98.04007,26.059395 -98.076347,26.034626 -98.083214,26.065758 -98.200691,26.055376 -98.291946,26.098104 -98.271355,26.120895 -98.292274,26.132809 -98.327934,26.111647 -98.347191,26.15868 -98.384521,26.156031 -98.453392,26.220911 -98.488518,26.201544 -98.599968,26.260454 -98.677917,26.242056 -98.819832,26.375071 -98.908897,26.360329 -98.93927,26.395309 -99.106728,26.419531 -99.101471,26.48834 -99.168678,26.545729 -99.165817,26.579889 -99.285522,26.857361 -99.390518,26.94663 -99.392715,26.99555 -99.455063,27.028648 -99.437157,27.199198 -99.465271,27.269884 -99.543587,27.318653 -99.490494,27.490755 -99.526741,27.504284 -99.549187,27.612627 -99.714493,27.661558 -99.815727,27.780107 -99.874733,27.797686 -99.941856,27.986881 -99.993309,28.00346 -100.096924,28.154282 -100.214073,28.201935 -100.223465,28.241457 -100.29792,28.280354 -100.292892,28.32036 -100.35157,28.394182 -100.37677,28.478651 -100.345802,28.500811 -100.419533,28.544191 -100.403175,28.589733 -100.49791,28.660988 -100.58979,28.894222 -100.647224,28.92235 -100.66877,29.080072 -100.768608,29.166571 -100.796989,29.242502 -101.009056,29.373255 -101.06736,29.473553 -101.261429,29.526474 -101.254585,29.62875 -101.308929,29.58091 -101.305862,29.652431 -101.368401,29.657162 -101.4161,29.745434 -101.401276,29.769905 -101.448425,29.760586 -101.470467,29.788691 -101.538345,29.763018 -101.543953,29.81012 -101.58149,29.76515 -101.639671,29.75696 -101.759094,29.787167 -101.805206,29.779999 -101.819099,29.814125 -101.924225,29.788502 -101.97332,29.818773 -102.063995,29.784571 -102.324333,29.880116 -102.367561,29.845289 -102.384796,29.767946 -102.503098,29.785456 -102.551949,29.7495 -102.5765,29.778248 -102.637611,29.732338 -102.676361,29.744225 -102.804726,29.530146 -102.822205,29.411844 -102.883011,29.353371 -102.908325,29.269203 -102.866173,29.229036 -102.988098,29.190863 -103.153465,28.978682 -103.266586,29.007454 -103.28035,28.986374 -103.335518,29.050339 -103.37545,29.032108 -103.474075,29.072134 -103.526237,29.146646 -103.720314,29.190632 -103.739853,29.230349 -103.782158,29.229795 -103.767761,29.28124 -103.786995,29.26726 -104.045631,29.328119 -104.164383,29.400715 -104.204735,29.484041 -104.377594,29.550611 -104.535248,29.679466 -104.57756,29.807936 -104.67437,29.909283 -104.696495,30.057302 -104.674759,30.148964 -104.702614,30.238489 -104.813957,30.35047 -104.806473,30.376448 -104.852997,30.392263 -104.890678,30.570557 -104.986931,30.641325 -104.997543,30.684334 -105.060562,30.68787 -105.21434,30.812086 -105.258186,30.797653 -105.287598,30.831949 -105.313782,30.816507 -105.390312,30.853081 -105.409065,30.90251 -105.554382,30.998285 -105.603218,31.086428 -105.76973,31.17078 -105.99836,31.393818</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-94.913429,29.257572 -94.76738,29.342451 -94.748405,29.31949 -95.105415,29.096958 -94.913429,29.257572</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-96.397881,28.345846 -96.834625,28.066322 -96.803841,28.172161 -96.738907,28.183535 -96.532135,28.318245 -96.463051,28.325832 -96.422554,28.391439 -96.397881,28.345846</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-96.939964,28.045933 -96.872421,28.131405 -96.837425,28.101841 -96.853806,28.049402 -97.049606,27.840954 -97.024429,27.914381 -96.949387,27.984526 -96.973,28.000853 -96.939964,28.045933</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-97.359116,27.283718 -97.379379,27.210453 -97.376091,27.284643 -97.335503,27.440819 -97.248672,27.581133 -97.258682,27.651749 -97.203583,27.612064 -97.170181,27.70746 -97.075294,27.811274 -97.113037,27.819216 -97.053566,27.830473 -97.223717,27.574007 -97.359116,27.283718</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-97.301132,26.601023 -97.358025,26.706646 -97.381332,26.820375 -97.395309,26.921988 -97.400909,27.111227 -97.388786,27.201651 -97.378532,27.204449 -97.386925,27.097244 -97.381332,26.949022 -97.358025,26.802664 -97.295837,26.60067 -97.232109,26.418142 -97.194992,26.259241 -97.171799,26.077721 -97.179337,26.07192 -97.208916,26.250542 -97.226311,26.348551 -97.251251,26.419304 -97.26725,26.478905 -97.278549,26.539963 -97.301132,26.601023</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Texas</topp:STATE_NAME><topp:STATE_FIPS>48</topp:STATE_FIPS><topp:SUB_REGION>W S Cen</topp:SUB_REGION><topp:STATE_ABBR>TX</topp:STATE_ABBR><topp:LAND_KM>688219.07</topp:LAND_KM><topp:WATER_KM>17337.549</topp:WATER_KM><topp:PERSONS>1.712202E7</topp:PERSONS><topp:FAMILIES>4377106.0</topp:FAMILIES><topp:HOUSHOLD>6115966.0</topp:HOUSHOLD><topp:MALE>8433346.00000001</topp:MALE><topp:FEMALE>8688674.0</topp:FEMALE><topp:WORKERS>6192585.0</topp:WORKERS><topp:DRVALONE>5860490.0</topp:DRVALONE><topp:CARPOOL>1142908.0</topp:CARPOOL><topp:PUBTRANS>168814.0</topp:PUBTRANS><topp:EMPLOYED>7687338.0</topp:EMPLOYED><topp:UNEMPLOY>590269.0</topp:UNEMPLOY><topp:SERVICE>2139266.0</topp:SERVICE><topp:MANUAL>1042397.0</topp:MANUAL><topp:P_MALE>0.493</topp:P_MALE><topp:P_FEMALE>0.507</topp:P_FEMALE><topp:SAMP_POP>2487642.0</topp:SAMP_POP></topp:states></gml:featureMember></wfs:FeatureCollection></wps:ComplexData>
+</wps:Data>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/ijson_o.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/ijson_o.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/ijson_o.xml	(revision 672)
@@ -0,0 +1,19 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Data>
+<wps:ComplexData mimeType="application/json">{"type":"Polygon","coordinates":[[[-102.036758,36.988972],[-106.860657,36.989491],[-109.047821,36.996643],[-109.055199,38.24493],[-109.052864,39.518196],[-109.050591,40.210545],[-109.047638,40.998474],[-107.918037,41.00341],[-104.051201,41.003227],[-102.620789,41.000225],[-102.047279,40.998077],[-102.04557,40.697323],[-102.036758,36.988972]]]}</wps:ComplexData>
+</wps:Data>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o.xml	(revision 672)
@@ -0,0 +1,17 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows?SERVICE=WFS&amp;REQUEST=GetFeature&amp;VERSION=1.0.0&amp;typename=topp:states&amp;SRS=EPSG:4326&amp;FeatureID=states.15" />
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o_async.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o_async.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_o_async.xml	(revision 672)
@@ -0,0 +1,17 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows?SERVICE=WFS&amp;REQUEST=GetFeature&amp;VERSION=1.0.0&amp;typename=topp:states&amp;SRS=EPSG:4326&amp;FeatureID=states.15" />
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument storeExecuteResponse="true" status="true">
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or.xml	(revision 672)
@@ -0,0 +1,17 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows?SERVICE=WFS&amp;REQUEST=GetFeature&amp;VERSION=1.0.0&amp;typename=topp:states&amp;SRS=EPSG:4326&amp;FeatureID=states.15" />
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output asReference="true">
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or_async.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or_async.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/ir_or_async.xml	(revision 672)
@@ -0,0 +1,17 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows?SERVICE=WFS&amp;REQUEST=GetFeature&amp;VERSION=1.0.0&amp;typename=topp:states&amp;SRS=EPSG:4326&amp;FeatureID=states.15" />
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument storeExecuteResponse="true" status="true">
+<wps:Output asReference="true">
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o.xml	(revision 672)
@@ -0,0 +1,22 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows" method="POST">
+<wps:Header key="Content-type" value="text/xml" />
+<wps:Body>
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" maxFeatures="10" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Query typeName="states" srsName="EPSG:4326"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName><gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>-98.417969 29.498046625</gml:lowerCorner><gml:upperCorner>-97.53906275 30.376952875</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter></wfs:Query></wfs:GetFeature>
+</wps:Body>
+</wps:Reference>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o_async.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o_async.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_o_async.xml	(revision 672)
@@ -0,0 +1,22 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows" method="POST">
+<wps:Header key="Content-type" value="text/xml" />
+<wps:Body>
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" maxFeatures="10" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Query typeName="states" srsName="EPSG:4326"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName><gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>-98.417969 29.498046625</gml:lowerCorner><gml:upperCorner>-97.53906275 30.376952875</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter></wfs:Query></wfs:GetFeature>
+</wps:Body>
+</wps:Reference>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument storeExecuteResponse="true" status="true">
+<wps:Output>
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or.xml	(revision 672)
@@ -0,0 +1,22 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows" method="POST">
+<wps:Header key="Content-type" value="text/xml" />
+<wps:Body>
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" maxFeatures="10" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Query typeName="states" srsName="EPSG:4326"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName><gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>-98.417969 29.498046625</gml:lowerCorner><gml:upperCorner>-97.53906275 30.376952875</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter></wfs:Query></wfs:GetFeature>
+</wps:Body>
+</wps:Reference>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument>
+<wps:Output asReference="true">
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or_async.xml
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or_async.xml	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/requests/irb_or_async.xml	(revision 672)
@@ -0,0 +1,22 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsExecute_request.xsd">
+<ows:Identifier>ServiceName</ows:Identifier>
+<wps:DataInputs>
+<wps:Input>
+<ows:Identifier>InputPolygon</ows:Identifier>
+<ows:Title>Playground area</ows:Title>
+<wps:Reference xlink:href="http://www.zoo-project.org:8082/geoserver/ows" method="POST">
+<wps:Header key="Content-type" value="text/xml" />
+<wps:Body>
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" maxFeatures="10" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Query typeName="states" srsName="EPSG:4326"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName><gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>-98.417969 29.498046625</gml:lowerCorner><gml:upperCorner>-97.53906275 30.376952875</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter></wfs:Query></wfs:GetFeature>
+</wps:Body>
+</wps:Reference>
+</wps:Input>
+</wps:DataInputs>
+<wps:ResponseForm>
+<wps:ResponseDocument storeExecuteResponse="true" status="true">
+<wps:Output asReference="true">
+<ows:Identifier>Result</ows:Identifier>
+</wps:Output>
+</wps:ResponseDocument>
+</wps:ResponseForm>
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/testing/run.sh
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/testing/run.sh	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/testing/run.sh	(revision 672)
@@ -0,0 +1,255 @@
+#!/bin/bash
+
+Usage=$(cat <<EOF
+Please use the following syntaxe:
+
+  ./run.sh <WPSInstance> <ServiceName> <Request>
+
+where <WPSInstance> should be the url to a WPS Server, <ServiceName> should 
+be the service name you want to run tests with (you can use multiple service 
+names, use quote and seperate them using space), <Request> should contain the 
+requests you want to use (you can use more than one at a time).
+
+For instance to test the Buffer service on a localhost WPS server, use the 
+following command:
+
+  ./run.sh http://localhost/cgi-bin/zoo_loader.cgi Buffer "GetCapabilities DescribeProcess Execute"
+
+EOF
+)
+
+if [ -z "$1" ] || [ -z "$2" ]; then
+    echo "$Usage"
+    exit
+fi
+
+WPSInstance=$1
+ServiceName=$2
+NBRequests=1000
+NBConcurrents=50
+pstat=0
+
+iter=0
+
+function testPostRequests {
+#
+# Tests for Execute using POST requests
+#
+    for i in $1; 
+    do
+	cat requests/${i}.xml | sed "s:ServiceName:${ServiceName}:g;s:InputName:$(cat tmp/inputName.txt):g" > tmp/${i}1.xml
+	if [ -z "$(echo $i | grep async)" ]; then
+	    postRequest "${WPSInstance}" "tmp/outputE${i}.xml" "Execute" "tmp/${i}1.xml"
+	else
+	    postRequest "${WPSInstance}" "tmp/outputE${i}.xml" "Execute" "tmp/${i}1.xml" "async"
+	fi
+	echo ""
+    done
+
+}
+
+function plotStat {
+    echo " **"
+    echo " * Plot statistics ..."
+    echo " **"
+    cp run.tsv tmp/run$1.tsv
+    sed "s:\[image\]:$2:g;s:\[file\]:$3:g" -i tmp/run$1.tsv
+    gnuplot tmp/run$1.tsv
+    cp run1.tsv tmp/run1$1.tsv
+    sed "s:\[image\]:$(echo $2 | sed "s:.jpg:1.jpg:g"):g;s:\[file\]:$3:g" -i tmp/run1$1.tsv
+    gnuplot tmp/run1$1.tsv
+}
+
+
+function kvpRequest {
+    echo " **"
+    echo " <h1> Simple KVP request start on $(date) </h1>"
+    echo " <a href='$1'>$1</a>"
+    
+    RESP=$(curl -v -o "$2" "$1" 2> tmp/temp.log; grep "< HTTP" tmp/temp.log | cut -d' ' -f3)
+    if [ "${3}" == "owsExceptionReport" ]; then
+	echo " *********************************"
+	if [ "$RESP" ==	"200" ]; then
+	    echo " ! Invalid response code ($RESP)"
+	else
+	    echo " * Valid response code ($RESP)"
+	fi
+	echo " *********************************"
+	echo " * Checking for ${3} response XML validity..."
+    	echo " * Schema: [http://schemas.opengis.net/ows/1.1.0/${3}.xsd]"
+	echo " *********************************"
+	xmllint --noout --schema http://schemas.opengis.net/ows/1.1.0/${3}.xsd "$2" 2> tmp/res${iter}.txt
+	echo " *********************************"
+	echo "Verifying that the missing / wrong argument was referenced in locator and the exceptionCode take the corresponding value ..."
+	echo -n " *********************************"
+	xsltproc ./extractExceptionInfo.xsl "$2"
+	echo " *********************************"
+    else
+	if [ "$RESP" ==	"200" ]; then
+	    echo " * Valid response code ($RESP)"
+	else
+	    echo " ! Invalid response code ($RESP)"
+	fi
+	echo " * Checking for ${3} response XML validity..."
+	echo " * Schema: [http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd]"
+	xmllint --noout --schema http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd "$2" 2> tmp/res${iter}.txt
+	v="$(cat tmp/res${iter}.txt | grep validates)"
+	echo ""
+    fi
+    echo " **"
+    echo " * Sending $NBRequests ${3} requests starting on $(date) ..."
+    echo " **"
+    ab -g tmp/stat${3}${iter}.plot -e tmp/stat${3}${iter}.txt -n "$NBRequests" -c "$NBConcurrents" "$1"
+    if [ "$pstat" -eq 1 ]; then
+	plotStat ${iter} tmp/stat${3}${iter}.jpg tmp/stat${3}${iter}.plot
+    fi
+    iter=$(expr $iter + 1)
+    echo " ** Ending on $(date)"
+}
+
+function postRequest {
+    echo " **"
+    echo " * Simple POST request started on $(date)"
+    echo " **"
+    echo " * Checking for ${3} request XML validity..."
+    echo " * Schema: http://schemas.opengis.net/wps/1.0.0/wps${3}_request.xsd"
+    echo " *********************************"
+    xmllint --noout --schema http://schemas.opengis.net/wps/1.0.0/wps${3}_request.xsd "$4" 
+    echo " *********************************"
+    curl -H "Content-type: text/xml" -d@"$4" -o "$2" "$1"
+    echo " * Checking for ${3} response XML validity on $(date) ..."
+    echo " * Schema: http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd"
+    echo " *********************************"
+    xmllint --noout --schema http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd "$2"
+    echo " *********************************"
+    if [ -z "$5" ]; then
+	echo ""
+    else
+	echo " * Schema: http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd"
+	echo " *********************************"
+	xmllint --noout --schema http://schemas.opengis.net/wps/1.0.0/wps${3}_response.xsd "$(xsltproc ./extractStatusLocation.xsl $2)"
+	echo " *********************************"
+    fi
+    echo " * Sending $NBRequests ${3} XML requests on $(date) ..."
+    ab -g tmp/stat${3}${iter}.plot -e tmp/stat${3}${iter}.txt -T "text/xml" -p "$4" -n "$NBRequests" -c "$NBConcurrents" "$1"
+    if [ "$pstat" -eq 1 ]; then
+	plotStat ${iter} tmp/stat${3}${iter}.jpg tmp/stat${3}${iter}.plot
+    fi
+    iter=$(expr $iter + 1)
+    echo " ** Ending on $(date)"
+}
+
+function kvpRequestWrite {
+    suffix=""
+    cnt=0
+    cnt0=0
+    for i in $2; do
+	if [ ! $1 -eq $cnt0 ]; then
+	    if [ $cnt -gt 0 ]; then
+		suffix="$suffix&$(echo $i | sed 's:\"::g')"
+	    else
+		suffix="$(echo $i | sed 's:\"::g')"
+	    fi
+	    cnt=$(expr $cnt + 1)
+	fi
+	cnt0=$(expr $cnt0 + 1)
+    done
+    echo $suffix
+}
+
+function kvpWrongRequestWrite {
+    suffix=""
+    cnt=0
+    cnt0=0
+    for i in $2; do
+	if [ ! $1 -eq $cnt0 ]; then
+	    if [ $cnt -gt 0 ]; then
+		suffix="$suffix&$(echo $i | sed 's:\"::g')"
+	    else
+		suffix="$(echo $i | sed 's:\"::g')"
+	    fi
+	    cnt=$(expr $cnt + 1)
+	else
+	    cnt1=0
+	    for j in $3; do 
+		if [ $cnt1 -eq $1 ]; then
+		    suffix="$suffix&$(echo $j | sed 's:\"::g')"
+		fi
+		cnt1=$(expr $cnt1 + 1)
+	    done
+	fi
+	cnt0=$(expr $cnt0 + 1)
+    done
+    echo $suffix
+}
+
+for i in $3; do
+    if [ "$i" == "GetCapabilities" ]; then
+#
+# Tests for GetCapabilities using KVP (including wrong requests) and POST requests
+#
+	kvpRequest "${WPSInstance}?REQUEST=GetCapabilities&SERVICE=WPS" "tmp/outputGC1.xml" "GetCapabilities"
+
+	params='"request=GetCapabilities" "service=WPS"'
+
+	suffix=$(kvpRequestWrite -1 "$params")
+	kvpRequest "${WPSInstance}?$suffix" "tmp/outputGC2.xml" "GetCapabilities"
+
+	for j in 0 1; do 
+	    suffix=$(kvpRequestWrite $j "$params")
+	    kvpRequest "${WPSInstance}?$suffix" "tmp/outputGC$(expr $j + 3).xml" "owsExceptionReport"
+	done
+
+	paramsw='"request=GetCapabilitie" "service=WXS"'
+	for j in 0 1; do 
+	    suffix=$(kvpWrongRequestWrite $j "$params" "$paramsw")
+	    kvpRequest "${WPSInstance}?$suffix" "tmp/outputGC$(expr $j + 5).xml" "owsExceptionReport"
+	done
+
+	echo "Check if differences between upper case and lower case parameter names"
+	diff -ru tmp/outputGC1.xml tmp/outputGC2.xml 
+
+	echo ""
+
+	curl -o tmp/10_wpsGetCapabilities_request.xml http://schemas.opengis.net/wps/1.0.0/examples/10_wpsGetCapabilities_request.xml
+	postRequest "${WPSInstance}" "tmp/outputGCp.xml" "GetCapabilities" "tmp/10_wpsGetCapabilities_request.xml"
+	echo ""
+    fi
+    if [ "$i" == "DescribeProcess" ]; then
+#
+# Tests for DescribeProcess using KVP and POST requests
+#
+	kvpRequest "${WPSInstance}?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=ALL" "tmp/outputDPall.xml" "DescribeProcess"
+
+	params='"request=DescribeProcess" "service=WPS" "version=1.0.0" "Identifier='${ServiceName}'"'
+
+	suffix=$(kvpRequestWrite -1 "$params")
+	kvpRequest "${WPSInstance}?$suffix" "tmp/outputDPb1.xml" "DescribeProcess"
+	
+	for j in 0 1 2 3; do 
+	    suffix=$(kvpRequestWrite $j "$params")
+	    kvpRequest "${WPSInstance}?$suffix" "tmp/outputDPb$(expr $j + 2).xml" "owsExceptionReport"
+	done
+
+	paramsw='"request=DescribeProces" "service=WXS" "version=1.2.0" "Identifier=Undefined"'
+	
+	for j in 0 1 2 3; do 
+	    suffix=$(kvpWrongRequestWrite $j "$params")
+	    kvpRequest "${WPSInstance}?$suffix" "tmp/outputDPb$(expr $j + 6).xml" "owsExceptionReport"
+	done
+
+
+	cat requests/dp.xml | sed "s:ServiceName:${ServiceName}:g" > tmp/dp1.xml
+	postRequest "${WPSInstance}" "tmp/outputDPp.xml" "DescribeProcess" "tmp/dp1.xml"
+	xsltproc extractInputs.xsl tmp/outputDPp.xml > tmp/inputName.txt
+	echo "" 
+    fi
+    if [ "$i" == "ExecuteSync" ]; then
+	testPostRequests "ijson_o igml_o ir_o ir_or irb_o irb_or"
+	echo "" 
+    fi
+    if [ "$i" == "ExecuteAsync" ]; then	
+	testPostRequests "ir_o_async ir_or_async irb_o_async irb_or_async"
+	echo "" 
+    fi
+done
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/Makefile	(revision 672)
@@ -0,0 +1,41 @@
+OS:=$(shell uname -s)
+CPU:=$(shell uname -m)
+ifeq ($(OS),Darwin)
+	MACOS_CFLAGS=-arch x86_64
+	LIBS= -L./ -lcgic /usr/lib/libfcgi.dylib
+else
+ifeq ($(CPU),x86_64)
+	LIBS= -L./ -lcgic /usr/lib64/libfcgi.so
+else
+	LIBS= -L./ -lcgic /usr/lib/libfcgi.a
+endif
+endif
+CFLAGS=-g -Wall ${MACOS_CFLAGS}
+CC=gcc
+AR=ar
+RANLIB=ranlib
+
+all: libcgic.a cgictest.cgi capture
+
+install: libcgic.a
+	mkdir -p ../../dist/lib
+	cp libcgic.a  ../../dist/lib
+	cp cgic.h  ../../dist/include
+	@echo libcgic.a is in  ../../dist/lib/ and cgic.h is in  ../../dist/include/
+
+libcgic.a: cgic.o cgic.h
+	rm -f libcgic.a
+	$(AR) rc libcgic.a cgic.o
+	$(RANLIB) libcgic.a
+
+#mingw32 and cygwin users: replace .cgi with .exe
+
+cgictest.cgi: cgictest.o libcgic.a
+	gcc cgictest.o -o cgictest.cgi ${LIBS}
+
+capture: capture.o libcgic.a
+	gcc capture.o -o capture ${LIBS}
+
+clean:
+	rm -f *.o *.a cgictest.cgi capture
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/capture.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/capture.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/capture.c	(revision 672)
@@ -0,0 +1,12 @@
+#include "cgic.h"
+
+int cgiMain() {
+	cgiWriteEnvironment("/tmp/capcgi.dat");
+	cgiHeaderContentType("text/html");
+	fprintf(cgiOut, "<title>Captured</title>\n");
+	fprintf(cgiOut, "<h1>Captured</h1>\n");
+	fprintf(cgiOut, "Your form submission was captured for use in\n");
+	fprintf(cgiOut, "debugging CGI code.\n");
+	return 0;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.c	(revision 672)
@@ -0,0 +1,2556 @@
+/* cgicTempDir is the only setting you are likely to need
+	to change in this file. */
+
+/* Used only in Unix environments, in conjunction with mkstemp(). 
+	Elsewhere (Windows), temporary files go where the tmpnam() 
+	function suggests. If this behavior does not work for you, 
+	modify the getTempFileName() function to suit your needs. */
+
+#define cgicTempDir "/tmp"
+
+#include <fcgi_stdio.h>
+#if CGICDEBUG
+#define CGICDEBUGSTART \
+	{ \
+		FILE *dout; \
+		dout = fopen("/home/boutell/public_html/debug", "a"); \
+	
+#define CGICDEBUGEND \
+		fclose(dout); \
+	}
+#else /* CGICDEBUG */
+#define CGICDEBUGSTART
+#define CGICDEBUGEND
+#endif /* CGICDEBUG */
+
+#ifdef WIN32
+#define _INC_STDIO
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+#include <io.h>
+
+/* cgic 2.01 */
+#include <fcntl.h>
+
+#else
+#include <unistd.h>
+#endif /* WIN32 */
+#include "cgic.h"
+
+#define cgiStrEq(a, b) (!strcmp((a), (b)))
+
+char *cgiServerSoftware;
+char *cgiServerName;
+char *cgiGatewayInterface;
+char *cgiServerProtocol;
+char *cgiServerPort;
+char *cgiRequestMethod;
+char *cgiPathInfo;
+char *cgiPathTranslated;
+char *cgiScriptName;
+char *cgiQueryString;
+char *cgiRemoteHost;
+char *cgiRemoteAddr;
+char *cgiAuthType;
+char *cgiRemoteUser;
+char *cgiRemoteIdent;
+char cgiContentTypeData[1024];
+char *cgiContentType = cgiContentTypeData;
+char *cgiMultipartBoundary;
+char *cgiCookie;
+int cgiContentLength;
+char *cgiAccept;
+char *cgiUserAgent;
+char *cgiReferrer;
+char *cgiSid;
+
+FILE *cgiIn;
+FILE *cgiOut;
+
+/* True if CGI environment was restored from a file. */
+static int cgiRestored = 0;
+static int cgiTreatUrlEncoding;
+
+static void cgiGetenv(char **s, char *var);
+
+typedef enum {
+	cgiParseSuccess,
+	cgiParseMemory,
+	cgiParseIO
+} cgiParseResultType;
+
+/* One form entry, consisting of an attribute-value pair,
+	and an optional filename and content type. All of
+	these are guaranteed to be valid null-terminated strings,
+	which will be of length zero in the event that the
+	field is not present, with the exception of tfileName
+	which will be null when 'in' is null. DO NOT MODIFY THESE 
+	VALUES. Make local copies if modifications are desired. */
+
+typedef struct cgiFormEntryStruct {
+        char *attr;
+	/* value is populated for regular form fields only.
+		For file uploads, it points to an empty string, and file
+		upload data should be read from the file tfileName. */ 
+	char *value;
+	/* When fileName is not an empty string, tfileName is not null,
+		and 'value' points to an empty string. */
+	/* Valid for both files and regular fields; does not include
+		terminating null of regular fields. */
+	int valueLength;
+	char *fileName;	
+	char *contentType;
+	/* Temporary file name for working storage of file uploads. */
+	char *tfileName;
+        struct cgiFormEntryStruct *next;
+} cgiFormEntry;
+
+/* The first form entry. */
+static cgiFormEntry *cgiFormEntryFirst;
+
+static cgiParseResultType cgiParseGetFormInput();
+static cgiParseResultType cgiParsePostFormInput();
+static cgiParseResultType cgiParsePostMultipartInput();
+static cgiParseResultType cgiParseFormInput(char *data, int length);
+static void cgiSetupConstants();
+static void cgiFreeResources();
+static int cgiStrEqNc(char *s1, char *s2);
+static int cgiStrBeginsNc(char *s1, char *s2);
+
+//int cgiMain_init() {}
+
+
+int main(int argc, char *argv[]) {
+	int result;
+	char *cgiContentLengthString;
+	char *e;
+	while (FCGI_Accept() >= 0) {
+	cgiSetupConstants();
+	cgiGetenv(&cgiServerSoftware, "SERVER_SOFTWARE");
+	cgiGetenv(&cgiServerName, "SERVER_NAME");
+	cgiGetenv(&cgiGatewayInterface, "GATEWAY_INTERFACE");
+	cgiGetenv(&cgiServerProtocol, "SERVER_PROTOCOL");
+	cgiGetenv(&cgiServerPort, "SERVER_PORT");
+	cgiGetenv(&cgiRequestMethod, "REQUEST_METHOD");
+	if(strcmp(cgiRequestMethod,"")==0 && argc>=1)
+		cgiRequestMethod="GET";
+	cgiGetenv(&cgiPathInfo, "PATH_INFO");
+	cgiGetenv(&cgiPathTranslated, "PATH_TRANSLATED");
+	cgiGetenv(&cgiScriptName, "SCRIPT_NAME");
+	cgiGetenv(&cgiQueryString, "QUERY_STRING");
+	cgiSid=NULL;
+	if(cgiQueryString!=NULL && argc>=2){
+		cgiQueryString=argv[1];
+		if(argc>2){
+		  cgiSid=argv[2];
+		}
+	}
+	cgiGetenv(&cgiRemoteHost, "REMOTE_HOST");
+	cgiGetenv(&cgiRemoteAddr, "REMOTE_ADDR");
+	cgiGetenv(&cgiAuthType, "AUTH_TYPE");
+	cgiGetenv(&cgiRemoteUser, "REMOTE_USER");
+	cgiGetenv(&cgiRemoteIdent, "REMOTE_IDENT");
+	/* 2.0: the content type string needs to be parsed and modified, so
+		copy it to a buffer. */
+	e = getenv("CONTENT_TYPE");
+	if (e) {
+		if (strlen(e) < sizeof(cgiContentTypeData)) {
+			strcpy(cgiContentType, e);
+		} else {
+			/* Truncate safely in the event of what is almost certainly
+				a hack attempt */
+			strncpy(cgiContentType, e, sizeof(cgiContentTypeData));
+			cgiContentType[sizeof(cgiContentTypeData) - 1] = '\0';
+		}
+	} else {
+		cgiContentType[0] = '\0';
+	}
+	/* Never null */
+	cgiMultipartBoundary = "";
+	/* 2.0: parse semicolon-separated additional parameters of the
+		content type. The one we're interested in is 'boundary'.
+		We discard the rest to make cgiContentType more useful
+		to the typical programmer. */
+	if (strchr(cgiContentType, ';')) {
+		char *sat = strchr(cgiContentType, ';');
+		while (sat) {
+			*sat = '\0';
+			sat++;
+			while (isspace(*sat)) {
+				sat++;
+			}	
+			if (cgiStrBeginsNc(sat, "boundary=")) {
+				char *s;
+				cgiMultipartBoundary = sat + strlen("boundary=");
+				s = cgiMultipartBoundary;
+				while ((*s) && (!isspace(*s))) {
+					s++;
+				}
+				*s = '\0';
+				break;
+			} else {
+				sat = strchr(sat, ';');
+			} 	
+		}
+	}
+	cgiGetenv(&cgiContentLengthString, "CONTENT_LENGTH");
+	cgiContentLength = atoi(cgiContentLengthString);	
+	if(cgiContentLength==0 && argc>=2){
+		cgiContentLength=strlen(argv[1]);
+	}
+	cgiGetenv(&cgiAccept, "HTTP_ACCEPT");
+	cgiGetenv(&cgiUserAgent, "HTTP_USER_AGENT");
+	cgiGetenv(&cgiReferrer, "HTTP_REFERER");
+	cgiGetenv(&cgiCookie, "HTTP_COOKIE");
+#ifdef CGICDEBUG
+	CGICDEBUGSTART
+	fprintf(dout, "%d\n", cgiContentLength);
+	fprintf(dout, "%s\n", cgiRequestMethod);
+	fprintf(dout, "%s\n", cgiContentType);
+	CGICDEBUGEND	
+#endif /* CGICDEBUG */
+#ifdef WIN32
+	/* 1.07: Must set stdin and stdout to binary mode */
+	/* 2.0: this is particularly crucial now and must not be removed */
+	_setmode( FCGI_fileno( stdin ), _O_BINARY );
+	_setmode( FCGI_fileno( stdout ), _O_BINARY );
+#endif /* WIN32 */
+	cgiFormEntryFirst = 0;
+	cgiIn = FCGI_stdin;
+	cgiOut = FCGI_stdout;
+	cgiRestored = 0;
+
+
+	/* These five lines keep compilers from
+		producing warnings that argc and argv
+		are unused. They have no actual function. */
+	if (argc) {
+		if (argv[0]) {
+			cgiRestored = 0;
+		}
+	}	
+
+
+	cgiTreatUrlEncoding=0;
+	if (cgiStrEqNc(cgiRequestMethod, "post")) {
+		cgiTreatUrlEncoding=0;
+#ifdef CGICDEBUG
+		CGICDEBUGSTART
+		fprintf(dout, "POST recognized\n");
+		CGICDEBUGEND
+#endif /* CGICDEBUG */
+		if (cgiStrEqNc(cgiContentType, "application/x-www-form-urlencoded")) {	
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "Calling PostFormInput\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+			if (cgiParsePostFormInput() != cgiParseSuccess) {
+#ifdef CGICDEBUG
+				CGICDEBUGSTART
+				fprintf(dout, "PostFormInput failed\n");
+				CGICDEBUGEND	
+#endif /* CGICDEBUG */
+				cgiFreeResources();
+				return -1;
+			}	
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "PostFormInput succeeded\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+		} else if (cgiStrEqNc(cgiContentType, "multipart/form-data")) {
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "Calling PostMultipartInput\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+			if (cgiParsePostMultipartInput() != cgiParseSuccess) {
+#ifdef CGICDEBUG
+				CGICDEBUGSTART
+				fprintf(dout, "PostMultipartInput failed\n");
+				CGICDEBUGEND	
+#endif /* CGICDEBUG */
+				cgiFreeResources();
+				return -1;
+			}	
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "PostMultipartInput succeeded\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+		}
+	} else if (cgiStrEqNc(cgiRequestMethod, "get")) {	
+		/* The spec says this should be taken care of by
+			the server, but... it isn't */
+		cgiContentLength = strlen(cgiQueryString);
+		if (cgiParseGetFormInput() != cgiParseSuccess) {
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "GetFormInput failed\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+			cgiFreeResources();
+			return -1;
+		} else {	
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "GetFormInput succeeded\n");
+			CGICDEBUGEND	
+#endif /* CGICDEBUG */
+		}
+	}
+	result = cgiMain();
+	cgiFreeResources();
+	}
+	FCGI_Finish();
+	return result;
+}
+
+static void cgiGetenv(char **s, char *var){
+	*s = getenv(var);
+	if (!(*s)) {
+		*s = "";
+	}
+}
+
+static cgiParseResultType cgiParsePostFormInput() {
+	char *input;
+	cgiParseResultType result;
+	if (!cgiContentLength) {
+		return cgiParseSuccess;
+	}
+	input = (char *) malloc(cgiContentLength);
+	if (!input) {
+		return cgiParseMemory;	
+	}
+	if (((int) fread(input, 1, cgiContentLength, cgiIn)) 
+		!= cgiContentLength) 
+	{
+		return cgiParseIO;
+	}	
+	result = cgiParseFormInput(input, cgiContentLength);
+	free(input);
+	return result;
+}
+
+/* 2.0: A virtual datastream supporting putback of 
+	enough characters to handle multipart boundaries easily.
+	A simple memset(&mp, 0, sizeof(mp)) is suitable initialization. */
+
+typedef struct {
+	/* Buffer for putting characters back */
+	char putback[1024];	
+	/* Position in putback from which next character will be read.
+		If readPos == writePos, then next character should
+		come from cgiIn. */
+	int readPos;
+	/* Position in putback to which next character will be put back.
+		If writePos catches up to readPos, as opposed to the other
+		way around, the stream no longer functions properly.
+		Calling code must guarantee that no more than 
+		sizeof(putback) bytes are put back at any given time. */
+	int writePos;
+	/* Offset in the virtual datastream; can be compared
+		to cgiContentLength */
+	int offset;
+} mpStream, *mpStreamPtr;
+
+int mpRead(mpStreamPtr mpp, char *buffer, int len)
+{
+	int ilen = len;
+	int got = 0;
+	while (len) {
+		if (mpp->readPos != mpp->writePos) {
+			*buffer++ = mpp->putback[mpp->readPos++];
+			mpp->readPos %= sizeof(mpp->putback);
+			got++;
+			len--;
+		} else {
+			break;
+		}	
+	}
+	/* Refuse to read past the declared length in order to
+		avoid deadlock */
+	if (len > (cgiContentLength - mpp->offset)) {
+		len = cgiContentLength - mpp->offset;
+	}
+	if (len) {
+		int fgot = fread(buffer, 1, len, cgiIn);
+		if (fgot >= 0) {
+			mpp->offset += (got + fgot);
+			return got + fgot;
+		} else if (got > 0) {
+			mpp->offset += got;
+			return got;
+		} else {
+			/* EOF or error */
+			return fgot;
+		}
+	} else if (got) {
+		return got;
+	} else if (ilen) {	
+		return EOF;
+	} else {
+		/* 2.01 */
+		return 0;
+	}
+}
+
+void mpPutBack(mpStreamPtr mpp, char *data, int len)
+{
+	mpp->offset -= len;
+	while (len) {
+		mpp->putback[mpp->writePos++] = *data++;
+		mpp->writePos %= sizeof(mpp->putback);
+		len--;
+	}
+}
+
+/* This function copies the body to outf if it is not null, otherwise to
+	a newly allocated character buffer at *outP, which will be null
+	terminated; if both outf and outP are null the body is not stored.
+	If bodyLengthP is not null, the size of the body in bytes is stored
+	to *bodyLengthP, not including any terminating null added to *outP. 
+	If 'first' is nonzero, a preceding newline is not expected before
+	the boundary. If 'first' is zero, a preceding newline is expected.
+	Upon return mpp is positioned after the boundary and its trailing 
+	newline, if any; if the boundary is followed by -- the next two 
+	characters read after this function returns will be --. Upon error, 
+	if outP is not null, *outP is a null pointer; *bodyLengthP 
+	is set to zero. Returns cgiParseSuccess, cgiParseMemory 
+	or cgiParseIO. */
+
+static cgiParseResultType afterNextBoundary(mpStreamPtr mpp,
+	FILE *outf,
+	char **outP,
+	int *bodyLengthP,
+	int first
+	);
+
+static int readHeaderLine(
+	mpStreamPtr mpp,	
+	char *attr,
+	int attrSpace,
+	char *value,
+	int valueSpace);
+
+static void decomposeValue(char *value,
+	char *mvalue, int mvalueSpace,
+	char **argNames,
+	char **argValues,
+	int argValueSpace);
+
+/* tfileName must be 1024 bytes to ensure adequacy on
+	win32 (1024 exceeds the maximum path length and
+	certainly exceeds observed behavior of _tmpnam).
+	May as well also be 1024 bytes on Unix, although actual
+	length is strlen(cgiTempDir) + a short unique pattern. */
+	
+static cgiParseResultType getTempFileName(char *tfileName);
+
+static cgiParseResultType cgiParsePostMultipartInput() {
+	cgiParseResultType result;
+	cgiFormEntry *n = 0, *l = 0;
+	int got;
+	FILE *outf = 0;
+	char *out = 0;
+	char tfileName[1024];
+	mpStream mp;
+	mpStreamPtr mpp = &mp;
+	memset(&mp, 0, sizeof(mp));
+	if (!cgiContentLength) {
+		return cgiParseSuccess;
+	}
+	/* Read first boundary, including trailing newline */
+	result = afterNextBoundary(mpp, 0, 0, 0, 1);
+	if (result == cgiParseIO) {	
+		/* An empty submission is not necessarily an error */
+		return cgiParseSuccess;
+	} else if (result != cgiParseSuccess) {
+		return result;
+	}
+	while (1) {
+		char d[1024];
+		char fvalue[1024];
+		char fname[1024];
+		int bodyLength = 0;
+		char ffileName[1024];
+		char fcontentType[1024];
+		char attr[1024];
+		char value[1024];
+		fvalue[0] = 0;
+		fname[0] = 0;
+		ffileName[0] = 0;
+		fcontentType[0] = 0;
+		out = 0;
+		outf = 0;
+		/* Check for EOF */
+		got = mpRead(mpp, d, 2);
+		if (got < 2) {
+			/* Crude EOF */
+			break;
+		}
+		if ((d[0] == '-') && (d[1] == '-')) {
+			/* Graceful EOF */
+			break;
+		}
+		mpPutBack(mpp, d, 2);
+		/* Read header lines until end of header */
+		while (readHeaderLine(
+				mpp, attr, sizeof(attr), value, sizeof(value))) 
+		{
+			char *argNames[3];
+			char *argValues[2];
+			/* Content-Disposition: form-data; 
+				name="test"; filename="googley.gif" */
+			if (cgiStrEqNc(attr, "Content-Disposition")) {
+				argNames[0] = "name";
+				argNames[1] = "filename";
+				argNames[2] = 0;
+				argValues[0] = fname;
+				argValues[1] = ffileName;
+				decomposeValue(value, 
+					fvalue, sizeof(fvalue),
+					argNames,
+					argValues,
+					1024);	
+			} else if (cgiStrEqNc(attr, "Content-Type")) {
+				argNames[0] = 0;
+				decomposeValue(value, 
+					fcontentType, sizeof(fcontentType),
+					argNames,
+					0,
+					0);
+			}
+		}
+		if (!cgiStrEqNc(fvalue, "form-data")) {
+			/* Not form data */	
+			continue;
+		}
+		/* Body is everything from here until the next 
+			boundary. So, set it aside and move past boundary. 
+			If a filename was submitted as part of the
+			disposition header, store to a temporary file.
+			Otherwise, store to a memory buffer (it is
+			presumably a regular form field). */
+		if (strlen(ffileName)) {
+			if (getTempFileName(tfileName) != cgiParseSuccess) {
+				return cgiParseIO;
+			}	
+			outf = fopen(tfileName, "w+b");
+		} else {
+			outf = 0;
+			tfileName[0] = '\0';
+		}	
+		result = afterNextBoundary(mpp, outf, &out, &bodyLength, 0);
+		if (result != cgiParseSuccess) {
+			/* Lack of a boundary here is an error. */
+			if (outf) {
+				fclose(outf);
+				unlink(tfileName);
+			}
+			if (out) {
+				free(out);
+			}
+			return result;
+		}
+		/* OK, we have a new pair, add it to the list. */
+		n = (cgiFormEntry *) malloc(sizeof(cgiFormEntry));	
+		if (!n) {
+			goto outOfMemory;
+		}
+		memset(n, 0, sizeof(cgiFormEntry));
+		/* 2.01: one of numerous new casts required
+			to please C++ compilers */
+		n->attr = (char *) malloc(strlen(fname) + 1);
+		if (!n->attr) {
+			goto outOfMemory;
+		}
+		strcpy(n->attr, fname);
+		if (out) {
+			n->value = out;
+			out = 0;
+		} else if (outf) {
+			n->value = (char *) malloc(1);
+			if (!n->value) {
+				goto outOfMemory;
+			}
+			n->value[0] = '\0';
+			fclose(outf);
+		}
+		n->valueLength = bodyLength;
+		n->next = 0;
+		if (!l) {
+			cgiFormEntryFirst = n;
+		} else {
+			l->next = n;
+		}
+		n->fileName = (char *) malloc(strlen(ffileName) + 1);
+		if (!n->fileName) {
+			goto outOfMemory;
+		}
+		strcpy(n->fileName, ffileName);
+		n->contentType = (char *) malloc(strlen(fcontentType) + 1);
+		if (!n->contentType) {
+			goto outOfMemory;
+		}
+		strcpy(n->contentType, fcontentType);
+		n->tfileName = (char *) malloc(strlen(tfileName) + 1);
+		if (!n->tfileName) {
+			goto outOfMemory;
+		}
+		strcpy(n->tfileName, tfileName);
+
+		l = n;			
+	}	
+	return cgiParseSuccess;
+outOfMemory:
+	if (n) {
+		if (n->attr) {
+			free(n->attr);
+		}
+		if (n->value) {
+			free(n->value);
+		}
+		if (n->fileName) {
+			free(n->fileName);
+		}
+		if (n->tfileName) {
+			free(n->tfileName);
+		}
+		if (n->contentType) {
+			free(n->contentType);
+		}
+		free(n);
+	}
+	if (out) {
+		free(out);
+	}
+	if (outf) {
+		fclose(outf);
+		unlink(tfileName);
+	}
+	return cgiParseMemory;
+}
+
+static cgiParseResultType getTempFileName(char *tfileName)
+{
+#ifndef WIN32
+	/* Unix. Use the robust 'mkstemp' function to create
+		a temporary file that is truly unique, with
+		permissions that are truly safe. The 
+		fopen-for-write destroys any bogus information
+		written by potential hackers during the brief
+		window between the file's creation and the
+		chmod call (glibc 2.0.6 and lower might
+		otherwise have allowed this). */
+	int outfd; 
+	strcpy(tfileName, cgicTempDir "/cgicXXXXXX");
+	outfd = mkstemp(tfileName);
+	if (outfd == -1) {
+		return cgiParseIO;
+	}
+	close(outfd);
+	/* Fix the permissions */
+	if (chmod(tfileName, 0600) != 0) {
+		unlink(tfileName);
+		return cgiParseIO;
+	}
+#else
+	/* Non-Unix. Do what we can. */
+	if (!tmpnam(tfileName)) {
+		return cgiParseIO;
+	}
+#endif
+	return cgiParseSuccess;
+}
+
+
+#define APPEND(string, char) \
+	{ \
+		if ((string##Len + 1) < string##Space) { \
+			string[string##Len++] = (char); \
+		} \
+	}
+
+#define RAPPEND(string, ch) \
+	{ \
+		if ((string##Len + 1) == string##Space)  { \
+			char *sold = string; \
+			string##Space *= 2; \
+			string = (char *) realloc(string, string##Space); \
+			if (!string) { \
+				string = sold; \
+				goto outOfMemory; \
+			} \
+		} \
+		string[string##Len++] = (ch); \
+	}
+		
+#define BAPPEND(ch) \
+	{ \
+		if (outf) { \
+			putc(ch, outf); \
+			outLen++; \
+		} else if (out) { \
+			RAPPEND(out, ch); \
+		} \
+	}
+
+cgiParseResultType afterNextBoundary(mpStreamPtr mpp, FILE *outf, char **outP,
+	int *bodyLengthP, int first)
+{
+	int outLen = 0;
+	int outSpace = 256;
+	char *out = 0;
+	cgiParseResultType result;
+	int boffset;
+	int got;
+	char d[2];	
+	/* This is large enough, because the buffer into which the
+		original boundary string is fetched is shorter by more
+		than four characters due to the space required for
+		the attribute name */
+	char workingBoundaryData[1024];
+	char *workingBoundary = workingBoundaryData;
+	int workingBoundaryLength;
+	if ((!outf) && (outP)) {
+		out = (char *) malloc(outSpace);
+		if (!out) {
+			goto outOfMemory;
+		}
+	}
+	boffset = 0;
+	sprintf(workingBoundaryData, "\r\n--%s", cgiMultipartBoundary);
+	if (first) {
+		workingBoundary = workingBoundaryData + 2;
+	}
+	workingBoundaryLength = strlen(workingBoundary);
+	while (1) {
+		got = mpRead(mpp, d, 1);
+		if (got != 1) {
+			/* 2.01: cgiParseIO, not cgiFormIO */
+			result = cgiParseIO;
+			goto error;
+		}
+		if (d[0] == workingBoundary[boffset]) {
+			/* We matched the next byte of the boundary.
+				Keep track of our progress into the
+				boundary and don't emit anything. */
+			boffset++;
+			if (boffset == workingBoundaryLength) {
+				break;
+			} 
+		} else if (boffset > 0) {
+			/* We matched part, but not all, of the
+				boundary. Now we have to be careful:
+				put back all except the first
+				character and try again. The 
+				real boundary could begin in the
+				middle of a false match. We can
+				emit the first character only so far. */
+			BAPPEND(workingBoundary[0]);
+			mpPutBack(mpp, 
+				workingBoundary + 1, boffset - 1);
+			mpPutBack(mpp, d, 1);
+			boffset = 0;
+		} else {		
+			/* Not presently in the middle of a boundary
+				match; just emit the character. */
+			BAPPEND(d[0]);
+		}	
+	}
+	/* Read trailing newline or -- EOF marker. A literal EOF here
+		would be an error in the input stream. */
+	got = mpRead(mpp, d, 2);
+	if (got != 2) {
+		result = cgiParseIO;
+		goto error;
+	}	
+	if ((d[0] == '\r') && (d[1] == '\n')) {
+		/* OK, EOL */
+	} else if (d[0] == '-') {
+		/* Probably EOF, but we check for
+			that later */
+		mpPutBack(mpp, d, 2);
+	}	
+	if (out && outSpace) {
+		char *oout = out;
+		out[outLen] = '\0';
+		out = (char *) realloc(out, outLen + 1);
+		if (!out) {
+			/* Surprising if it happens; and not fatal! We were
+				just trying to give some space back. We can
+				keep it if we have to. */
+			out = oout;
+		}
+		*outP = out;
+	}
+	if (bodyLengthP) {
+		*bodyLengthP = outLen;
+	}
+	return cgiParseSuccess;
+outOfMemory:
+	result = cgiParseMemory;
+	if (outP) {
+		if (out) {
+			free(out);
+		}
+		*outP = '\0';	
+	}
+error:
+	if (bodyLengthP) {
+		*bodyLengthP = 0;
+	}
+	if (out) {
+		free(out);
+	}
+	if (outP) {
+		*outP = 0;	
+	}
+	return result;
+}
+
+static void decomposeValue(char *value,
+	char *mvalue, int mvalueSpace,
+	char **argNames,
+	char **argValues,
+	int argValueSpace)
+{
+	char argName[1024];
+	int argNameSpace = sizeof(argName);
+	int argNameLen = 0;
+	int mvalueLen = 0;
+	char *argValue;
+	int argNum = 0;
+	while (argNames[argNum]) {
+		if (argValueSpace) {
+			argValues[argNum][0] = '\0';
+		}
+		argNum++;
+	}
+	while (isspace(*value)) {
+		value++;
+	}
+	/* Quoted mvalue */
+	if (*value == '\"') {
+		value++;
+		while ((*value) && (*value != '\"')) {
+			APPEND(mvalue, *value);
+			value++;
+		}
+		while ((*value) && (*value != ';')) {
+			value++;
+		}
+	} else {
+		/* Unquoted mvalue */
+		while ((*value) && (*value != ';')) {
+			APPEND(mvalue, *value);
+			value++;
+		}	
+	}	
+	if (mvalueSpace) {
+		mvalue[mvalueLen] = '\0';
+	}
+	while (*value == ';') {
+		int argNum;
+		int argValueLen = 0;
+		/* Skip the ; between parameters */
+		value++;
+		/* Now skip leading whitespace */
+		while ((*value) && (isspace(*value))) { 
+			value++;
+		}
+		/* Now read the parameter name */
+		argNameLen = 0;
+		while ((*value) && (isalnum(*value))) {
+			APPEND(argName, *value);
+			value++;
+		}
+		if (argNameSpace) {
+			argName[argNameLen] = '\0';
+		}
+		while ((*value) && isspace(*value)) {
+			value++;
+		}
+		if (*value != '=') {
+			/* Malformed line */
+			return;	
+		}
+		value++;
+		while ((*value) && isspace(*value)) {
+			value++;
+		}
+		/* Find the parameter in the argument list, if present */
+		argNum = 0;
+		argValue = 0;
+		while (argNames[argNum]) {
+			if (cgiStrEqNc(argName, argNames[argNum])) {
+				argValue = argValues[argNum];
+				break;
+			}
+			argNum++;
+		}		
+		/* Finally, read the parameter value */
+		if (*value == '\"') {
+			value++;
+			while ((*value) && (*value != '\"')) {
+				if (argValue) {
+					APPEND(argValue, *value);
+				}
+				value++;
+			}
+			while ((*value) && (*value != ';')) {
+				value++;
+			}
+		} else {
+			/* Unquoted value */
+			while ((*value) && (*value != ';')) {
+				if (argNames[argNum]) {
+					APPEND(argValue, *value);
+				}
+				value++;
+			}	
+		}	
+		if (argValueSpace) {
+			argValue[argValueLen] = '\0';
+		}
+	}	 	
+}
+
+static int readHeaderLine(
+	mpStreamPtr mpp,
+	char *attr,
+	int attrSpace,
+	char *value,
+	int valueSpace)
+{	
+	int attrLen = 0;
+	int valueLen = 0;
+	int valueFound = 0;
+	while (1) {
+		char d[1];
+		int got = mpRead(mpp, d, 1);
+		if (got != 1) {	
+			return 0;
+		}
+		if (d[0] == '\r') {
+			got = mpRead(mpp, d, 1);
+			if (got == 1) {	
+				if (d[0] == '\n') {
+					/* OK */
+				} else {
+					mpPutBack(mpp, d, 1);
+				}
+			}
+			break;
+		} else if (d[0] == '\n') {
+			break;
+		} else if ((d[0] == ':') && attrLen) {
+			valueFound = 1;
+			while (mpRead(mpp, d, 1) == 1) {
+				if (!isspace(d[0])) {
+					mpPutBack(mpp, d, 1);
+					break;
+				} 
+			}
+		} else if (!valueFound) {
+			if (!isspace(*d)) {
+				if (attrLen < (attrSpace - 1)) {
+					attr[attrLen++] = *d;
+				}
+			}		
+		} else if (valueFound) {	
+			if (valueLen < (valueSpace - 1)) {
+				value[valueLen++] = *d;
+			}
+		}
+	}
+	if (attrSpace) {
+		attr[attrLen] = '\0';
+	}
+	if (valueSpace) {
+		value[valueLen] = '\0';
+	}
+	if (attrLen && valueLen) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+static cgiParseResultType cgiParseGetFormInput() {
+	return cgiParseFormInput(cgiQueryString, cgiContentLength);
+}
+
+typedef enum {
+	cgiEscapeRest,
+	cgiEscapeFirst,
+	cgiEscapeSecond
+} cgiEscapeState;
+
+typedef enum {
+	cgiUnescapeSuccess,
+	cgiUnescapeMemory
+} cgiUnescapeResultType;
+
+static cgiUnescapeResultType cgiUnescapeChars(char **sp, char *cp, int len);
+
+static cgiParseResultType cgiParseFormInput(char *data, int length) {
+	/* Scan for pairs, unescaping and storing them as they are found. */
+	int pos = 0;
+	cgiFormEntry *n;
+	cgiFormEntry *l = 0;
+	while (pos != length) {
+		int foundEq = 0;
+		int foundAmp = 0;
+		int start = pos;
+		int len = 0;
+		char *attr;
+		char *value;
+		while (pos != length) {
+			if (data[pos] == '=') {
+				foundEq = 1;
+				pos++;
+				break;
+			}
+			pos++;
+			len++;
+		}
+		if (!foundEq) {
+			break;
+		}
+		if (cgiUnescapeChars(&attr, data+start, len)
+			!= cgiUnescapeSuccess) {
+			return cgiParseMemory;
+		}	
+		start = pos;
+		len = 0;
+		while (pos != length) {
+			if (data[pos] == '&') {
+				foundAmp = 1;
+				pos++;
+				break;
+			}
+			pos++;
+			len++;
+		}
+		/* The last pair probably won't be followed by a &, but
+			that's fine, so check for that after accepting it */
+		if (cgiUnescapeChars(&value, data+start, len)
+			!= cgiUnescapeSuccess) {
+			free(attr);
+			return cgiParseMemory;
+		}	
+		/* OK, we have a new pair, add it to the list. */
+		n = (cgiFormEntry *) malloc(sizeof(cgiFormEntry));	
+		if (!n) {
+			free(attr);
+			free(value);
+			return cgiParseMemory;
+		}
+		n->attr = attr;
+		n->value = value;
+		n->valueLength = strlen(n->value);
+		n->fileName = (char *) malloc(1);
+		if (!n->fileName) {
+			free(attr);
+			free(value);
+			free(n);
+			return cgiParseMemory;
+		}	
+		n->fileName[0] = '\0';
+		n->contentType = (char *) malloc(1);
+		if (!n->contentType) {
+			free(attr);
+			free(value);
+			free(n->fileName);
+			free(n);
+			return cgiParseMemory;
+		}	
+		n->contentType[0] = '\0';
+		n->tfileName = (char *) malloc(1);
+		if (!n->tfileName) {
+			free(attr);
+			free(value);
+			free(n->fileName);
+			free(n->contentType);
+			free(n);
+			return cgiParseMemory;
+		}	
+		n->tfileName[0] = '\0';
+		n->next = 0;
+		if (!l) {
+			cgiFormEntryFirst = n;
+		} else {
+			l->next = n;
+		}
+		l = n;
+		if (!foundAmp) {
+			break;
+		}			
+	}
+	return cgiParseSuccess;
+}
+
+static int cgiHexValue[256];
+
+cgiUnescapeResultType cgiUnescapeChars(char **sp, char *cp, int len) {
+	char *s;
+	cgiEscapeState escapeState = cgiEscapeRest;
+	int escapedValue = 0;
+	int srcPos = 0;
+	int dstPos = 0;
+	s = (char *) malloc(len + 1);
+	if (!s) {
+		return cgiUnescapeMemory;
+	}
+	while (srcPos < len) {
+		int ch = cp[srcPos];
+		if(cgiTreatUrlEncoding==1)
+		switch (escapeState) {
+			case cgiEscapeRest:
+			if (ch == '%') {
+				escapeState = cgiEscapeFirst;
+			} else if (ch == '+') {
+				s[dstPos++] = ' ';
+			} else {
+				s[dstPos++] = ch;
+			}
+			break;
+			case cgiEscapeFirst:
+			escapedValue = cgiHexValue[ch] << 4;	
+			escapeState = cgiEscapeSecond;
+			break;
+			case cgiEscapeSecond:
+			escapedValue += cgiHexValue[ch];
+			s[dstPos++] = escapedValue;
+			escapeState = cgiEscapeRest;
+			break;
+		}
+		else
+		  s[dstPos++] = ch;
+		srcPos++;
+	}
+	s[dstPos] = '\0';
+	*sp = s;
+	return cgiUnescapeSuccess;
+}		
+	
+static void cgiSetupConstants() {
+	int i;
+	for (i=0; (i < 256); i++) {
+		cgiHexValue[i] = 0;
+	}
+	cgiHexValue['0'] = 0;	
+	cgiHexValue['1'] = 1;	
+	cgiHexValue['2'] = 2;	
+	cgiHexValue['3'] = 3;	
+	cgiHexValue['4'] = 4;	
+	cgiHexValue['5'] = 5;	
+	cgiHexValue['6'] = 6;	
+	cgiHexValue['7'] = 7;	
+	cgiHexValue['8'] = 8;	
+	cgiHexValue['9'] = 9;
+	cgiHexValue['A'] = 10;
+	cgiHexValue['B'] = 11;
+	cgiHexValue['C'] = 12;
+	cgiHexValue['D'] = 13;
+	cgiHexValue['E'] = 14;
+	cgiHexValue['F'] = 15;
+	cgiHexValue['a'] = 10;
+	cgiHexValue['b'] = 11;
+	cgiHexValue['c'] = 12;
+	cgiHexValue['d'] = 13;
+	cgiHexValue['e'] = 14;
+	cgiHexValue['f'] = 15;
+}
+
+static void cgiFreeResources() {
+	cgiFormEntry *c = cgiFormEntryFirst;
+	cgiFormEntry *n;
+	while (c) {
+		n = c->next;
+		free(c->attr);
+		free(c->value);
+		free(c->fileName);
+		free(c->contentType);
+		if (strlen(c->tfileName)) {
+			unlink(c->tfileName);
+		}
+		free(c->tfileName);
+		free(c);
+		c = n;
+	}
+	/* If the cgi environment was restored from a saved environment,
+		then these are in allocated space and must also be freed */
+	if (cgiRestored) {
+		free(cgiServerSoftware);
+		free(cgiServerName);
+		free(cgiGatewayInterface);
+		free(cgiServerProtocol);
+		free(cgiServerPort);
+		free(cgiRequestMethod);
+		free(cgiPathInfo);
+		free(cgiPathTranslated);
+		free(cgiScriptName);
+		free(cgiQueryString);
+		free(cgiRemoteHost);
+		free(cgiRemoteAddr);
+		free(cgiAuthType);
+		free(cgiRemoteUser);
+		free(cgiRemoteIdent);
+		free(cgiContentType);
+		free(cgiAccept);
+		free(cgiUserAgent);
+		free(cgiReferrer);
+	}
+	/* 2.0: to clean up the environment for cgiReadEnvironment,
+		we must set these correctly */
+	cgiFormEntryFirst = 0;
+	cgiRestored = 0;
+}
+
+static cgiFormResultType cgiFormEntryString(
+	cgiFormEntry *e, char *result, int max, int newlines);
+
+static cgiFormEntry *cgiFormEntryFindFirst(char *name);
+static cgiFormEntry *cgiFormEntryFindNext();
+
+cgiFormResultType cgiFormString(
+        char *name, char *result, int max) {
+	cgiFormEntry *e;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		strcpy(result, "");
+		return cgiFormNotFound;
+	}
+	return cgiFormEntryString(e, result, max, 1);
+}
+
+cgiFormResultType cgiFormFileName(
+	char *name, char *result, int resultSpace)
+{
+	cgiFormEntry *e;
+	int resultLen = 0;
+	char *s;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		strcpy(result, "");
+		return cgiFormNotFound;
+	}
+	s = e->fileName;
+	while (*s) {
+		APPEND(result, *s);
+		s++;
+	}	
+	if (resultSpace) {
+		result[resultLen] = '\0';
+	}
+	if (!strlen(e->fileName)) {
+		return cgiFormNoFileName;
+	} else if (((int) strlen(e->fileName)) > (resultSpace - 1)) {
+		return cgiFormTruncated;
+	} else {
+		return cgiFormSuccess;
+	}
+}
+
+cgiFormResultType cgiFormFileContentType(
+	char *name, char *result, int resultSpace)
+{
+	cgiFormEntry *e;
+	int resultLen = 0;
+	char *s;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		if (resultSpace) {
+			result[0] = '\0';
+		}	
+		return cgiFormNotFound;
+	}
+	s = e->contentType;
+	while (*s) {
+		APPEND(result, *s);
+		s++;
+	}	
+	if (resultSpace) {
+		result[resultLen] = '\0';
+	}
+	if (!strlen(e->contentType)) {
+		return cgiFormNoContentType;
+	} else if (((int) strlen(e->contentType)) > (resultSpace - 1)) {
+		return cgiFormTruncated;
+	} else {
+		return cgiFormSuccess;
+	}
+}
+
+cgiFormResultType cgiFormFileSize(
+	char *name, int *sizeP)
+{
+	cgiFormEntry *e;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		if (sizeP) {
+			*sizeP = 0;
+		}
+		return cgiFormNotFound;
+	} else if (!strlen(e->tfileName)) {
+		if (sizeP) {
+			*sizeP = 0;
+		}
+		return cgiFormNotAFile;
+	} else {
+		if (sizeP) {
+			*sizeP = e->valueLength;
+		}
+		return cgiFormSuccess;
+	}
+}
+
+typedef struct cgiFileStruct {
+	FILE *in;
+} cgiFile;
+
+cgiFormResultType cgiFormFileOpen(
+	char *name, cgiFilePtr *cfpp)
+{
+	cgiFormEntry *e;
+	cgiFilePtr cfp;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		*cfpp = 0;
+		return cgiFormNotFound;
+	}
+	if (!strlen(e->tfileName)) {
+		*cfpp = 0;
+		return cgiFormNotAFile;
+	}
+	cfp = (cgiFilePtr) malloc(sizeof(cgiFile));
+	if (!cfp) {
+		*cfpp = 0;
+		return cgiFormMemory;
+	}
+	cfp->in = fopen(e->tfileName, "rb");
+	if (!cfp->in) {
+		free(cfp);
+		return cgiFormIO;
+	}
+	*cfpp = cfp;
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormFileRead(
+	cgiFilePtr cfp, char *buffer, 
+	int bufferSize, int *gotP)
+{
+	int got = 0;
+	if (!cfp) {
+		return cgiFormOpenFailed;
+	}
+	got = fread(buffer, 1, bufferSize, cfp->in);
+	if (got <= 0) {
+		return cgiFormEOF;
+	}
+	*gotP = got;
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormFileClose(cgiFilePtr cfp)
+{
+	if (!cfp) {
+		return cgiFormOpenFailed;
+	}
+	fclose(cfp->in);
+	free(cfp);
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormStringNoNewlines(
+        char *name, char *result, int max) {
+	cgiFormEntry *e;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		strcpy(result, "");
+		return cgiFormNotFound;
+	}
+	return cgiFormEntryString(e, result, max, 0);
+}
+
+cgiFormResultType cgiFormStringMultiple(
+        char *name, char ***result) {
+	char **stringArray;
+	cgiFormEntry *e;
+	int i;
+	int total = 0;
+	/* Make two passes. One would be more efficient, but this
+		function is not commonly used. The select menu and
+		radio box functions are faster. */
+	e = cgiFormEntryFindFirst(name);
+	if (e != 0) {
+		do {
+			total++;
+		} while ((e = cgiFormEntryFindNext()) != 0); 
+	}
+	stringArray = (char **) malloc(sizeof(char *) * (total + 1));
+	if (!stringArray) {
+		*result = 0;
+		return cgiFormMemory;
+	}
+	/* initialize all entries to null; the last will stay that way */
+	for (i=0; (i <= total); i++) {
+		stringArray[i] = 0;
+	}
+	/* Now go get the entries */
+	e = cgiFormEntryFindFirst(name);
+#ifdef CGICDEBUG
+	CGICDEBUGSTART
+	fprintf(dout, "StringMultiple Beginning\n");
+	CGICDEBUGEND
+#endif /* CGICDEBUG */
+	if (e) {
+		i = 0;
+		do {
+			int max = (int) (strlen(e->value) + 1);
+			stringArray[i] = (char *) malloc(max);
+			if (stringArray[i] == 0) {
+				/* Memory problems */
+				cgiStringArrayFree(stringArray);
+				*result = 0;
+				return cgiFormMemory;
+			}	
+			strcpy(stringArray[i], e->value);
+			cgiFormEntryString(e, stringArray[i], max, 1);
+			i++;
+		} while ((e = cgiFormEntryFindNext()) != 0); 
+		*result = stringArray;
+#ifdef CGICDEBUG
+		CGICDEBUGSTART
+		fprintf(dout, "StringMultiple Succeeding\n");
+		CGICDEBUGEND
+#endif /* CGICDEBUG */
+		return cgiFormSuccess;
+	} else {
+		*result = stringArray;
+#ifdef CGICDEBUG
+		CGICDEBUGSTART
+		fprintf(dout, "StringMultiple found nothing\n");
+		CGICDEBUGEND
+#endif /* CGICDEBUG */
+		return cgiFormNotFound;
+	}	
+}
+
+cgiFormResultType cgiFormStringSpaceNeeded(
+        char *name, int *result) {
+	cgiFormEntry *e;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		*result = 1;
+		return cgiFormNotFound; 
+	}
+	*result = ((int) strlen(e->value)) + 1;
+	return cgiFormSuccess;
+}
+
+static cgiFormResultType cgiFormEntryString(
+	cgiFormEntry *e, char *result, int max, int newlines) {
+	char *dp, *sp;
+	int truncated = 0;
+	int len = 0;
+	int avail = max-1;
+	int crCount = 0;
+	int lfCount = 0;	
+	dp = result;
+	sp = e->value;	
+	while (1) {
+		int ch;
+		/* 1.07: don't check for available space now.
+			We check for it immediately before adding
+			an actual character. 1.06 handled the
+			trailing null of the source string improperly,
+			resulting in a cgiFormTruncated error. */
+		ch = *sp;
+		/* Fix the CR/LF, LF, CR nightmare: watch for
+			consecutive bursts of CRs and LFs in whatever
+			pattern, then actually output the larger number 
+			of LFs. Consistently sane, yet it still allows
+			consecutive blank lines when the user
+			actually intends them. */
+		if ((ch == 13) || (ch == 10)) {
+			if (ch == 13) {
+				crCount++;
+			} else {
+				lfCount++;
+			}	
+		} else {
+			if (crCount || lfCount) {
+				int lfsAdd = crCount;
+				if (lfCount > crCount) {
+					lfsAdd = lfCount;
+				}
+				/* Stomp all newlines if desired */
+				if (!newlines) {
+					lfsAdd = 0;
+				}
+				while (lfsAdd) {
+					if (len >= avail) {
+						truncated = 1;
+						break;
+					}
+					*dp = 10;
+					dp++;
+					lfsAdd--;
+					len++;		
+				}
+				crCount = 0;
+				lfCount = 0;
+			}
+			if (ch == '\0') {
+				/* The end of the source string */
+				break;				
+			}	
+			/* 1.06: check available space before adding
+				the character, because a previously added
+				LF may have brought us to the limit */
+			if (len >= avail) {
+				truncated = 1;
+				break;
+			}
+			*dp = ch;
+			dp++;
+			len++;
+		}
+		sp++;	
+	}	
+	*dp = '\0';
+	if (truncated) {
+		return cgiFormTruncated;
+	} else if (!len) {
+		return cgiFormEmpty;
+	} else {
+		return cgiFormSuccess;
+	}
+}
+
+static int cgiFirstNonspaceChar(char *s);
+
+cgiFormResultType cgiFormInteger(
+        char *name, int *result, int defaultV) {
+	cgiFormEntry *e;
+	int ch;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		*result = defaultV;
+		return cgiFormNotFound; 
+	}	
+	if (!strlen(e->value)) {
+		*result = defaultV;
+		return cgiFormEmpty;
+	}
+	ch = cgiFirstNonspaceChar(e->value);
+	if (!(isdigit(ch)) && (ch != '-') && (ch != '+')) {
+		*result = defaultV;
+		return cgiFormBadType;
+	} else {
+		*result = atoi(e->value);
+		return cgiFormSuccess;
+	}
+}
+
+cgiFormResultType cgiFormIntegerBounded(
+        char *name, int *result, int min, int max, int defaultV) {
+	cgiFormResultType error = cgiFormInteger(name, result, defaultV);
+	if (error != cgiFormSuccess) {
+		return error;
+	}
+	if (*result < min) {
+		*result = min;
+		return cgiFormConstrained;
+	} 
+	if (*result > max) {
+		*result = max;
+		return cgiFormConstrained;
+	} 
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormDouble(
+        char *name, double *result, double defaultV) {
+	cgiFormEntry *e;
+	int ch;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		*result = defaultV;
+		return cgiFormNotFound; 
+	}	
+	if (!strlen(e->value)) {
+		*result = defaultV;
+		return cgiFormEmpty;
+	} 
+	ch = cgiFirstNonspaceChar(e->value);
+	if (!(isdigit(ch)) && (ch != '.') && (ch != '-') && (ch != '+')) {
+		*result = defaultV;
+		return cgiFormBadType;
+	} else {
+		*result = atof(e->value);
+		return cgiFormSuccess;
+	}
+}
+
+cgiFormResultType cgiFormDoubleBounded(
+        char *name, double *result, double min, double max, double defaultV) {
+	cgiFormResultType error = cgiFormDouble(name, result, defaultV);
+	if (error != cgiFormSuccess) {
+		return error;
+	}
+	if (*result < min) {
+		*result = min;
+		return cgiFormConstrained;
+	} 
+	if (*result > max) {
+		*result = max;
+		return cgiFormConstrained;
+	} 
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormSelectSingle(
+	char *name, char **choicesText, int choicesTotal, 
+	int *result, int defaultV) 
+{
+	cgiFormEntry *e;
+	int i;
+	e = cgiFormEntryFindFirst(name);
+#ifdef CGICDEBUG
+	CGICDEBUGSTART
+	fprintf(dout, "%d\n", (int) e);
+	CGICDEBUGEND
+#endif /* CGICDEBUG */
+	if (!e) {
+		*result = defaultV;
+		return cgiFormNotFound;
+	}
+	for (i=0; (i < choicesTotal); i++) {
+#ifdef CGICDEBUG
+		CGICDEBUGSTART
+		fprintf(dout, "%s %s\n", choicesText[i], e->value);
+		CGICDEBUGEND
+#endif /* CGICDEBUG */
+		if (cgiStrEq(choicesText[i], e->value)) {
+#ifdef CGICDEBUG
+			CGICDEBUGSTART
+			fprintf(dout, "MATCH\n");
+			CGICDEBUGEND
+#endif /* CGICDEBUG */
+			*result = i;
+			return cgiFormSuccess;
+		}
+	}
+	*result = defaultV;
+	return cgiFormNoSuchChoice;
+}
+
+cgiFormResultType cgiFormSelectMultiple(
+	char *name, char **choicesText, int choicesTotal, 
+	int *result, int *invalid) 
+{
+	cgiFormEntry *e;
+	int i;
+	int hits = 0;
+	int invalidE = 0;
+	for (i=0; (i < choicesTotal); i++) {
+		result[i] = 0;
+	}
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		*invalid = invalidE;
+		return cgiFormNotFound;
+	}
+	do {
+		int hit = 0;
+		for (i=0; (i < choicesTotal); i++) {
+			if (cgiStrEq(choicesText[i], e->value)) {
+				result[i] = 1;
+				hits++;
+				hit = 1;
+				break;
+			}
+		}
+		if (!(hit)) {
+			invalidE++;
+		}
+	} while ((e = cgiFormEntryFindNext()) != 0);
+
+	*invalid = invalidE;
+
+	if (hits) {
+		return cgiFormSuccess;
+	} else {
+		return cgiFormNotFound;
+	}
+}
+
+cgiFormResultType cgiFormCheckboxSingle(
+	char *name)
+{
+	cgiFormEntry *e;
+	e = cgiFormEntryFindFirst(name);
+	if (!e) {
+		return cgiFormNotFound;
+	}
+	return cgiFormSuccess;
+}
+
+extern cgiFormResultType cgiFormCheckboxMultiple(
+	char *name, char **valuesText, int valuesTotal, 
+	int *result, int *invalid)
+{
+	/* Implementation is identical to cgiFormSelectMultiple. */
+	return cgiFormSelectMultiple(name, valuesText, 
+		valuesTotal, result, invalid);
+}
+
+cgiFormResultType cgiFormRadio(
+	char *name, 
+	char **valuesText, int valuesTotal, int *result, int defaultV)
+{
+	/* Implementation is identical to cgiFormSelectSingle. */
+	return cgiFormSelectSingle(name, valuesText, valuesTotal, 
+		result, defaultV);
+}
+
+cgiFormResultType cgiCookieString(
+	char *name,
+	char *value,
+	int space)
+{
+	char *p = cgiCookie;
+	while (*p) {
+		char *n = name;
+		/* 2.02: if cgiCookie is exactly equal to name, this
+			can cause an overrun. The server probably wouldn't
+			allow it, since a name without values makes no sense 
+			-- but then again it might not check, so this is a
+			genuine security concern. Thanks to Nicolas 
+			Tomadakis. */
+		while (*p == *n) {
+			if ((p == '\0') && (n == '\0')) {
+				/* Malformed cookie header from client */
+				return cgiFormNotFound;
+			}
+			p++;
+			n++;
+		}
+		if ((!*n) && (*p == '=')) {
+			p++;
+			while ((*p != ';') && (*p != '\0') &&
+				(space > 1)) 
+			{
+				*value = *p;
+				value++;
+				p++;
+				space--;
+			}
+			if (space > 0) {
+				*value = '\0';
+			}
+			/* Correct parens: 2.02. Thanks to
+				Mathieu Villeneuve-Belair. */
+			if (!(((*p) == ';') || ((*p) == '\0')))
+			{
+				return cgiFormTruncated;
+			} else {	
+				return cgiFormSuccess;
+			}
+		} else {
+			/* Skip to next cookie */	
+			while (*p) {
+				if (*p == ';') {
+					break;
+				}
+				p++;
+			}
+			if (!*p) {
+				/* 2.01: default to empty */
+				if (space) {
+					*value = '\0';
+				}
+				return cgiFormNotFound;
+			}
+			p++;	
+			/* Allow whitespace after semicolon */
+			while ((*p) && isspace(*p)) {
+				p++;
+			} 
+		}
+	}
+	/* 2.01: actually the above loop never terminates except
+		with a return, but do this to placate gcc */
+	if (space) {
+		*value = '\0';
+	}
+	return cgiFormNotFound;
+}
+
+cgiFormResultType cgiCookieInteger(
+	char *name,
+	int *result,
+	int defaultV)
+{
+	char buffer[256];
+	cgiFormResultType r = 
+		cgiCookieString(name, buffer, sizeof(buffer));
+	if (r != cgiFormSuccess) {
+		*result = defaultV;
+	} else {
+		*result = atoi(buffer);
+	}
+	return r;
+}
+
+void cgiHeaderCookieSetInteger(char *name, int value, int secondsToLive,
+	char *path, char *domain)
+{
+	char svalue[256];
+	sprintf(svalue, "%d", value);
+	cgiHeaderCookieSetString(name, svalue, secondsToLive, path, domain);
+}
+
+char *days[] = {
+	"Sun",
+	"Mon",
+	"Tue",
+	"Wed",
+	"Thu",
+	"Fri",
+	"Sat"
+};
+
+char *months[] = {
+	"Jan",
+	"Feb",
+	"Mar",
+	"Apr",
+	"May",
+	"Jun",
+	"Jul",
+	"Aug",
+	"Sep",
+	"Oct",
+	"Nov",
+	"Dec"
+};
+
+void cgiHeaderCookieSetString(char *name, char *value, int secondsToLive,
+	char *path, char *domain)
+{
+	/* cgic 2.02: simpler and more widely compatible implementation.
+		Thanks to Chunfu Lai. 
+	   cgic 2.03: yes, but it didn't work. Reimplemented by
+		Thomas Boutell. ; after last element was a bug. 
+	   Examples of real world cookies that really work:
+   	   Set-Cookie: MSNADS=UM=; domain=.slate.com; 
+             expires=Tue, 26-Apr-2022 19:00:00 GMT; path=/
+	   Set-Cookie: MC1=V=3&ID=b5bc08af2b8a43ff85fcb5efd8b238f0; 
+             domain=.slate.com; expires=Mon, 04-Oct-2021 19:00:00 GMT; path=/
+	*/
+	time_t now;
+	time_t then;
+	struct tm *gt;
+	time(&now);
+	then = now + secondsToLive;
+	gt = gmtime(&then);
+	fprintf(cgiOut, 
+		"Set-Cookie: %s=%s; domain=%s; expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT; path=%s\r\n",
+		name, value, domain, 
+		days[gt->tm_wday],
+		gt->tm_mday,
+		months[gt->tm_mon],
+		gt->tm_year + 1900, 	
+		gt->tm_hour,
+		gt->tm_min,
+		gt->tm_sec,
+		path);
+}
+
+void cgiHeaderLocation(char *redirectUrl) {
+	fprintf(cgiOut, "Location: %s\r\n\r\n", redirectUrl);
+}
+
+void cgiHeaderStatus(int status, char *statusMessage) {
+	fprintf(cgiOut, "Status: %d %s\r\n\r\n", status, statusMessage);
+}
+
+void cgiHeaderContentType(char *mimeType) {
+	fprintf(cgiOut, "Content-type: %s\r\n\r\n", mimeType);
+}
+
+static int cgiWriteString(FILE *out, char *s);
+
+static int cgiWriteInt(FILE *out, int i);
+
+#define CGIC_VERSION "2.0"
+
+cgiEnvironmentResultType cgiWriteEnvironment(char *filename) {
+	FILE *out;
+	cgiFormEntry *e;
+	/* Be sure to open in binary mode */
+	out = fopen(filename, "wb");
+	if (!out) {
+		/* Can't create file */
+		return cgiEnvironmentIO;
+	}
+	if (!cgiWriteString(out, "CGIC2.0")) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiServerSoftware)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiServerName)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiGatewayInterface)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiServerProtocol)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiServerPort)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiRequestMethod)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiPathInfo)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiPathTranslated)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiScriptName)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiQueryString)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiRemoteHost)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiRemoteAddr)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiAuthType)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiRemoteUser)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiRemoteIdent)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiContentType)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiAccept)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiUserAgent)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiReferrer)) {
+		goto error;
+	}
+	if (!cgiWriteString(out, cgiCookie)) {
+		goto error;
+	}
+	if (!cgiWriteInt(out, cgiContentLength)) {
+		goto error;
+	}
+	e = cgiFormEntryFirst;
+	while (e) {
+		cgiFilePtr fp;
+		if (!cgiWriteString(out, e->attr)) {
+			goto error;
+		}
+		if (!cgiWriteString(out, e->value)) {
+			goto error;
+		}
+		/* New 2.0 fields and file uploads */
+		if (!cgiWriteString(out, e->fileName)) {
+			goto error;
+		}
+		if (!cgiWriteString(out, e->contentType)) {
+			goto error;
+		}
+		if (!cgiWriteInt(out, e->valueLength)) {
+			goto error;
+		}
+		if (cgiFormFileOpen(e->attr, &fp) == cgiFormSuccess) {
+			char buffer[1024];
+			int got;
+			if (!cgiWriteInt(out, 1)) {
+				cgiFormFileClose(fp);
+				goto error;
+			}
+			while (cgiFormFileRead(fp, buffer, 
+				sizeof(buffer), &got) == cgiFormSuccess)
+			{
+				if (((int) fwrite(buffer, 1, got, out)) != got) {
+					cgiFormFileClose(fp);
+					goto error;
+				}
+			}
+			if (cgiFormFileClose(fp) != cgiFormSuccess) {
+				goto error;
+			}
+		} else {
+			if (!cgiWriteInt(out, 0)) {
+				goto error;
+			}
+		}
+		e = e->next;
+	}
+	fclose(out);
+	return cgiEnvironmentSuccess;
+error:
+	fclose(out);
+	/* If this function is not defined in your system,
+		you must substitute the appropriate 
+		file-deletion function. */
+	unlink(filename);
+	return cgiEnvironmentIO;
+}
+
+static int cgiWriteString(FILE *out, char *s) {
+	int len = (int) strlen(s);
+	cgiWriteInt(out, len);
+	if (((int) fwrite(s, 1, len, out)) != len) {
+		return 0;
+	}
+	return 1;
+}
+
+static int cgiWriteInt(FILE *out, int i) {
+	if (!fwrite(&i, sizeof(int), 1, out)) {
+		return 0;
+	}
+	return 1;
+}
+
+static int cgiReadString(FILE *out, char **s);
+
+static int cgiReadInt(FILE *out, int *i);
+
+cgiEnvironmentResultType cgiReadEnvironment(char *filename) {
+	FILE *in;
+	cgiFormEntry *e = 0, *p;
+	char *version;
+	/* Prevent compiler warnings */
+	cgiEnvironmentResultType result = cgiEnvironmentIO;
+	/* Free any existing data first */
+	cgiFreeResources();
+	/* Be sure to open in binary mode */
+	in = fopen(filename, "rb");
+	if (!in) {
+		/* Can't access file */
+		return cgiEnvironmentIO;
+	}
+	if (!cgiReadString(in, &version)) {
+		goto error;
+	}
+	if (strcmp(version, "CGIC" CGIC_VERSION)) {
+		/* 2.02: Merezko Oleg */
+		free(version);
+		return cgiEnvironmentWrongVersion;
+	}	
+	/* 2.02: Merezko Oleg */
+	free(version);
+	if (!cgiReadString(in, &cgiServerSoftware)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiServerName)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiGatewayInterface)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiServerProtocol)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiServerPort)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiRequestMethod)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiPathInfo)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiPathTranslated)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiScriptName)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiQueryString)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiRemoteHost)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiRemoteAddr)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiAuthType)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiRemoteUser)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiRemoteIdent)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiContentType)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiAccept)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiUserAgent)) {
+		goto error;
+	}
+	if (!cgiReadString(in, &cgiReferrer)) {
+		goto error;
+	}
+	/* 2.0 */
+	if (!cgiReadString(in, &cgiCookie)) {
+		goto error;
+	}
+	if (!cgiReadInt(in, &cgiContentLength)) {
+		goto error;
+	}
+	p = 0;
+	while (1) {
+		int fileFlag;
+		e = (cgiFormEntry *) calloc(1, sizeof(cgiFormEntry));
+		if (!e) {
+			cgiFreeResources();
+			fclose(in);
+			return cgiEnvironmentMemory;
+		}
+		memset(e, 0, sizeof(cgiFormEntry));
+		if (!cgiReadString(in, &e->attr)) {
+			/* This means we've reached the end of the list. */
+			/* 2.02: thanks to Merezko Oleg */
+			free(e);
+			break;
+		}
+		if (!cgiReadString(in, &e->value)) {
+			goto outOfMemory;
+		}
+		if (!cgiReadString(in, &e->fileName)) {
+			goto outOfMemory;
+		}
+		if (!cgiReadString(in, &e->contentType)) {
+			goto outOfMemory;
+		}
+		if (!cgiReadInt(in, &e->valueLength)) {
+			goto outOfMemory;
+		}
+		if (!cgiReadInt(in, &fileFlag)) {
+			goto outOfMemory;
+		}
+		if (fileFlag) {
+			char buffer[1024];
+			FILE *out;
+			char tfileName[1024];
+			int got;
+			int len = e->valueLength;
+			if (getTempFileName(tfileName)
+				!= cgiParseSuccess)
+			{
+				result = cgiEnvironmentIO;
+				goto error;
+			}
+			out = fopen(tfileName, "w+b");
+			if (!out) {
+				result = cgiEnvironmentIO;
+				goto error;
+			}
+			while (len > 0) {		
+				/* 2.01: try is a bad variable name in
+					C++, and it wasn't being used
+					properly either */
+				int tryr = len;
+				if (tryr > ((int) sizeof(buffer))) {
+					tryr = sizeof(buffer);
+				}
+				got = fread(buffer, 1, tryr, in);
+				if (got <= 0) {
+					result = cgiEnvironmentIO;
+					fclose(out);
+					unlink(tfileName);
+					goto error;
+				}
+				if (((int) fwrite(buffer, 1, got, out)) != got) {
+					result = cgiEnvironmentIO;
+					fclose(out);
+					unlink(tfileName);
+					goto error;
+				}
+				len -= got;
+			}
+			/* cgic 2.05: should be fclose not rewind */
+			fclose(out);
+			e->tfileName = (char *) malloc((int) strlen(tfileName) + 1);
+			if (!e->tfileName) {
+				result = cgiEnvironmentMemory;
+				unlink(tfileName);
+				goto error;
+			}
+			strcpy(e->tfileName, tfileName);
+		} else {
+			e->tfileName = (char *) malloc(1);
+			if (!e->tfileName) {
+				result = cgiEnvironmentMemory;
+				goto error;
+			}
+		}	
+		e->next = 0;
+		if (p) {
+			p->next = e;
+		} else {
+			cgiFormEntryFirst = e;
+		}	
+		p = e;
+	}
+	fclose(in);
+	cgiRestored = 1;
+	return cgiEnvironmentSuccess;
+outOfMemory:
+	result = cgiEnvironmentMemory;
+error:
+	cgiFreeResources();
+	fclose(in);
+	if (e) {
+		if (e->attr) {
+			free(e->attr);
+		}
+		if (e->value) {
+			free(e->value);
+		}
+		if (e->fileName) {
+			free(e->fileName);
+		}
+		if (e->contentType) {
+			free(e->contentType);
+		}
+		if (e->tfileName) {
+			free(e->tfileName);
+		}
+		free(e);
+	}
+	return result;
+}
+
+static int cgiReadString(FILE *in, char **s) {
+	int len;
+	/* 2.0 fix: test cgiReadInt for failure! */ 
+	if (!cgiReadInt(in, &len)) {
+		return 0;
+	}
+	*s = (char *) malloc(len + 1);
+	if (!(*s)) {
+		return 0;
+	}	
+	if (((int) fread(*s, 1, len, in)) != len) {
+		return 0;
+	}
+	(*s)[len] = '\0';
+	return 1;
+}
+
+static int cgiReadInt(FILE *out, int *i) {
+	if (!fread(i, sizeof(int), 1, out)) {
+		return 0;
+	}
+	return 1;
+}
+
+static int cgiStrEqNc(char *s1, char *s2) {
+	while(1) {
+		if (!(*s1)) {
+			if (!(*s2)) {
+				return 1;
+			} else {
+				return 0;
+			}
+		} else if (!(*s2)) {
+			return 0;
+		}
+		if (isalpha(*s1)) {
+			if (tolower(*s1) != tolower(*s2)) {
+				return 0;
+			}
+		} else if ((*s1) != (*s2)) {
+			return 0;
+		}
+		s1++;
+		s2++;
+	}
+}
+
+static int cgiStrBeginsNc(char *s1, char *s2) {
+	while(1) {
+		if (!(*s2)) {
+			return 1;
+		} else if (!(*s1)) {
+			return 0;
+		}
+		if (isalpha(*s1)) {
+			if (tolower(*s1) != tolower(*s2)) {
+				return 0;
+			}
+		} else if ((*s1) != (*s2)) {
+			return 0;
+		}
+		s1++;
+		s2++;
+	}
+}
+
+static char *cgiFindTarget = 0;
+static cgiFormEntry *cgiFindPos = 0;
+
+static cgiFormEntry *cgiFormEntryFindFirst(char *name) {
+	cgiFindTarget = name;
+	cgiFindPos = cgiFormEntryFirst;
+	return cgiFormEntryFindNext();
+}
+
+static cgiFormEntry *cgiFormEntryFindNext() {
+	while (cgiFindPos) {
+		cgiFormEntry *c = cgiFindPos;
+		cgiFindPos = c->next;
+		if (!strcmp(c -> attr, cgiFindTarget)) {
+			return c;
+		}
+	}
+	return 0;
+}
+
+static int cgiFirstNonspaceChar(char *s) {
+	int len = strspn(s, " \n\r\t");
+	return s[len];
+}
+
+void cgiStringArrayFree(char **stringArray) {
+	char *p;
+	char **arrayItself = stringArray;
+	p = *stringArray;
+	while (p) {
+		free(p);
+		stringArray++;
+		p = *stringArray;
+	}
+	/* 2.0: free the array itself! */
+	free(arrayItself);
+}	
+
+cgiFormResultType cgiCookies(char ***result) {
+	char **stringArray;
+	int i;
+	int total = 0;
+	char *p;
+	char *n;
+	p = cgiCookie;
+	while (*p) {
+		if (*p == '=') {
+			total++;
+		}
+		p++;
+	}
+	stringArray = (char **) malloc(sizeof(char *) * (total + 1));
+	if (!stringArray) {
+		*result = 0;
+		return cgiFormMemory;
+	}
+	/* initialize all entries to null; the last will stay that way */
+	for (i=0; (i <= total); i++) {
+		stringArray[i] = 0;
+	}
+	i = 0;
+	p = cgiCookie;
+	while (*p) {
+		while (*p && isspace(*p)) {
+			p++;
+		}
+		n = p;
+		while (*p && (*p != '=')) {
+			p++;
+		}
+		if (p != n) {
+			stringArray[i] = (char *) malloc((p - n) + 1);
+			if (!stringArray[i]) {
+				cgiStringArrayFree(stringArray);
+				*result = 0;
+				return cgiFormMemory;
+			}	
+			memcpy(stringArray[i], n, p - n);
+			stringArray[i][p - n] = '\0';
+			i++;
+		}
+		while (*p && (*p != ';')) {
+			p++;	
+		}
+		if (!*p) {
+			break;
+		}
+		if (*p == ';') {
+			p++;
+		}
+	}
+	*result = stringArray;
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiFormEntries(char ***result) {
+	char **stringArray;
+	cgiFormEntry *e, *pe;
+	int i;
+	int total = 0;
+	e = cgiFormEntryFirst;
+	while (e) {
+		/* Don't count a field name more than once if
+			multiple values happen to be present for it */
+		pe = cgiFormEntryFirst;
+		while (pe != e) {
+			if (!strcmp(e->attr, pe->attr)) {
+				goto skipSecondValue;
+			}
+			pe = pe->next;					
+		}
+		total++;
+skipSecondValue:
+		e = e->next;
+	}
+	stringArray = (char **) malloc(sizeof(char *) * (total + 1));
+	if (!stringArray) {
+		*result = 0;
+		return cgiFormMemory;
+	}
+	/* initialize all entries to null; the last will stay that way */
+	for (i=0; (i <= total); i++) {
+		stringArray[i] = 0;
+	}
+	/* Now go get the entries */
+	e = cgiFormEntryFirst;
+	i = 0;
+	while (e) {
+		int space;
+		/* Don't return a field name more than once if
+			multiple values happen to be present for it */
+		pe = cgiFormEntryFirst;
+		while (pe != e) {
+			if (!strcmp(e->attr, pe->attr)) {
+				goto skipSecondValue2;
+			}
+			pe = pe->next;					
+		}		
+		space = (int) strlen(e->attr) + 1;
+		stringArray[i] = (char *) malloc(space);
+		if (stringArray[i] == 0) {
+			/* Memory problems */
+			cgiStringArrayFree(stringArray);
+			*result = 0;
+			return cgiFormMemory;
+		}	
+		strcpy(stringArray[i], e->attr);
+		i++;
+skipSecondValue2:
+		e = e->next;
+	}
+	*result = stringArray;
+	return cgiFormSuccess;
+}
+
+#define TRYPUTC(ch) \
+	{ \
+		if (putc((ch), cgiOut) == EOF) { \
+			return cgiFormIO; \
+		} \
+	} 
+
+cgiFormResultType cgiHtmlEscapeData(char *data, int len)
+{
+	while (len--) {
+		if (*data == '<') {
+			TRYPUTC('&');
+			TRYPUTC('l');
+			TRYPUTC('t');
+			TRYPUTC(';');
+		} else if (*data == '&') {
+			TRYPUTC('&');
+			TRYPUTC('a');
+			TRYPUTC('m');
+			TRYPUTC('p');
+			TRYPUTC(';');
+		} else if (*data == '>') {
+			TRYPUTC('&');
+			TRYPUTC('g');
+			TRYPUTC('t');
+			TRYPUTC(';');
+		} else {
+			TRYPUTC(*data);
+		}
+		data++;
+	}
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiHtmlEscape(char *s)
+{
+	return cgiHtmlEscapeData(s, (int) strlen(s));
+}
+
+/* Output data with the " character HTML-escaped, and no
+	other characters escaped. This is useful when outputting
+	the contents of a tag attribute such as 'href' or 'src'.
+	'data' is not null-terminated; 'len' is the number of
+	bytes in 'data'. Returns cgiFormIO in the event
+	of error, cgiFormSuccess otherwise. */
+cgiFormResultType cgiValueEscapeData(char *data, int len)
+{
+	while (len--) {
+		if (*data == '\"') {
+			TRYPUTC('&');
+			TRYPUTC('#');
+			TRYPUTC('3');
+			TRYPUTC('4');
+			TRYPUTC(';');
+		} else {
+			TRYPUTC(*data);
+		}
+		data++;
+	}
+	return cgiFormSuccess;
+}
+
+cgiFormResultType cgiValueEscape(char *s)
+{
+	return cgiValueEscapeData(s, (int) strlen(s));
+}
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.h	(revision 672)
@@ -0,0 +1,457 @@
+/* The CGI_C library, by Thomas Boutell, version 2.01. CGI_C is intended
+	to be a high-quality API to simplify CGI programming tasks. */
+
+/* Make sure this is only included once. */
+
+#ifndef CGI_C
+#define CGI_C 1
+
+/* Bring in standard I/O since some of the functions refer to
+	types defined by it, such as FILE *. */
+
+#include "fcgi_stdio.h"
+//#include <stdio.h>
+
+/* The various CGI environment variables. Instead of using getenv(),
+	the programmer should refer to these, which are always
+	valid null-terminated strings (they may be empty, but they 
+	will never be null). If these variables are used instead
+	of calling getenv(), then it will be possible to save
+	and restore CGI environments, which is highly convenient
+	for debugging. */
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiServerSoftware;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiServerName;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiGatewayInterface;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiServerProtocol;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiServerPort;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiRequestMethod;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiPathInfo;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiPathTranslated;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiScriptName;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiQueryString;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiRemoteHost;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiRemoteAddr;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiAuthType;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiRemoteUser;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiRemoteIdent;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiContentType;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiAccept;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiUserAgent;
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiReferrer;
+
+/* Cookies as sent to the server. You can also get them
+	individually, or as a string array; see the documentation. */
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiCookie;
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+char *cgiSid;
+
+/* A macro providing the same incorrect spelling that is
+	found in the HTTP/CGI specifications */
+#define cgiReferer cgiReferrer
+
+/* The number of bytes of data received.
+	Note that if the submission is a form submission
+	the library will read and parse all the information
+	directly from cgiIn; the programmer need not do so. */
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+int cgiContentLength;
+
+/* Pointer to CGI output. The cgiHeader functions should be used
+	first to output the mime headers; the output HTML
+	page, GIF image or other web document should then be written
+	to cgiOut by the programmer. In the standard CGIC library,
+	cgiOut is always equivalent to stdout. */
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+FILE *cgiOut;
+
+/* Pointer to CGI input. The programmer does not read from this.
+	We have continued to export it for backwards compatibility
+	so that cgic 1.x applications link properly. */
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+FILE *cgiIn;
+
+/* Possible return codes from the cgiForm family of functions (see below). */
+
+typedef enum {
+	cgiFormSuccess,
+	cgiFormTruncated,
+	cgiFormBadType,
+	cgiFormEmpty,
+	cgiFormNotFound,
+	cgiFormConstrained,
+	cgiFormNoSuchChoice,
+	cgiFormMemory,
+	cgiFormNoFileName,
+	cgiFormNoContentType,
+	cgiFormNotAFile,
+	cgiFormOpenFailed,
+	cgiFormIO,
+	cgiFormEOF
+} cgiFormResultType;
+
+/* These functions are used to retrieve form data. See
+	cgic.html for documentation. */
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormString(
+	char *name, char *result, int max);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormStringNoNewlines(
+	char *name, char *result, int max);
+
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormStringSpaceNeeded(
+	char *name, int *length);
+
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormStringMultiple(
+	char *name, char ***ptrToStringArray);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiStringArrayFree(char **stringArray);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormInteger(
+	char *name, int *result, int defaultV);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormIntegerBounded(
+	char *name, int *result, int min, int max, int defaultV);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormDouble(
+	char *name, double *result, double defaultV);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormDoubleBounded(
+	char *name, double *result, double min, double max, double defaultV);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormSelectSingle(
+	char *name, char **choicesText, int choicesTotal, 
+	int *result, int defaultV);	
+
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormSelectMultiple(
+	char *name, char **choicesText, int choicesTotal, 
+	int *result, int *invalid);
+
+/* Just an alias; users have asked for this */
+#define cgiFormSubmitClicked cgiFormCheckboxSingle
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormCheckboxSingle(
+	char *name);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormCheckboxMultiple(
+	char *name, char **valuesText, int valuesTotal, 
+	int *result, int *invalid);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormRadio(
+	char *name, char **valuesText, int valuesTotal, 
+	int *result, int defaultV);	
+
+/* The paths returned by this function are the original names of files
+	as reported by the uploading web browser and shoult NOT be
+	blindly assumed to be "safe" names for server-side use! */
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileName(
+	char *name, char *result, int max);
+
+/* The content type of the uploaded file, as reported by the browser.
+	It should NOT be assumed that browsers will never falsify
+	such information. */
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileContentType(
+	char *name, char *result, int max);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileSize(
+	char *name, int *sizeP);
+
+typedef struct cgiFileStruct *cgiFilePtr;
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileOpen(
+	char *name, cgiFilePtr *cfpp);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileRead(
+	cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormFileClose(
+	cgiFilePtr cfp);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiCookieString(
+	char *name, char *result, int max);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiCookieInteger(
+	char *name, int *result, int defaultV);
+
+cgiFormResultType cgiCookies(
+	char ***ptrToStringArray);
+
+/* path can be null or empty in which case a path of / (entire site) is set. 
+	domain can be a single web site; if it is an entire domain, such as
+	'boutell.com', it should begin with a dot: '.boutell.com' */
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiHeaderCookieSetString(char *name, char *value, 
+	int secondsToLive, char *path, char *domain);
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiHeaderCookieSetInteger(char *name, int value,
+	int secondsToLive, char *path, char *domain);
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiHeaderLocation(char *redirectUrl);
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiHeaderStatus(int status, char *statusMessage);
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+void cgiHeaderContentType(char *mimeType);
+
+typedef enum {
+	cgiEnvironmentIO,
+	cgiEnvironmentMemory,
+	cgiEnvironmentSuccess,
+	cgiEnvironmentWrongVersion
+} cgiEnvironmentResultType;
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiEnvironmentResultType cgiWriteEnvironment(char *filename);
+extern cgiEnvironmentResultType cgiReadEnvironment(char *filename);
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+int cgiMain();
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+int cgiMain_init();
+
+
+extern 
+#ifdef __cplusplus
+"C" 
+#endif
+cgiFormResultType cgiFormEntries(
+	char ***ptrToStringArray);
+
+/* Output string with the <, &, and > characters HTML-escaped. 
+	's' is null-terminated. Returns cgiFormIO in the event
+	of error, cgiFormSuccess otherwise. */
+cgiFormResultType cgiHtmlEscape(char *s);
+
+/* Output data with the <, &, and > characters HTML-escaped. 
+	'data' is not null-terminated; 'len' is the number of
+	bytes in 'data'. Returns cgiFormIO in the event
+	of error, cgiFormSuccess otherwise. */
+cgiFormResultType cgiHtmlEscapeData(char *data, int len);
+
+/* Output string with the " character HTML-escaped, and no
+	other characters escaped. This is useful when outputting
+	the contents of a tag attribute such as 'href' or 'src'.
+	's' is null-terminated. Returns cgiFormIO in the event
+	of error, cgiFormSuccess otherwise. */
+cgiFormResultType cgiValueEscape(char *s);
+
+/* Output data with the " character HTML-escaped, and no
+	other characters escaped. This is useful when outputting
+	the contents of a tag attribute such as 'href' or 'src'.
+	'data' is not null-terminated; 'len' is the number of
+	bytes in 'data'. Returns cgiFormIO in the event
+	of error, cgiFormSuccess otherwise. */
+cgiFormResultType cgiValueEscapeData(char *data, int len);
+
+#endif /* CGI_C */
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.html
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.html	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgic.html	(revision 672)
@@ -0,0 +1,2116 @@
+<html>
+<head>
+<title>cgic: an ANSI C library for CGI Programming</title>
+</head>
+<body>
+<h1>cgic 2.05: an ANSI C library for CGI Programming</h1>
+<h2>By <a href="http://www.boutell.com/boutell/">Thomas Boutell</a></h2>
+<em><a href="http://www.boutell.com/cgic/">
+The LATEST documentation is available here. Check often
+for new releases.</a></em>
+<blockquote>
+<strong>IMPORTANT NOTICES:</strong>
+<p>
+If you have CGIC 1.05 or earlier, you should upgrade to CGIC 1.07,
+or to CGIC 2.02 or better, in order to obtain important security fixes.
+<p>
+If you have CGIC 2.0 or CGIC 2.01 and you use the cgiCookie routines, 
+you should upgrade to CGIC 2.02 or better, in order to obtain
+important security fixes.
+</blockquote>
+<h3>Table of Contents</h3>
+<ul>
+<li><a href="#credits">Credits and license terms</a>
+<li><a href="#support">How to get support</a>
+<li><a href="#whatsnew205">What's new in version XYZ of CGIC?</a>
+<li><a href="#whatis">What is cgic?</a>
+<li><a href="#obtain">Obtaining cgic</a>
+<li><a href="#build">Building and testing cgic: a sample application</a>
+<li><a href="#nocompile">What to do if it won't compile</a>
+<li><a href="#howto">How to write a cgic application</a>
+<li><a href="#images">How can I generate images from my cgic application?</a>
+<li><a href="#debug">CGI debugging features: using capture</a>
+<li><a href="#functions">cgic function reference</a>
+<li><a href="#variables">cgic variable reference</a>
+<li><a href="#resultcodes">cgic result code reference</a>
+<li><a href="#index">cgic quick index</a>
+</ul>
+
+<h3><a name="credits">Credits and License Terms</a></h3>
+
+cgic can be used free of charge, <strong>provided that a
+credit notice is provided online.</strong> Alternatively,
+a nonexclusive Commercial License can be purchased, which
+grants the right to use cgic without a public credit notice.
+<p>
+Please see the file
+<code><a href="license.txt">license.txt</a></code>
+for the details of the Basic License and Commercial License,
+including ordering information for the Commercial License.
+<p>
+Thanks are due to Robert Gustavsson, Ken Holervich, Bob Nestor, 
+Jon Ribbens, Thomas Strangert, Wu Yongwei, and other CGIC users 
+who have corresponded over the years. Although the implementation
+of multipart/form-data file upload support in CGIC 2.x is my own, 
+I particularly wish to thank those who submitted their own 
+implementations of this feature.
+<h3><a name="support">How to Get Support</a></h3>
+<blockquote>
+<h4>STOP! READ THIS FIRST! REALLY!</h4>
+    Are you getting a "server error," indicating that your web server
+    "cannot allow POST to this URL," or a similar message? <strong>YOU MUST
+    CONFIGURE YOUR WEB SERVER TO ALLOW CGI PROGRAMS, AND YOU MUST
+    INSTALL CGI PROGRAMS IN THE LOCATION (OR WITH THE EXTENSION) THAT
+    YOUR WEB SERVER EXPECTS TO SEE.</strong> Please don't send me email about
+    this, unless you wish me to configure your web server for you; I can
+    certainly do that for $50/hr, but you can probably straighten this out
+    yourself or have your web server administrator do it.
+</blockquote>
+<h4>Free Support</h4>
+Please submit support inquiries about CGIC via our                              <a href="http://www.boutell.com/contact/">contact page</a>.
+Please note that we receive a large volume of inquiries and cannot always
+respond personally. Sometimes
+the response must take the form of an eventual
+new release or an addition to a FAQ or other document, as opposed to an
+detailed individual response.
+<h4>Hourly Support</h4>
+Those requiring support in detail may arrange for direct support
+from the author, Thomas Boutell, at the rate of $50/hr, billed
+directly by credit card. To make arrangements, contact us via our
+our <a href="https://www.boutell.com/freeform/">secure
+message page</a>. To avoid delay, be sure to specifically mention
+that you wish to purchase CGIC support at the hourly rate above.
+<h3><a name="whatsnew205">What's new in version 2.05?</a></h3>
+Uploaded files properly closed; corrects a resource leak and enables
+file uploads to work properly on platforms with particular file
+locking semantics.
+<h3><a name="whatsnew204">What's new in version 2.04?</a></h3>
+Documentation fixes: the cgiHtmlEscape, cgiHtmlEscapeData,
+cgiValueEscape, and cgiValueEscapeData routines were named
+incorrectly in the manual. No code changes in version 2.04.
+<h3><a name="whatsnew203">What's new in version 2.03?</a></h3>
+<ul>
+<li>Support for setting cookies has been reimplemented. The new
+code closely follows the actual practice of web sites that successfully
+use cookies, rather than attempting to implement the specification.
+The new code can successfully set more than one cookie at a time in
+typical web browsers.
+</ul>
+<h3><a name="whatsnew202">What's new in version 2.02?</a></h3>
+<ul>
+<li>In CGIC 2.0 and 2.01, if the HTTP_COOKIE environment variable
+was exactly equal to the name of a cookie requested with cgiCookieString,
+with no value or equal sign or other characters present, a buffer
+overrun could take place. This was not normal behavior and it is
+unknown whether any actual web server would allow it to occur, however
+we have of course released a patch to correct it. 
+Thanks to Nicolas Tomadakis.
+<li>cgiCookieString returned cgiFormTruncated when cgiFormSuccess would
+be appropriate. Fixed; thanks to Mathieu Villeneuve-Belair.
+<li>Cookies are now set using a simpler Set-Cookie: header, and with
+one header line per cookie, based on data collected by Chunfu Lai. 
+<li>Memory leaks in cgiReadEnvironment fixed by Merezko Oleg. These
+memory leaks were <em>not</em> experienced in a normal CGI situation, only
+when reading a saved CGI environment.
+</ul>
+<h3><a name="whatsnew201">What's new in version 2.01?</a></h3>
+<ul>
+<li>Makefile supports "make install"
+<li>Compiles without warnings under both C and C++ with strict
+warnings and strict ANSI compliance enabled
+<li>Builds out of the box on Windows (#include &lt;fcntl.h&gt; was needed)
+<li>Rare problem in cgiReadEnvironment corrected; no impact on
+normal CGI operations
+<li>cgiCookieString now sets the result to an empty string
+when returning cgiFormNotFound
+<li>Minor code cleanups
+</ul>
+<h3><a name="whatsnew200">What's new in version 2.0?</a></h3>
+1. CGIC 2.0 provides support for file upload fields. User-uploaded
+files are kept in temporary files, to avoid the use of
+excessive swap space (Solaris users may wish to change the
+<code>cgicTempDir</code> macro in cgic.c before compiling).
+The <code><a href="#cgiFormFileName">cgiFormFileName</a></code>, 
+<code><a href="#cgiFormFileContentType">cgiFormFileContentType</a></code>, 
+<code><a href="#cgiFormFileSize">cgiFormFileSize</a></code>, 
+<code><a href="#cgiFormFileOpen">cgiFormFileOpen</a></code>, 
+<code><a href="#cgiFormFileRead">cgiFormFileRead</a></code>, and
+<code><a href="#cgiFormFileClose">cgiFormFileClose</a></code> functions
+provide a complete interface to this new functionality. Remember,
+the <code>enctype</code> attribute of the <code>form</code> tag
+must be set to <code>multipart/form-data</code> when
+<code>&lt;input type="file"&gt;</code> tags are used.
+<p>
+2. CGIC 2.0 provides support for setting and examining cookies
+(persistent data storage on the browser side).
+The <code><a href="#cgiCookieString">cgiCookieString</a></code>,
+and <code><a href="#cgiCookieInteger">cgiCookieInteger</a></code>
+and <code><a href="#cgiCookies">cgiCookies</a></code>
+functions retrieve cookies. The 
+<code><a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a></code>
+and <code><a href="#cgiHeaderCookieSetInteger">cgiHeaderCookieSetInteger</a></code> functions set cookies.
+<p>
+3. CGIC 2.0 offers a convenient way to retrieve a list of all form fields.
+The new <code><a href="#cgiFormEntries">cgiFormEntries</a></code>
+function performs this operation.
+<p>
+4. CGIC 2.0 provides convenience functions to correctly escape
+text before outputting it as part of HTML, or as part of the 
+value of a tag attribute, such as the <code>HREF</code> or
+<code>VALUE</code> attribute. See 
+<code><a href="#cgiHtmlEscape">cgiHtmlEscape</a></code>,
+<code><a href="#cgiHtmlEscapeData">cgiHtmlEscapeData</a></code>,
+<code><a href="#cgiValueEscape">cgiValueEscape</a></code> and
+<code><a href="#cgiValueEscapeData">cgiValueEscapeData</a></code>.
+<p>
+5. Users have often asked the correct way to determine which submit
+button was clicked. This could always be accomplished in previous versions,
+but CGIC 2.0 also provides 
+<a href="#cgiFormSubmitClicked">cgiFormSubmitClicked</a>,
+a convenient alternate label for the 
+<a href="#cgiFormCheckboxSingle">cgiFormCheckboxSingle</a> function.
+<h3><a name="whatsnew107">What's new in version 1.07?</a></h3>
+A problem with the cgiFormString and related functions has been
+corrected. These functions were previously incorrectly returning cgiFormTruncated
+in cases where the returned string fit the buffer exactly.
+<h3><a name="whatsnew106">What's new in version 1.06?</a></h3>
+1. A potentially significant buffer overflow problem has been
+corrected. Jon Ribbens correctly pointed out to me (and to the
+Internet's bugtraq mailing list) that the cgiFormEntryString
+function, which is used directly or indirectly by almost all
+CGIC programs, can potentially write past the buffer passed
+to it by the programmer. This bug has been corrected.
+Upgrading to version 1.06 is <strong>strongly recommended.</strong>
+<P>
+2. The function <code>cgiSaferSystem()</code> has been
+removed entirely. This function escaped only a few metacharacters,
+while most shells have many, and there was no way to account for
+the many different operating system shells that might be in use
+on different operating systems. Since this led to a false sense
+of security, the function has been removed. It is our recommendation
+that user input should never be passed directly on the command line
+unless it has been carefully shown to contain only characters
+regarded as safe and appropriate by the programmer. Even then, it is
+better to design your utilities to accept their input from standard
+input rather than the command line.
+<h3><a name="whatsnew105">What's new in version 1.05?</a></h3>
+Non-exclusive commercial license fee reduced to $200.
+<h3><a name="whatsnew104">What's new in version 1.04?</a></h3>
+For consistency with other packages, the standard Makefile
+now produces a true library for cgic (libcgic.a). 
+<h3><a name="whatsnew103">What's new in version 1.03?</a></h3>
+Version 1.03 sends line feeds only (ascii 10) to end 
+Content-type:, Status:, and other HTTP protocol output lines,
+instead of CR/LF sequences. The standard specifies CR/LF.
+Unfortunately, too many servers reject CR/LF to make
+implementation of that standard practical. No server
+tested ever rejects LF alone in this context. 
+<h3><a name="whatsnew102">What's new in version 1.02?</a></h3>
+Version 1.02 corrects bugs in previous versions:
+<ul>
+<li>
+<a href="#cgiFormDoubleBounded">cgiFormDoubleBounded</a> specified
+its arguments in the wrong order, with surprising results.
+This bug has been corrected.
+<li>
+Many small changes have been made to increase compatibility.
+cgic now compiles with no warnings under the compilers
+available at boutell.com.
+</ul>
+<h3><a name="whatsnew101">What's new in version 1.01?</a></h3>
+Version 1.01 adds no major functionality but corrects 
+significant bugs and incompatibilities:
+<ul>
+<li>
+<a href="#cgiFormInteger">cgiFormInteger</a>,
+<a href="#cgiFormIntegerBounded">cgiFormIntegerBounded</a>,
+<a href="#cgiFormDouble">cgiFormDouble</a> and
+<a href="#cgiFormDoubleBounded">cgiFormDoubleBounded</a> now
+accept negative numbers properly. They also accept positive
+numbers with an explicit + sign.
+<li>Hex values containing the digit <code>9</code> are
+now properly decoded.
+<li><a href="#cgiFormString">cgiFormString</a> now
+represents each newline as a single line feed (ascii 10 decimal)
+as described in the documentation, not a carriage return
+(ascii 13 decimal) as in version 1.0. The latter approach
+pleased no one.
+<li><a href="#cgiFormString">cgiFormString</a> and
+<a href="#cgiFormStringNoNewlines">cgiFormStringNoNewlines</a>
+no longer erroneously return cgiFormEmpty in place of
+cgiFormSuccess.
+<li>The main() function of cgic now flushes standard output
+and sleeps for one second before exiting in order to inhibit
+problems with the completion of I/O on some platforms. This was
+not a cgic bug per se, but has been reported as a common problem
+with CGI when used with the CERN server. This change should
+improve compatibility.
+<li>The single selection example in the testform.html
+example now works properly. This was an error in the
+form itself, not cgic.
+<li><a href="#cgiRemoteUser">cgiRemoteUser</a> and
+<a href="#cgiRemoteIdent">cgiRemoteIdent</a> are now
+documented accurately. They were reversed earlier.
+</ul>
+<h3><a name="whatis">What is cgic?</a></h3>
+cgic is an ANSI C-language library for the creation of CGI-based
+World Wide Web applications. For basic information about
+the CGI standard, see the <a href="http://hoohoo.ncsa.uiuc.edu/cgi/">
+CGI documentation</a> at NCSA.
+<p>
+cgic performs the following tasks:
+<ul>
+<li>Parses form data, correcting for defective and/or inconsistent browsers
+<li>Transparently accepts both GET and POST form data
+<li>Accepts uploaded files as well as regular form fields
+<li>Provides functions to set and retrieve "cookies"
+(browser-side persistent information)
+<li>Handles line breaks in form fields in a consistent manner
+<li>Provides string, integer, floating-point, and single- and
+multiple-choice functions to retrieve form data
+<li>Provides bounds checking for numeric fields
+<li>Loads CGI environment variables into C strings which are always non-null
+<li>Provides a way to capture CGI situations for replay in a debugging
+environment, including file uploads and cookies
+</ul>
+<p>
+cgic is compatible with any CGI-compliant server environment, and
+compiles without modification in Posix/Unix/Linux and Windows
+environments.
+<h3><a name="obtain">Obtaining cgic</a></h3>
+cgic is distributed via the web in two forms: as a Windows-compatible
+.ZIP file, and as a gzipped tar file. Most users of Windows and
+related operating systems have access to 'unzip' or 'pkunzip'. All modern Unix 
+systems come with 'gunzip' and 'tar' as standard equipment, and gzip/gunzip
+is not difficult to find if yours does not. Versions
+of these programs for other operating systems are widely
+available if you do not already have them.
+<p>
+<strong>Important:</strong> to use cgic, you will need an ANSI-standard
+C compiler. Under Unix, just obtain and use gcc. Most Unix systems have
+standardiszed on gcc. Users of Windows operating systems should not have
+ANSI C-related problems as all of the popular compilers follow the ANSI 
+standard.
+<p>
+<strong>Note for Windows Programmers:</strong> you must use a modern
+32-bit compiler. Visual C++ 2.0 or higher, Borland C++ and the
+mingw32 gcc compiler are all appropriate, as is cygwin. Do 
+<strong>NOT</strong> use an ancient 16-bit DOS executable compiler, please.
+<blockquote>
+<h4>What Operating System Does Your WEB SERVER Run?</h4>
+Remember, the computer on your desk is usually NOT your web server.
+Compiling a Windows console executable will not give you a CGI program that
+can be installed on a Linux-based server. 
+</blockquote>
+Your web browser should inquire whether to save the file to disk
+when you select one of the links below. Under Unix and compatible
+operating systems, save it, then issue the following
+commands to unpack it:
+<pre>
+gunzip cgic205.tar.gz
+tar -xf cgic205.tar
+</pre>
+This should produce the subdirectory 'cgic205', which will contain
+the complete cgic distribution for version 2.05, including a copy of this 
+documentation in the file cgic.html.
+<p>
+Under Windows and compatible operating systems, save it,
+open a console ("DOS") window, and issue the following commands to unpack it:
+<pre>
+unzip /d cgic205.zip
+</pre>
+Or use the unzip utility of your choice.
+<p>
+This command also produces the subdirectory 'cgic205', which will contain
+the complete cgic distribution for version 2.0, including a copy of this 
+documentation in the file cgic.html.
+<p>
+cgic is available via the web from www.boutell.com:
+<ul>
+<li><a href="http://www.boutell.com/cgic/cgic205.tar.gz">Obtain cgic: gzipped tar file</a>
+<li><a href="http://www.boutell.com/cgic/cgic205.zip">Obtain cgic: .ZIP file</a>
+</ul>
+<h3><a name="build">Building cgic: a sample application</a></h3>
+The sample application 'cgictest.c' is provided as part of the
+cgic distribution. This CGI program displays an input form, 
+accepts a submission, and then displays what was submitted.
+In the process essentially all of cgic's features are tested.
+<p>
+On a Unix system, you can build cgictest simply by typing
+'make cgictest.cgi'. cgic.c and cgictest.c will be compiled and linked
+together to produce the cgictest application. Under non-Unix
+operating systems, you will need to create and compile an appropriate
+project containing the files cgic.c and cgictest.c. 
+<p>
+<strong>IMPORTANT:</strong> after compiling cgictest.cgi, you will
+need to place it in a location on your server system which is
+designated by your server administrator as an appropriate location
+for CGI scripts. Some servers are configured to recognize any
+file ending in .cgi as a CGI program when it is found in any
+subdirectory of the server's web space, but this is not always
+the case! The right locations for CGI
+programs vary greatly from one server to another. Resolving
+this issue is between you, your web server administrator,
+and your web server documentation. Before submitting a bug
+report for cgic, make certain that the CGI example programs
+which came with your server <em>do</em> work for you. Otherwise
+it is very likely that you have a server configuration problem.
+<p>
+Once you have moved cgictest.cgi (or cgictest.exe, under Windows)
+to an appropriate cgi directory,
+use the web browser of your choice to access the URL at which
+you have installed it 
+(for instance, <code>www.mysite.com/cgi-bin/cgictest.cgi</code>).
+Fill out the various fields in any manner you wish, then
+select the SUBMIT button.
+<p>
+If all goes well, cgictest.cgi will respond with a page which
+indicates the various settings you submitted. If not,
+please reread the section above regarding the correct location in
+which to install your CGI program on your web server.
+<h3><a name="nocompile">What to do if it won't compile</a></h3>
+<ul>
+<li><strong>Are you using Visual C++ or Borland C++? Did you forget to add
+cgic.c to your project?</strong>
+<li><strong>Make sure you are using an ANSI C or C++ compiler.</strong>
+(All of the Windows compilers are ANSI C compliant.)
+</ul>
+If none of the above proves effective, please see the
+section regarding <a href="#support">support</a>.
+<h3><a name="howto">How to write a cgic application</a></h3>
+<em>Note: </em> All cgic applications must be linked to the cgic.c module
+itself. How to do this depends on your operating system; under Unix,
+just use the provided Makefile as an example.
+<p>
+Since all CGI applications must perform certain initial
+tasks, such as parsing form data and examining
+environment variables, the cgic library provides its
+own main() function. When you write applications that
+use cgic, you will begin your own programs by writing
+a cgiMain() function, which cgic will invoke when
+the initial cgi work has been successfully completed. Your
+program must also be sure to #include the file cgic.h.
+<p>
+<strong>Important:</strong> if you write your own main()
+function, your program will not link properly. Your own
+code should begin with cgiMain(). The library
+provides main() for you. (Those who prefer different behavior
+can easily modify cgic.c.)
+<p>
+Consider the cgiMain function of cgictest.c:
+<p>
+<PRE>
+int cgiMain() {
+#ifdef DEBUG
+  LoadEnvironment();
+#endif /* DEBUG */
+  /* Load a previously saved CGI scenario if that button
+    has been pressed. */
+  if (cgiFormSubmitClicked("loadenvironment") == cgiFormSuccess) {
+    LoadEnvironment();
+  }
+  /* Set any new cookie requested. Must be done *before*
+    outputting the content type. */
+  CookieSet();
+  /* Send the content type, letting the browser know this is HTML */
+  cgiHeaderContentType("text/html");
+  /* Top of the page */
+  fprintf(cgiOut, "&lt;HTML&gt;&lt;HEAD&gt;\n");
+  fprintf(cgiOut, "&lt;TITLE&gt;cgic test&lt;/TITLE&gt;&lt;/HEAD&gt;\n");
+  fprintf(cgiOut, "&lt;BODY&gt;&lt;H1&gt;cgic test&lt;/H1&gt;\n");
+  /* If a submit button has already been clicked, act on the 
+    submission of the form. */
+  if ((cgiFormSubmitClicked("testcgic") == cgiFormSuccess) ||
+    cgiFormSubmitClicked("saveenvironment") == cgiFormSuccess)
+  {
+    HandleSubmit();
+    fprintf(cgiOut, "&lt;hr&gt;\n");
+  }
+  /* Now show the form */
+  ShowForm();
+  /* Finish up the page */
+  fprintf(cgiOut, "&lt;/BODY&gt;&lt;/HTML&gt;\n");
+  return 0;
+}
+</PRE>
+Note the DEBUG #ifdef. If DEBUG is defined at compile time, either by
+inserting the line "#define DEBUG 1" into the program or by setting
+it in the Makefile or other development environment, then the
+LoadEnvironment function is invoked. This function calls 
+<a href="#cgiReadEnvironment">cgiReadEnvironment()</a> 
+to restore a captured CGI environment for debugging purposes. See
+also the discussion of the <a href="#debug">capture</a> program, which is
+provided for use in CGI debugging. Because this is a test program,
+the <a href="#cgiFormSubmitClicked">cgiFormSubmitClicked</a> function is
+also called to check for the use of a button that requests the reloading
+of a saved CGI environment. A completed CGI program typically would
+never allow the end user to make that decision.
+<h4>Setting Cookies</h4>
+Next, one of the cgiHeader functions should be called.
+This particular program demonstrates many features, including
+the setting of cookies. If the programmer wishes to set a cookie,
+the cookie-setting function must be called
+first, before other headers are output. This is done by the
+CookieSet() function of cgictest.c:
+<pre>
+void CookieSet()
+{
+  char cname[1024];
+  char cvalue[1024];
+  /* Must set cookies BEFORE calling 
+    cgiHeaderContentType */
+  cgiFormString("cname", cname, sizeof(cname));  
+  cgiFormString("cvalue", cvalue, sizeof(cvalue));  
+  if (strlen(cname)) {
+    /* Cookie lives for one day (or until 
+      browser chooses to get rid of it, which 
+      may be immediately), and applies only to 
+      this script on this site. */  
+    cgiHeaderCookieSetString(cname, cvalue,
+      86400, cgiScriptName, cgiServerName);
+  }
+}
+</pre>
+Since this is a test program, the <a href="#cgiFormString">cgiFormString</a> 
+function is used to fetch the name and value from the form previously filled
+in by the user. Normally, cookie names and values are chosen to meet the
+needs of the programmer and provide a means of identifying the same
+user again later.
+<p>
+The <a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>
+function sets the cookie by requesting that the web browser store it.
+<strong>There is never any guarantee that this will happen!</strong>
+Many browsers reject cookies completely; others do not necessarily keep
+them as long as requested or return them with their values intact.
+Always code defensively when using cookies.
+<p>
+The cname and cvalue parameters are of course the namd and value for
+the cookie. The third argument is the time, in seconds, that the
+cookie should "live" on the browser side before it expires; in this
+case it has been set to 86,400 seconds, which is exactly one day. 
+<strong>The browser may or may not respect this setting, as with everything
+else about cookies.</strong>
+<p>
+The fourth argument identifies the "path" within the web site for which
+the cookie is considered valid. A cookie that should be sent back
+for every access to the site should be set with a path of <code>/</code>.
+In this case the cookie is relevant only to the CGI program itself, so
+<code><a href="#cgiScriptName">cgiScriptName</a></code> (the URL of the CGI program, not including the
+domain name) is sent. Similarly, a cookie can be considered relevant
+to a single web site or to an entire domain, such as 
+<code>www.boutell.com</code> or the entire <code>.boutell.com</code>
+domain. In this case, the current site on which the program is running
+is the only relevant site, so <code><a href="#cgiServerName">cgiServerName</a></code> is used
+as the domain.
+<h4>Outputting the Content Type Header</h4>
+Next, <a href="#cgiHeaderContentType">cgiHeaderContentType()</a> is 
+called to indicate the MIME type of the document being output, in this case 
+"text/html" (a normal HTML document). A few other common MIME types are
+"image/gif", "image/jpeg" and "audio/wav". 
+<p>
+Note that <a href="#cgiHeaderStatus">cgiHeaderStatus()</a> or 
+<a href="#cgiHeaderLocation">cgiHeaderLocation()</a> could have
+been invoked instead to output an error code or redirect the
+request to a different URL. Only one of the cgiHeader functions
+should be called in a single execution of the program.
+<p>
+<strong>Important:</strong> one of the cgiHeader functions,
+usually <a href="#cgiHeaderContentType">cgiHeaderContentType()</a>, 
+<em>must</em> be invoked before outputting any other
+response to the user. Otherwise, the result will not be a valid
+document and the browser's behavior will be unpredictable.
+You may, of course, output your own ContentType and other
+header information to <a href="#cgiOut">cgiOut</a> if you prefer. The cgiHeader functions
+are provided as a convenience.
+<h4>Handling Form Submissions</h4>
+Like many CGI programs, cgictest makes decisions about the way it
+should behave based on whether various submit buttons have been clicked.
+When either the testcgic or saveenvironment button is present, cgictest
+invokes the HandleSubmit function, which invokes additional functions to
+handle various parts of the form:
+<pre>
+void HandleSubmit()
+{
+  Name();
+  Address();
+  Hungry();
+  Temperature();
+  Frogs();
+  Color();
+  Flavors();
+  NonExButtons();
+  RadioButtons();
+  File();
+  Entries();
+  Cookies();
+  /* The saveenvironment button, in addition to submitting 
+    the form, also saves the resulting CGI scenario to 
+    disk for later replay with the 'load saved environment' 
+    button. */
+  if (cgiFormSubmitClicked("saveenvironment") == cgiFormSuccess) {
+    SaveEnvironment();
+  }
+}
+</pre>
+<h4>Handling Text Input</h4>
+The Name() function of cgictest is shown below, in its simplest
+possible form:
+<PRE>
+void Name() {
+        char name[81];
+        <a href="#cgiFormStringNoNewlines">cgiFormStringNoNewlines</a>("name", name, 81);
+        fprintf(cgiOut, "Name: ");
+        cgicHtmlEscape(name);
+        fprintf(cgiOut, "<BR>\n");
+}
+</PRE>
+The purpose of this function is to retrieve and display the name that was
+input by the user. Since the programmer has decided that names should
+be permitted to have up to 80 characters, a buffer of 81 characters
+has been declared (allowing for the final null character). 
+The <a href="#cgiFormStringNoNewlines">cgiFormStringNoNewlines()</a>
+function is then invoked to retrieve the name and ensure that
+carriage returns are not present in the name (despite the
+incorrect behavior of some web browsers). The first argument
+is the name of the input field in the form, the second argument
+is the buffer to which the data should be copied, and the third
+argument is the size of the buffer. cgic will never write beyond
+the size of the buffer, and will always provide a null-terminated
+string in response; if the buffer is too small, the string will
+be shortened. If this is not acceptable, the
+<a href="#cgiFormStringSpaceNeeded">cgiFormStringSpaceNeeded()</a>
+function can be used to check the amount of space needed; the
+return value of cgiFormStringNoNewlines() can also be checked
+to determine whether truncation occurred. See
+the full description of <a href="#cgiFormStringNoNewlines">
+cgiFormStringNoNewlines()</a>.
+<h4>Handling Output</h4>
+Note that Name() writes its HTML output to <a href="#cgiOut">cgiOut</a>, not
+to stdout.
+<p>
+The actual name submitted by the user may or may not contain
+characters that have special meaning in HTML, specifically the
+the <code>&lt;</code>, <code>&gt;</code>, and <code>&amp;</code> characters.
+The <a href="#cgiHtmlEscape">cgiHtmlEscape</a> function is used to output
+the user-entered name with any occurrences of these characters
+correctly escaped as <code>&amp;lt;</code>, <code>&amp;gt;</code>, 
+and <code>&amp;amp;</code>.
+<p>
+<strong>Important:</strong> <a href="#cgiOut">cgiOut</a> is normally equivalent
+to stdout, and there is no performance penalty for using it.
+It is recommended that you write output to <a href="#cgiOut">cgiOut</a> to ensure compatibility
+with modified versions of the cgic library for special
+environments that do not provide stdin and stdout for
+each cgi connection.
+<p>
+Note that, for text input areas in which carriage returns <em>are</em>
+desired, the function <a href="#cgiFormString">cgiFormString</a>
+should be used instead. cgiFormString ensures that line breaks
+are always represented by a single carriage return (ascii decimal 13),
+making life easier for the programmer. See the source code to
+the Address() function of cgictest.c for an example.
+<h4>Handling Single Checkboxes</h4>
+Consider the Hungry() function, which determines whether
+the user has selected the "hungry" checkbox:
+<PRE>
+void Hungry() {
+        if (<a href="#cgiFormCheckboxSingle">cgiFormCheckboxSingle</a>("hungry") == <a href="#cgiFormSuccess">cgiFormSuccess</a>) {
+                fprintf(cgiOut, "I'm Hungry!&lt;BR&gt;\n");
+        } else {
+                fprintf(cgiOut, "I'm Not Hungry!&lt;BR&gt;\n");
+        }
+}
+</PRE>
+This function takes advantage of the
+<a href="#cgiFormCheckboxSingle">cgiFormCheckboxSingle()</a> function, which
+determines whether a single checkbox has been selected. 
+cgiFormCheckboxSingle() accepts the name attribute of the checkbox
+as its sole argument and returns <a href="#cgiFormSuccess">
+cgiFormSuccess</a> if the checkbox is selected, or 
+<a href="#cgiFormNotFound">cgiFormNotFound</a> if it is not.
+If multiple checkboxes with the same name are in use,
+consider the <a href="#cgiFormCheckboxMultiple">
+cgiFormCheckboxMultiple()</a> and 
+<a href="#cgiFormStringMultiple">cgiFormStringMultiple()</a>
+functions.
+<h4>Handling Numeric Input</h4>
+Now consider the Temperature() function, which retrieves
+a temperature in degrees (a floating-point value) and ensures
+that it lies within particular bounds:
+<PRE>
+void Temperature() {
+        double temperature;
+        <a href="#cgiFormDoubleBounded">cgiFormDoubleBounded</a>("temperature", &amp;temperature, 80.0, 120.0, 98.6);
+        fprintf(<a href="#cgiOut">cgiOut</a>, "My temperature is %f.&lt;BR&gt;\n", temperature);
+}
+</PRE>
+The temperature is retrieved by the function 
+<a href="#cgiFormDoubleBounded">cgiFormDoubleBounded()</a>. The first
+argument is the name of the temperature input field in the form;
+the second argument points to the address of the variable that will 
+contain the result. The next two arguments are the lower and upper
+bounds, respectively. The final argument is the default value to
+be returned if the user did not submit a value.
+<p>
+This function always retrieves a reasonable value within the
+specified bounds; values above or below bounds are constrained
+to fit the bounds. However, the return value of
+cgiFormDoubleBounded can be checked to make sure the
+actual user entry was in bounds, not blank, and so forth;
+see the description of <a href="#cgiFormDoubleBounded">
+cgiFormDoubleBounded()</a> for more details. If bounds checking
+is not desired, consider using <a href="#cgiFormDouble">
+cgiFormDouble()</a> instead.
+<p>
+Note that, for integer input, the functions
+<a href="#cgiFormInteger">cgiFormInteger</a> and
+<a href="#cgiFormIntegerBounded">cgiFormIntegerBounded</a>
+are available. The behavior of these functions is similar to
+that of their floating-point counterparts above.
+<h4>Handling Single-Choice Input</h4>
+The &lt;SELECT&gt; tag of HTML is used to provide the user with
+several choices. Radio buttons and checkboxes can also be used
+when the number of choices is relatively small. Consider
+the Color() function of cgictest.c:
+<PRE>
+char *colors[] = {
+        "Red",
+        "Green",
+        "Blue"
+};
+
+void Color() {
+        int colorChoice;
+        <a href="#cgiFormSelectSingle">cgiFormSelectSingle</a>("colors", colors, 3, &amp;colorChoice, 0);
+        fprintf(<a href="#cgiOut">cgiOut</a>, "I am: %s&lt;BR&gt;\n", colors[colorChoice]);
+}
+</PRE>
+This function determines which of several colors the user chose
+from a &lt;SELECT&gt; list in the form. An array of colors is
+declared; the <a href="#cgiFormSelectSingle">cgiFormSelectSingle()</a>
+function is then invoked to determine which, if any, of those choices
+was selected. The first argument indicates the name of the input
+field in the form. The second argument points to the list of
+acceptable colors. The third argument indicates the number of
+entries in the color array. The fourth argument points to the
+variable which will accept the chosen color, and the last argument
+indicates the index of the default value to be set if no
+selection was submitted by the browser. 
+<p>
+<a href="#cgiFormSelectSingle">cgiFormSelectSingle()</a> will
+always indicate a reasonable selection value. However, if
+the programmer wishes to know for certain that a value was
+actually submitted, that the value submitted was a legal
+response, and so on, the return value of cgiFormSelectSingle()
+can be consulted. See the full description of
+<a href="#cgiFormSelectSingle">cgiFormSelectSingle()</a> for
+more information.
+<p>
+Note that radio button groups and &lt;SELECT&gt; lists can both
+be handled by this function. If you are processing radio
+button groups, you may prefer to invoke 
+<a href="#cgiFormRadio">cgiFormRadio()</a>, which functions
+identically. 
+<p>
+<em>"What if I won't know the acceptable choices at runtime?"</em>
+<p>
+If the acceptable choices aren't known <em>until</em> runtime,
+one can simply load the choices from disk. But if the acceptable
+choices aren't fixed at all (consider a list of country names;
+new names may be added to the form at any time and it is
+inconvenient to also update program code or a separate list
+of countries), simply invoke 
+<a href="#cgiFormStringNoNewlines">cgiFormStringNoNewlines()</a>
+instead to retrieve the string directly. Keep in mind that, if
+you do so, validating the response to make sure it is
+safe and legitimate becomes a problem for your own
+program to solve. The advantage of cgiFormSelectSingle() is that invalid 
+responses are never returned.
+<p>
+To handle multiple-selection &lt;SELECT&gt; lists and
+groups of checkboxes with the same name, see the
+discussion of the NonExButtons() function of cgictest.c, immediately below.
+<h4>Handling Multiple-Choice Input</h4>
+Consider the first half of the NonExButtons() function of cgictest.c:
+<PRE>
+char *votes[] = {
+  "A",
+  "B",
+  "C",
+  "D"
+};
+
+void NonExButtons() {
+  int voteChoices[4];
+  int i;
+  int result;  
+  int invalid;
+
+  char **responses;
+
+  /* Method #1: check for valid votes. This is a good idea,
+    since votes for nonexistent candidates should probably
+    be discounted... */
+  fprintf(<a href="#cgiOut">cgiOut</a>, "Votes (method 1):&lt;BR&gt;\n");
+  result = <a href="#cgiFormCheckboxMultiple">cgiFormCheckboxMultiple</a>("vote", votes, 4, 
+    voteChoices, &amp;invalid);
+  if (result == <a href="#cgiFormNotFound">cgiFormNotFound</a>) {
+    fprintf(<a href="#cgiOut">cgiOut</a>, "I hate them all!&lt;p&gt;\n");
+  } else {  
+    fprintf(<a href="#cgiOut">cgiOut</a>, "My preferred candidates are:\n");
+    fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;ul&gt;\n");
+    for (i=0; (i &lt; 4); i++) {
+      if (voteChoices[i]) {
+        fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;li&gt;%s\n", votes[i]);
+      }
+    }
+    fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;/ul&gt;\n");
+  }
+</PRE>
+This function takes advantage of
+<a href="#cgiFormCheckboxMultiple">cgiFormCheckboxMultiple()</a>,
+which is used to identify one or more selected checkboxes with 
+the same name. This function performs identically to
+<a href="#cgiFormSelectMultiple">cgiFormSelectMultiple()</a>.
+That is, &lt;SELECT&gt; tags with the MULTIPLE attribute are handled
+just like a group of several checkboxes with the same name.
+<p>
+The first argument to <a href="#cgiFormCheckboxMultiple">
+cgiFormCheckboxMultiple()</a> is the name given to all
+checkbox input fields in the group. The second argument
+points to an array of legitimate values; these should
+correspond to the VALUE attributes of the checkboxes
+(or OPTION tags in a &lt;SELECT&gt; list). The third argument
+indicates the number of entries in the array of
+legitimate values. The fourth argument points to
+an array of integers with the same number of entries
+as the array of legitimate values; each entry
+will be set true if that checkbox or option was selected,
+false otherwise.
+<p>
+The last argument points to an integer which will be set to the 
+number of invalid responses (responses not in the array of
+valid responses) that were submitted. If this value is not
+of interest, the last argument may be a null pointer (0).
+<p>
+Note that the return value of cgiFormCheckboxMultiple is
+inspected to determine whether any choices at all were
+set. See the full description of
+<a href="#cgiFormCheckboxMultiple">cgiFormCheckboxMultiple</a>
+for other possible return values. 
+<p>
+<em>"What if I won't know the acceptable choices at runtime?"</em>
+<p>
+If the acceptable choices aren't known <em>until</em> runtime,
+one can simply load the choices from disk. But if the acceptable
+choices aren't fixed at all (consider a list of ice cream flavors;
+new names may be added to the form at any time and it is
+inconvenient to also update program code or a separate list
+of countries), a more dynamic approach is needed. Consider
+the second half of the NonExButtons() function of cgictest.c:
+<PRE>
+  /* Method #2: get all the names voted for and trust them.
+    This is good if the form will change more often
+    than the code and invented responses are not a danger
+    or can be checked in some other way. */
+  fprintf(<a href="#cgiOut">cgiOut</a>, "Votes (method 2):&lt;BR&gt;\n");
+  result = <a href="#cgiFormStringMultiple">cgiFormStringMultiple</a>("vote", &amp;responses);
+  if (result == <a href="#cgiFormNotFound">cgiFormNotFound</a>) {  
+    fprintf(<a href="#cgiOut">cgiOut</a>, "I hate them all!&lt;p&gt;\n");
+  } else {
+    int i = 0;
+    fprintf(<a href="#cgiOut">cgiOut</a>, "My preferred candidates are:\n");
+    fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;ul&gt;\n");
+    while (responses[i]) {
+      fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;li&gt;%s\n", responses[i]);
+      i++;
+    }
+    fprintf(<a href="#cgiOut">cgiOut</a>, "&lt;/ul&gt;\n");
+  }
+  /* We must be sure to free the string array or a memory
+    leak will occur. Simply calling free() would free
+    the array but not the individual strings. The
+    function cgiStringArrayFree() does the job completely. */  
+  <A HREF="#cgiStringArrayFree">cgiStringArrayFree</a>(responses);
+}
+</PRE>
+This code excerpt demonstrates an alternate means of retrieving
+a list of choices. The function
+<a href="#cgiFormStringMultiple">cgiFormStringMultiple()</a> is used
+to retrieve an array consisting of all the strings submitted
+for with a particular input field name. This works both for
+&lt;SELECT&gt; tags with the MULTIPLE attribute and for 
+groups of checkboxes with the same name. 
+<P>
+The first argument to <a href="#cgiFormStringMultiple">
+cgiFormStringMultiple()</a> is the name of the input field or
+group of input fields in question. The second argument should
+be the address of a pointer to a pointer to a string, which
+isn't as bad as it sounds. Consider the following simple call
+of the function:
+<PRE>
+/* An array of strings; each C string is an array of characters */
+char **responses; 
+
+<a href="#cgiFormStringMultiple">cgiFormStringMultiple</a>("vote", &amp;responses);
+</PRE>
+<em>"How do I know how many responses there are?"</em>
+<p>
+After the call, the last entry in the string array will be
+a null pointer. Thus the simple loop:
+<PRE>
+int i = 0;
+while (responses[i]) {
+  /* Do something with the string responses[i] */
+  i++;
+}
+</PRE>
+can be used to walk through the array until the last
+entry is encountered.
+<p>
+<strong>Important:</strong> the 
+<a href="#cgiFormStringMultiple">cgiFormStringMultiple</a> function
+returns a pointer to <strong>allocated memory</strong>. Your code
+should not modify the strings in the responses array or the responses
+array itself; if modification is needed, the strings should be
+copied. When your code is done examining the responses array,
+you <strong>MUST</strong> call <a href="#cgiStringArrayFree">
+cgiStringArrayFree()</a> with the array as an argument to free the memory 
+associated with the array. Otherwise, the memory will not be available 
+again until the program exists. <strong>Don't</strong> just call the 
+free() function; if you do, the individual strings will not be freed.
+<h4>Accessing Uploaded Files</h4>
+CGIC provides functions to access files that have been uploaded
+as part of a form submission. <strong>IMPORTANT: you MUST</strong> set
+the <code>enctype</code> attribute of your <code>form</code> tag
+to <code>multipart/form-data</code> for this feature to work! For an
+example, see the <a href="#ShowForm">ShowForm</a> function of 
+cgictest.c, examined below.
+<p>
+The <code>File</code> function of cgictest.c takes care of 
+receiving uploaded files:
+<pre>
+void File()
+{
+  cgiFilePtr file;
+  char name[1024];
+  char contentType[1024];
+  char buffer[1024];
+  int size;
+  int got;
+  if (cgiFormFileName("file", name, sizeof(name)) != 
+    cgiFormSuccess) 
+  {
+    printf("&lt;p&gt;No file was uploaded.&lt;p&gt;\n");
+    return;
+  } 
+        fprintf(cgiOut, "The filename submitted was: ");
+        cgiHtmlEscape(name);
+        fprintf(cgiOut, "&lt;p&gt;\n");
+        cgiFormFileSize("file", &size);
+        fprintf(cgiOut, "The file size was: %d bytes&lt;p&gt;\n", size);
+        cgiFormFileContentType("file", contentType, sizeof(contentType));
+        fprintf(cgiOut, "The alleged content type of the file was: ");
+        cgiHtmlEscape(contentType);
+        fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Of course, this is only the claim the browser "
+    "made when uploading the file. Much like the filename, "
+    "it cannot be trusted.&lt;p&gt;\n");
+  fprintf(cgiOut, "The file's contents are shown here:&lt;p&gt;\n");
+  if (cgiFormFileOpen("file", &file) != cgiFormSuccess) {
+    fprintf(cgiOut, "Could not open the file.&lt;p&gt;\n");
+    return;
+  }
+  fprintf(cgiOut, "&lt;pre&gt;\n");
+  while (cgiFormFileRead(file, buffer, sizeof(buffer), &got) ==
+    cgiFormSuccess)
+  {
+    cgiHtmlEscapeData(buffer, got);
+  }
+  fprintf(cgiOut, "&lt;/pre&gt;\n");
+  cgiFormFileClose(file);
+}
+</pre>
+First, the File function checks to determine the filename that was
+submitted by the user. <strong>VERY IMPORTANT: this filename may or
+may not bear any relation to the real name of the file on the user's
+computer, may be deliberately manipulated with malicious intent,</strong>
+and should not be used for <strong>any</strong> purpose unless you have
+determined that its content is safe for your intended use and will not,
+at the very least, overwrite another file of importance to you, especially if
+you intend to use it as a file name on the server side. The cgic library
+itself does not use this file name for temporary storage.
+<p>
+If the <a href="#cgiFormFileName">cgiFormFileName</a> function does
+not succeed, no file was uploaded.
+<p>
+Next, the <a href="#cgiFormFileSize">cgiFormFileSize</a> function is called
+to determine the size of the uploaded file, in bytes.
+<p>
+The File function then proceeds to query the content type of the uploaded
+file.  Files uploaded by the user have their own content type information, 
+which may be useful in determining whether the file is an image, HTML document,
+word processing document, or other type of file. However,
+<strong>as with the filename and any other claim made by the browser,
+this information should not be blindly trusted.</strong> The browser
+may upload a file with the name <code>picture.jpg</code> and the
+content type <code>image/jpeg</code>, but this does not guarantee that the
+actual file will contain a valid JPEG image suitable for display.
+<p>
+The content type submitted by the browser can be queried using the
+<a href="#cgiFormFileContentType">cgiFormFileContentType</a> function.
+<p>
+Of course, CGIC also provides access to the actual uploded file. 
+First, the programmer calls <a href="#cgiFormFileOpen">cgiFormFileOpen</a>,
+passing the address of a <code>cgiFilePtr</code> object. If this function
+succeeds, the <code>cgiFilePtr</code> object becomes valid, and can be
+used in subsequent calls to <a href="#cgiFormFileRead">cgiFormFileRead</a>.
+Notice that the number of bytes read may be less than the number requested,
+in particular on the last successful call before cgiFormFileRead begins
+to return <code>cgiFormEOF</code>. When cgiFormFileRead no longer returns 
+cgiFormSuccess, 
+the programmer calls <a href="#cgiFormClose">cgiFormFileClose</a> to
+release the <code>cgiFilePtr</code> object.
+<p>
+The uploaded file data may contain anything, including binary data,
+null characters, and so on. The example program uses the 
+<a href="#cgiHtmlEscapeData">cgiHtmlEscapeData</a> function to output the
+data with any special characters that have meaning in HTML escaped.
+Most programs will save the uploaded information to a server-side file or
+database.
+<h4>Fetching All Form Entries</h4>
+From time to time, the programmer may not know the names of all
+form fields in advance. In such situations it is convenient to
+use the <a href="#cgiFormEntries">cgiFormEntries</a> function.
+The Entries function of cgictest.c demonstrates the use of
+cgiFormEntries:
+<pre>
+void Entries()
+{
+        char **array, **arrayStep;
+        fprintf(cgiOut, "List of All Submitted Form Field Names:&lt;p&gt;\n");
+        if (cgiFormEntries(&array) != cgiFormSuccess) {
+                return;
+        }
+        arrayStep = array;
+        fprintf(cgiOut, "&lt;ul&gt;\n");
+        while (*arrayStep) {
+                fprintf(cgiOut, "&lt;li&gt;");
+                cgiHtmlEscape(*arrayStep);
+                fprintf(cgiOut, "\n");
+                arrayStep++;
+        }
+        fprintf(cgiOut, "&lt;/ul&gt;\n");
+        cgiStringArrayFree(array);
+}
+</pre>
+The cgiFormEntries function retrieves an array of form field names.
+This array consists of pointers to strings, with a final null pointer
+to mark the end of the list. The above code illustrates one way of
+looping through the returned strings. Note the final call to
+<a href="#cgiStringArrayFree">cgiStringArrayFree</a>, which is
+essential in order to return the memory used to store the strings
+and the string array.
+<h4>Retrieving Cookies</h4>
+The Cookies function of cgictest.c displays a list of all cookies
+submitted by the browser with the current form submission, along
+with their values:
+<pre>
+void Cookies()
+{
+  char **array, **arrayStep;
+  char cname[1024], cvalue[1024];
+  fprintf(cgiOut, "Cookies Submitted On This Call, With Values "
+    "(Many Browsers NEVER Submit Cookies):&lt;p&gt;\n");
+  if (cgiCookies(&array) != cgiFormSuccess) {
+    return;
+  }
+  arrayStep = array;
+  fprintf(cgiOut, "&lt;table border=1&gt;\n");
+  fprintf(cgiOut, "&lt;tr&gt;&lt;th&gt;Cookie&lt;th&gt;Value&lt;/tr&gt;\n");
+  while (*arrayStep) {
+    char value[1024];
+    fprintf(cgiOut, "&lt;tr&gt;");
+    fprintf(cgiOut, "&lt;td&gt;");
+    cgiHtmlEscape(*arrayStep);
+    fprintf(cgiOut, "&lt;td&gt;");
+    cgiCookieString(*arrayStep, value, sizeof(value));
+    cgiHtmlEscape(value);
+    fprintf(cgiOut, "\n");
+    arrayStep++;
+  }
+  fprintf(cgiOut, "&lt;/table&gt;\n");
+  cgiFormString("cname", cname, sizeof(cname));  
+  cgiFormString("cvalue", cvalue, sizeof(cvalue));  
+  if (strlen(cname)) {
+    fprintf(cgiOut, "New Cookie Set On This Call:&lt;p&gt;\n");
+    fprintf(cgiOut, "Name: ");  
+    cgiHtmlEscape(cname);
+    fprintf(cgiOut, "Value: ");  
+    cgiHtmlEscape(cvalue);
+    fprintf(cgiOut, "&lt;p&gt;\n");
+    fprintf(cgiOut, "If your browser accepts cookies "
+      "(many do not), this new cookie should appear "
+      "in the above list the next time the form is "
+      "submitted.&lt;p&gt;\n"); 
+  }
+  cgiStringArrayFree(array);
+}
+</pre>
+<strong>VERY IMPORTANT: YOUR BROWSER MIGHT NOT SUBMIT COOKIES,
+EVER, REGARDLESS OF WHAT VALUES YOU ENTER INTO THE TEST FORM.</strong>
+Many, many browsers are configured not to accept or send cookies;
+others are configured to send them as little as possible to meet the
+bare minimum requirements for entry into popular sites. Users will often
+refuse your cookies; make sure your code still works in that situation!
+<p>
+The above code uses the <a href="#cgiCookies">cgiCookies</a> function
+to retrieve a list of all currently set cookies as a null-terminated
+array of strings. The <a href="#cgiCookieString">cgiCookieString</a>
+function is then used to fetch the value associated with each cookie;
+this function works much like <a href="#cgiFormString">cgiFormString</a>,
+discussed earlier. Note that a cookie set as a part of the current
+form submission process does not appear on this list immediately, as
+it has not yet been sent back by the browser. It should appear on
+future submissions, provided that the browser chooses to accept
+and resend the cookie at all.
+<h4>Displaying a Form That Submits to the Current Program</h4>
+CGI programmers often need to display HTML pages as part of the output
+of CGI programs; these HTML pages often contain forms which should submit
+fields back to the same program they came from. Provided that your
+web server is well-configured, this can be done conveniently using
+the cgiScriptName environment variable, as shown below. Here is the
+source code of the ShowForm function of cgictest.c:
+<pre>
+void ShowForm()
+{
+  fprintf(cgiOut, "&lt;!-- 2.0: multipart/form-data is required 
+    "for file uploads. --&gt;");
+  fprintf(cgiOut, "&lt;form method=\"POST\" "
+    "enctype=\"multipart/form-data\" ");
+  fprintf(cgiOut, "  action=\"");
+  cgiValueEscape(cgiScriptName);
+  fprintf(cgiOut, "\"&gt;\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Text Field containing Plaintext\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"text\" name=\"name\"&gt;Your Name\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Multiple-Line Text Field\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;textarea NAME=\"address\" ROWS=4 COLS=40&gt;\n");
+  fprintf(cgiOut, "Default contents go here. \n");
+  fprintf(cgiOut, "&lt;/textarea&gt;\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Checkbox\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"checkbox\" name=\"hungry\" checked&gt;Hungry\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Text Field containing a Numeric Value\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"text\" name=\"temperature\" value=\"98.6\"&gt;\n");
+  fprintf(cgiOut, "Blood Temperature (80.0-120.0)\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Text Field containing an Integer Value\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"text\" name=\"frogs\" value=\"1\"&gt;\n");
+  fprintf(cgiOut, "Frogs Eaten\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "Single-SELECT\n");
+  fprintf(cgiOut, "&lt;br&gt;\n");
+  fprintf(cgiOut, "&lt;select name=\"colors\"&gt;\n");
+  fprintf(cgiOut, "&lt;option value=\"Red\"&gt;Red\n");
+  fprintf(cgiOut, "&lt;option value=\"Green\"&gt;Green\n");
+  fprintf(cgiOut, "&lt;option value=\"Blue\"&gt;Blue\n");
+  fprintf(cgiOut, "&lt;/select&gt;\n");
+  fprintf(cgiOut, "&lt;br&gt;\n");
+  fprintf(cgiOut, "Multiple-SELECT\n");
+  fprintf(cgiOut, "&lt;br&gt;\n");
+  fprintf(cgiOut, "&lt;select name=\"flavors\" multiple&gt;\n");
+  fprintf(cgiOut, "&lt;option value=\"pistachio\"&gt;Pistachio\n");
+  fprintf(cgiOut, "&lt;option value=\"walnut\"&gt;Walnut\n");
+  fprintf(cgiOut, "&lt;option value=\"creme\"&gt;Creme\n");
+  fprintf(cgiOut, "&lt;/select&gt;\n");
+  fprintf(cgiOut, "&lt;p&gt;Exclusive Radio Button Group: Age of "
+    "Truck in Years\n");
+  fprintf(cgiOut, "&lt;input type=\"radio\" name=\"age\" "
+    "value=\"1\"&gt;1\n");
+  fprintf(cgiOut, "&lt;input type=\"radio\" name=\"age\" "
+    "value=\"2\"&gt;2\n");
+  fprintf(cgiOut, "&lt;input type=\"radio\" name=\"age\" "
+    "value=\"3\" checked&gt;3\n");
+  fprintf(cgiOut, "&lt;input type=\"radio\" name=\"age\" "
+    "value=\"4\"&gt;4\n");
+  fprintf(cgiOut, "&lt;p&gt;Nonexclusive Checkbox Group: "
+    "Voting for Zero through Four Candidates\n");
+  fprintf(cgiOut, "&lt;input type=\"checkbox\" name=\"vote\" "
+    "value=\"A\"&gt;A\n");
+  fprintf(cgiOut, "&lt;input type=\"checkbox\" name=\"vote\" "
+    "value=\"B\"&gt;B\n");
+  fprintf(cgiOut, "&lt;input type=\"checkbox\" name=\"vote\" "
+    "value=\"C\"&gt;C\n");
+  fprintf(cgiOut, "&lt;input type=\"checkbox\" name=\"vote\" "
+    "value=\"D\"&gt;D\n");
+  fprintf(cgiOut, "&lt;p&gt;File Upload:\n");
+  fprintf(cgiOut, "&lt;input type=\"file\" name=\"file\" "
+    "value=\"\"&gt; (Select A Local File)\n");
+  fprintf(cgiOut, "&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;p&gt;Set a Cookie&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input name=\"cname\" "
+    "value=\"\"&gt; Cookie Name\n");
+  fprintf(cgiOut, "&lt;input name=\"cvalue\" "
+    "value=\"\"&gt; Cookie Value&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"submit\" "
+    "name=\"testcgic\" value=\"Submit Request\"&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"reset\" "
+    "value=\"Reset Request\"&gt;\n");
+  fprintf(cgiOut, "&lt;p&gt;Save the CGI Environment&lt;p&gt;\n");
+  fprintf(cgiOut, "Pressing this button will submit the form, then "
+    "save the CGI environment so that it can be replayed later "
+    "by calling cgiReadEnvironment (in a debugger, for "
+    "instance).&lt;p&gt;\n");
+  fprintf(cgiOut, "&lt;input type=\"submit\" name=\"saveenvironment\" "
+    "value=\"Save Environment\"&gt;\n");
+  fprintf(cgiOut, "&lt;/form&gt;\n");
+}
+</pre>
+Note the use of <code>enctype="multipart/form-data"</code> in the
+<code>FORM</code> tag. This is absolutely required if the form
+will contain file upload fields, as in the above example. Most
+browsers will not even attempt file uploads without the
+presence of this attribute.
+<h4>Examining CGI environment variables</h4>
+The CGI standard specifies a number of environment variables
+which are set by the server. However, servers are somewhat
+unpredictable as to whether these variables will be null or
+point to empty strings when an environment variable is not set.
+Also, in order to allow the programmer to restore saved
+CGI environments, the cgic library needs have a way of insulating
+the programmer from the actual environment variables.
+<p>
+Instead of calling getenv() to determine the value of a
+variable such as HTTP_USER_AGENT (the browser software being used),
+always use the
+<a href="#variables">cgic copies of the environment variables</a>,
+which are always valid C strings (they are never null, although
+they may point to an empty string). For instance, the cgic
+variable containing the name of the browser software is
+<a href="#cgiUserAgent">cgiUserAgent</a>. The referring URL appears
+in the variable <a href="#cgiReferrer">cgiReferrer</a>.
+<h3><a name="images">How can I generate images from my cgic application?</a></h3>
+cgic can be used in conjunction with the
+<a href="http://www.boutell.com/gd/">gd graphics library</a>, which
+can produce GIF images on the fly.
+<p>
+The following short sample program hints at the possibilities:
+<pre>
+#include "cgic.h"
+#include "gd.h"
+
+char *colors[] = {
+  "red", "green", "blue"
+};
+
+#define colorsTotal 3
+
+int cgiMain() {
+  int colorChosen;
+  gdImagePtr im;
+  int r, g, b;
+  /* Use gd to create an image */
+  im = gdImageCreate(64, 64);
+  r = gdImageColorAllocate(im, 255, 0, 0);  
+  g = gdImageColorAllocate(im, 0, 255, 0);  
+  b = gdImageColorAllocate(im, 0, 0, 255);  
+  /* Now use cgic to find out what color the user requested */
+  <a href="#cgiFormSelectSingle">cgiFormSelectSingle</a>("color", 3, &amp;colorChosen, 0);  
+  /* Now fill with the desired color */
+  switch(colorChosen) {
+    case 0:
+    gdImageFill(im, 32, 32, r);
+    break;
+    case 1:
+    gdImageFill(im, 32, 32, g);
+    break;
+    case 2:
+    gdImageFill(im, 32, 32, b);
+    break;
+  }  
+  /* Now output the image. Note the content type! */
+  cgiHeaderContentType("image/gif");
+  /* Send the image to cgiOut */
+  gdImageGif(im, cgiOut);
+  /* Free the gd image */
+  gdImageDestroy(im);
+  return 0;
+}
+</pre>
+Note that this program would need to be linked with both cgic.o
+and libgd.a. Often programs of this type respond to one
+cgiPathInfo value or set of form fields by returning an HTML page 
+with an inline image reference that, in turn, generates a GIF image.
+<h3><a name="debug">Debugging CGI applications: using capture</a></h3>
+Debugging CGI applications can be a painful task. Since CGI applications
+run in a special environment created by the web server, it is difficult
+to execute them in a debugger. However, the cgic library provides a way 
+of capturing "live" CGI environments to a file, and also provides a way
+to reload saved environments. 
+<p>
+The provided program 'capture.c' can be used to capture CGI
+environments. Just change the first line of the cgiMain() function
+of capture.c to save the CGI environment to a filename appropriate
+on your system and type 'make capture'. Then place capture in your
+cgi directory and set the form action or other link you want to test
+to point to it. When the form submission or other link takes place,
+capture will write the CGI environment active at that time to
+the filename you specified in the source. The
+<a href="#cgiReadEnvironment">cgiReadEnvironment()</a> function can then 
+be invoked on the same filename at the beginning of the cgiMain() function 
+of the application you want to test in order to restore the captured 
+environment.  You can then execute your program in the debugger of your choice,
+and it should perform exactly as it would have performed had
+it been launched by the actual web server, including file uploads,
+cookies and all other phenomena within the purview of cgic.
+<p>
+<strong>Important:</strong> Make sure you specify the full path, as the
+current working directory of a CGI script may not be what you
+think it is!
+<p>
+<strong>Even More Important:</strong> If you call getenv() yourself
+in your code, instead of using the provided <a href="#variables">
+cgic copies of the CGI environment variables</a>, you will
+<em>not</em> get the values you expect when running with
+a saved CGI environment. Always use the cgic variables instead
+of calling getenv().
+<h3><a name="functions">cgic function reference</a></h3>
+<dl>
+<br><dt><strong><a name="cgiFormString">cgiFormResultType cgiFormString(
+  char *name, char *result, int max)</a>
+</strong><br><dd>cgiFormString attempts to retrieve the string sent for the
+  specified input field. The text will be copied into
+  the buffer specified by result, up to but not
+  exceeding max-1 bytes; a terminating null is then
+  added to complete the string. Regardless of the newline
+  format submitted by the browser, cgiFormString always
+  encodes each newline as a single line feed (ascii decimal 10); as
+  a result the final string may be slightly shorter than indicated
+  by a call to <a href="#cgiFormStringSpaceNeeded">
+  cgiFormStringSpaceNeeded</a> but will never be longer.
+  cgiFormString returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if the string was 
+  successfully retrieved, 
+  <a href="#cgiFormTruncated">cgiFormTruncated</a> if the string was
+  retrieved but was truncated to fit the buffer,
+  cgiFormEmpty if the string was 
+  retrieved but was empty, and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no 
+  such input field was submitted. In the last case, 
+  an empty string is copied to result. 
+<br><br><dt><strong><a name="cgiFormStringNoNewlines">
+cgiFormResultType cgiFormStringNoNewlines(
+  char *name, char *result, int max)</a>
+</strong><br><dd>
+cgiFormStringNoNewlines() is exactly equivalent to <a href="#cgiFormString">
+  cgiFormString()</a>, except
+  that any carriage returns or line feeds that occur in the input
+  will be stripped out. The use of this function is recommended
+  for single-line text input fields, as some browsers will submit
+  carriage returns and line feeds when they should not. 
+<br><br><dt><strong><a name="cgiFormStringSpaceNeeded">
+cgiFormResultType cgiFormStringSpaceNeeded(
+  char *name, int *length)</a>
+</strong><br><dd>
+cgiFormStringSpaceNeeded() is used to determine the length of the input text 
+  buffer needed to receive the contents of the specified input field. 
+  This is useful if the programmer wishes to allocate sufficient memory 
+  for input of arbitrary length. The actual length of the string 
+  retrieved by a subsequent call to cgiFormString() may be slightly shorter
+  but will never be longer than *result. On success, cgiFormStringSpaceNeeded() 
+  sets the value pointed to by length to the number of bytes of data, 
+  including the terminating null, and returns <a href="#cgiFormSuccess">cgiFormSuccess</a>. If no 
+  value was submitted for the specified field, cgiFormStringSpaceNeeded sets 
+  the value pointed to by length to 1 and returns <a href="#cgiFormNotFound">cgiFormNotFound</a>. 1 is
+  set to ensure space for an empty string (a single null
+  character) if cgiFormString is called despite the return value.
+
+<br><br><dt><strong><a name="cgiFormStringMultiple">cgiFormResultType cgiFormStringMultiple(
+  char *name, char ***ptrToStringArray)</a>
+</strong><br><dd>cgiFormStringMultiple is useful in the unusual case in which several
+  input elements in the form have the same name and, for whatever
+  reason, the programmer does not wish to use the checkbox, radio 
+  button and selection menu functions provided below. This is
+  occasionally needed if the programmer cannot know 
+  in advance what values might appear in a multiple-selection list
+  or group of checkboxes on a form. The value pointed to
+  by result will be set to a pointer to an array of strings; the last
+  entry in the array will be a null pointer.  This array is allocated 
+  by the CGI library. Important: when done working with the array,
+  you must call cgiStringArrayFree() with the array pointer as the 
+  argument.  cgiFormStringMultiple() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if at least
+  one occurrence of the name is found, <a href="#cgiFormNotFound">cgiFormNotFound</a>
+  if no occurrences are found, or cgiFormMemory if not enough
+  memory is available to allocate the array to be returned.
+  In all cases except the last, ptrToStringArray is set to point to a 
+  valid array of strings, with the last element in the array being a 
+  null pointer; in the out-of-memory case ptrToStringArray is set to 
+  a null pointer.
+
+<br><br><dt><strong><a name="cgiFormEntries">cgiFormResultType cgiFormEntries(
+  char ***ptrToStringArray)</a>
+</strong><br><dd>cgiFormEntries is useful when the programmer cannot know the names
+  of all relevant form fields in advance. The value pointed to
+  by result will be set to a pointer to an array of strings; the last
+  entry in the array will be a null pointer.  This array is allocated 
+  by the CGI library. Important: when done working with the array,
+  you must call cgiStringArrayFree() with the array pointer as the 
+  argument. cgiFormEntries() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> except in the event of an out of memory error.
+  On success, ptrToStringArray is set to point to a 
+  valid array of strings, with the last element in the array being a 
+  null pointer; in the out-of-memory case ptrToStringArray is set to 
+  a null pointer, and 
+  <a href="#cgiFormOutOfMemory">cgiFormOutOfMemory</a> is returned.
+
+<br><br><dt><strong><a name="cgiStringArrayFree">void cgiStringArrayFree(char **stringArray)
+</a>
+</strong><br><dd>
+cgiStringArrayFree() is used to free the memory associated with
+  a string array created by 
+  <a href="#cgiFormStringMultiple">cgiFormStringMultiple()</a>,
+  <a href="#cgiFormEntries">cgiFormEntries()</a>, or
+  <a href="#cgiFormCookies">cgiFormCookies()</a>.
+<br><br><dt><strong><a name="cgiFormInteger">cgiFormResultType cgiFormInteger(
+  char *name, int *result, int defaultV)</a>
+</strong><br><dd>cgiFormInteger() attempts to retrieve the integer sent for the
+  specified input field. The value pointed to by result
+  will be set to the value submitted. cgiFormInteger() returns 
+  cgiFormSuccess if the value was successfully retrieved,
+  cgiFormEmpty if the value submitted is an empty string,
+  cgiFormBadType if the value submitted is not an integer,
+  and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no such input field was submitted. 
+  In the last three cases, the value pointed to by result
+  is set to the specified default.
+<br><br><dt><strong><a name="cgiFormIntegerBounded">
+cgiFormResultType cgiFormIntegerBounded(
+  char *name, int *result, int min, int max, int defaultV)</a>
+</strong><br><dd>cgiFormIntegerBounded() attempts to retrieve the integer sent for the
+  specified input field, and constrains the result to be within
+  the specified bounds. The value pointed to by result
+  will be set to the value submitted. cgiFormIntegerBounded() returns 
+  cgiFormSuccess if the value was successfully retrieved,
+  <a href="#cgiFormConstrained">cgiFormConstrained</a> if the value was out of bounds and result
+  was adjusted accordingly, <a href="#cgiFormEmpty">cgiFormEmpty</a> if the value submitted is 
+  an empty string, <a href="#cgiFormBadType">cgiFormBadType</a> if the value submitted is not an 
+  integer, and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no such input field was submitted. 
+  In the last three cases, the value pointed to by result
+  is set to the specified default.
+
+<br><br><dt><strong><a name="cgiFormDouble">cgiFormResultType cgiFormDouble(
+  char *name, double *result, double defaultV)</a>
+</strong><br><dd>cgiFormDouble attempts to retrieve the floating-point value sent for 
+  the specified input field. The value pointed to by result
+  will be set to the value submitted. cgiFormDouble returns 
+  cgiFormSuccess if the value was successfully retrieved,
+  cgiFormEmpty if the value submitted is an empty string,
+  cgiFormBadType if the value submitted is not a number,
+  and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no such input field was submitted. 
+  In the last three cases, the value pointed to by result
+  is set to the specified default. 
+<br><br><dt><strong><a name="cgiFormDoubleBounded">
+cgiFormResultType cgiFormDoubleBounded(
+  char *name, double *result, double min, double max, 
+  double defaultV)</a>
+</strong><br><dd>
+cgiFormDoubleBounded() attempts to retrieve the floating-point
+  value  sent for the specified input field, and constrains the 
+  result to be within the specified bounds. The value pointed to by 
+  result will be set to the value submitted. cgiFormDoubleBounded() returns 
+  cgiFormSuccess if the value was successfully retrieved,
+  <a href="#cgiFormConstrained">cgiFormConstrained</a> if the value was out of bounds and result
+  was adjusted accordingly, <a href="#cgiFormEmpty">cgiFormEmpty</a> if the value submitted is 
+  an empty string, <a href="#cgiFormBadType">cgiFormBadType</a> if the value submitted is not a 
+  number, and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no such input field was submitted. 
+  In the last three cases, the value pointed to by result
+  is set to the specified default. 
+
+<br><br><dt><strong><a name="cgiFormSelectSingle">
+cgiFormResultType cgiFormSelectSingle(
+  char *name, char **choicesText, int choicesTotal, 
+  int *result, int defaultV)</a>
+</strong><br><dd>
+cgiFormSelectSingle() retrieves the selection number associated with a
+  &lt;SELECT&gt; element that does not allow multiple selections. name
+  should identify the NAME attribute of the &lt;SELECT&gt; element. choicesText 
+  should point to an array of strings identifying each choice; 
+  choicesTotal should indicate the total number of choices. The value 
+  pointed to by result will be set to the position of the actual choice
+  selected within the choicesText array, if any, or to the value of 
+  default, if no selection was submitted or an invalid selection was 
+  made.  cgiFormSelectSingle() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if the value was
+  successfully retrieved, <a href="#cgiFormNotFound">cgiFormNotFound</a> if no selection
+  was submitted, and <a href="#cgiFormNoSuchChoice">cgiFormNoSuchChoice</a> if the selection
+  does not match any of the possibilities in the choicesText array. 
+<br><dt><strong>
+<a name="cgiFormSelectMultiple">
+cgiFormResultType cgiFormSelectMultiple(
+  char *name, char **choicesText, int choicesTotal, 
+  int *result, int *invalid)</a>
+</strong><br><dd>cgiFormSelectMultiple() retrieves the selection numbers associated with a
+  &lt;SELECT&gt; element that does allow multiple selections. name should
+  identify the NAME attribute of the &lt;SELECT&gt; element. choicesText 
+  should point to an array of strings identifying each choice; 
+  choicesTotal should indicate the total number of choices. result
+  should point to an array of integers with as many elements as there
+  are strings in the choicesText array. For each choice in the
+  choicesText array that is selected, the corresponding integer in
+  the result array will be set to one; other entries in the result
+  array will be set to zero. cgiFormSelectMultiple() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> 
+  if at least one valid selection was successfully retrieved or
+  cgiFormNotFound if no valid selections were submitted.
+  The integer pointed to by invalid is set to the number of
+  invalid selections that were submitted, which should be zero
+  unless the form and the choicesText array do not agree.
+
+<br><br><dt><strong>
+<a name="cgiFormSubmitClicked">
+cgiFormResultType cgiFormSubmitClicked(
+  char *name)</a>
+</strong><br><dd>
+It is often desirable to know whether a particular submit button was clicked,
+  when multiple submit buttons with different name attributes exist.
+  cgiFormSubmitClicked is an alternative name for the 
+  <a href="#cgiFormCheckboxSingle">cgiFormCheckboxSingle</a> function,
+  which is suitable for testing whether a particular submit button
+  was used.
+<br><br><dt><strong>
+<a name="cgiFormCheckboxSingle">
+cgiFormResultType cgiFormCheckboxSingle(
+  char *name)</a>
+</strong><br><dd>
+cgiFormCheckboxSingle determines whether the checkbox with the specified name
+  is checked. cgiFormCheckboxSingle returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if the
+  button is checked, <a href="#cgiFormNotFound">cgiFormNotFound</a> if the checkbox is
+  not checked. cgiFormCheckboxSingle is intended for single
+  checkboxes with a unique name; see below for functions to
+  deal with multiple checkboxes with the same name, and
+  with radio buttons.
+
+<br><br><dt><strong><a name="cgiFormCheckboxMultiple">
+cgiFormResultType cgiFormCheckboxMultiple(
+  char *name, char **valuesText, int valuesTotal, 
+  int *result, int *invalid)</a>
+</strong><br><dd>cgiFormCheckboxMultiple() determines which checkboxes among a group
+  of checkboxes with the same name are checked. This is distinct
+  from radio buttons (see <a href="#cgiFormRadio">cgiFormRadio</a>). 
+  valuesText 
+  should point to an array of strings identifying the VALUE
+  attribute of each checkbox; valuesTotal should indicate the total 
+  number of checkboxes. result should point to an array of integers with 
+  as many elements as there are strings in the valuesText array. For 
+  each choice in the valuesText array that is selected, the corresponding
+  integer in the result array will be set to one; other entries in the 
+  result array will be set to zero. cgiFormCheckboxMultiple returns 
+  cgiFormSuccess if at least one valid checkbox was checked or
+  cgiFormNotFound if no valid checkboxes were checked.
+  The integer pointed to by invalid is set to the number of
+  invalid selections that were submitted, which should be zero
+  unless the form and the valuesText array do not agree.
+<br><br><dt><strong><a name="cgiFormRadio">
+cgiFormResultType cgiFormRadio(
+  char *name, char **valuesText, int valuesTotal, 
+  int *result, int defaultV)</a>
+</strong><br><dd>cgiFormRadio() determines which, if any, of a group of radio boxes with
+  the same name was selected. valuesText should point to an array of 
+  strings identifying the VALUE attribute of each radio box; 
+  valuesTotal should indicate the total number of radio boxes. The value 
+  pointed to by result will be set to the position of the actual choice 
+  selected within the valuesText array, if any, or to the value of 
+  default, if no radio box was checked or an invalid selection was 
+  made. cgiFormRadio() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if a checked radio box was 
+  found in the group, <a href="#cgiFormNotFound">cgiFormNotFound</a> if no box was checked, and 
+  <a href="#cgiFormNoSuchChoice">cgiFormNoSuchChoice</a> if the radio box submitted does not match any of 
+  the possibilities in the valuesText array.
+
+<br><dt><strong><a name="cgiFormFileName">cgiFormResultType cgiFormFileName(
+  char *name, char *fileName, int max)</a>
+</strong><br><dd>cgiFormFileName attempts to retrieve the file name uploaded by the
+  user for the specified form input field of type <code>file</code>. 
+  <strong>NEVER, EVER TRUST THIS FILENAME TO BE REASONABLE AND
+  SAFE FOR DIRECT USE ON THE SERVER SIDE.</strong>
+  The text will be copied into
+  the buffer specified by fileName, up to but not
+  exceeding max-1 bytes; a terminating null is then
+  added to complete the string. cgiFormFileName returns 
+  <a href="#cgiFormSuccess">cgiFormSuccess</a> if the string was 
+  successfully retrieved and was not empty,
+  <a href="#cgiFormNoFileName">cgiFormNoFileName</a> if the string was 
+  successfully retrieved but empty indicating that no file was uploaded,
+  <a href="#cgiFormTruncated">cgiFormTruncated</a> if the string was
+  retrieved but was truncated to fit the buffer,
+  and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no 
+  such input field was submitted. In the last case, 
+  an empty string is copied to result. 
+<br><dt><strong><a name="cgiFormFileSize">cgiFormResultType cgiFormFileSize(
+  char *name, int *sizeP)</a>
+</strong><br><dd>cgiFormFileSize attempts to retrieve the size, in bytes, of a
+  file uploaded by the browser in response to the
+  input field of type <code>file</code> specified by the
+  <code>name</code> parameter. On success, the size is stored
+  to *sizeP, and this function returns 
+  <a href="#cgiFormSuccess">cgiFormSuccess</a>. If the form
+  field does not exist, this function returns 
+  <a href="#cgiFormNotFound">cgiFormNotFound</a>.
+  If the form field exists but no file was uploaded, this function
+  returns <a href="#cgiFormNotAFile">cgiFormNotAFile</a>.
+<br><dt><strong><a name="cgiFormFileContentType">cgiFormResultType cgiFormFileContentType(
+  char *name, char *contentType, int max)</a>
+</strong><br><dd>cgiFormString attempts to retrieve the content name claimed by the
+  user for the specified form input field of type <code>file</code>. 
+  <strong>THERE IS NO GUARANTEE THAT THE CONTENT TYPE WILL BE
+  ACCURATE.</strong>
+  The content type string will be copied into
+  the buffer specified by contentType, up to but not
+  exceeding max-1 bytes; a terminating null is then
+  added to complete the string. cgiFormFileContentType returns 
+  <a href="#cgiFormSuccess">cgiFormSuccess</a> if the string was 
+  successfully retrieved and was not empty,
+  <a href="#cgiFormNoContentType">cgiFormNoContentType</a> if the string was 
+  successfully retrieved but empty indicating that no file was uploaded
+  or the browser did not know the content type,
+  <a href="#cgiFormTruncated">cgiFormTruncated</a> if the string was
+  retrieved but was truncated to fit the buffer,
+  and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no 
+  such input field was submitted. In the last case, 
+  an empty string is copied to result. 
+
+<br><dt><strong><a name="cgiFormFileOpen">cgiFormResultType cgiFormFileOpen(
+  char *name, cgiFilePtr *cfpp)</a>
+</strong><br><dd>cgiFormFileOpen attempts to open the actual uploaded file data for
+  the specified form field of type <code>file</code>. Upon success,
+  this function returns retrieve the content name claimed by the
+  user for the specified form input field of type <code>file</code>. 
+  On success, this function sets *cfpp to a valid cgiFilePtr
+  object for use with <a href="#cgiFormFileRead</a>cgiFormFileRead</a>
+  and returns <a href="#cgiFormSuccess">cgiFormSuccess</a>.
+  On failure, this function sets *cfpp to a null pointer, and
+  returns <a href="#cgiFormNotFound">cgiFormNotFound</a>,
+  <a href="#cgiFormNotAFile">cgiFormNotAFile</a>,
+  <a href="#cgiFormMemory">cgiFormMemory</a> or
+  <a href="#cgiFormIO">cgiFormIO</a> as appropriate.
+<p>
+  See also <a href="#cgiFormFileRead">cgiFormFileRead</a> 
+and <a href="#cgiFormFileClose">cgiFormFileClose</a>.
+<br><dt><strong><a name="cgiFormFileRead">cgiFormResultType cgiFormFileRead(
+  cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP)</a>
+</strong><br><dd>cgiFormFileRead attempts to read up to <code>bufferSize</code>
+  bytes from a cgiFilePtr object previously opened with
+  <a href="#cgiFormFileOpen">cgiFormFileOpen</a>. If any data
+  is successfully read, it is copied to <code>buffer</code>, 
+  and the number of bytes successfully read is stored 
+  to <code>*gotP</code>. This function returns 
+  <a href="#cgiFormSuccess">cgiFormSuccess</a> if any data
+  is successfully read. At end of file, this function
+  returns <a href="#cgiFormEOF">cgiFormEOF</a>. In the event
+  of an I/O error, this function returns 
+  <a href="#cgiFormIO">cgiFormIO</a>. If cfp is a null pointer,
+  this function returns <a href="#cgiFormOpenFailed">cgiFormOpenFailed</a>.
+  <p>
+  See also <a href="#cgiFormFileOpen">cgiFormFileOpen</a> 
+and <a href="#cgiFormFileClose">cgiFormFileClose</a>.
+<br><dt><strong><a name="cgiFormFileClose">cgiFormResultType cgiFormFileClose(
+  cgiFilePtr cfp)</a>
+</strong><br><dd>cgiFormFileClose closes a cgiFilePtr object previously opened
+  with <a href="#cgiFormFileOpen">cgiFormFileOpen</a>, freeing
+  memory and other system resources. This
+  function returns <a href="#cgiFormSuccess">cgiFormSuccess</a>
+  unless cfp is null, in which case 
+  <a href="#cgiFormOpenFailed">cgiFormOpenFailed</a> is returned.
+<p>
+  See also <a href="#cgiFormFileOpen">cgiFormFileOpen</a> 
+and <a href="#cgiFormFileRead">cgiFormFileRead</a>.
+<br><br><dt><strong><a name="cgiHeaderLocation">
+void cgiHeaderLocation(char *redirectUrl)</a>
+</strong><br><dd>
+cgiHeaderLocation() should be called if the programmer wishes to
+redirect the user to a different URL. No futher output
+is needed in this case.
+<p>
+If you wish to set cookies,
+<strong>you must make your calls to 
+<a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>
+and 
+<a href="#cgiHeaderCookieSetInteger">cgiHeaderCookieSetInteger</a>
+</strong> BEFORE invoking cgiHeaderLocation. 
+<br><br><dt><strong><a name="cgiHeaderStatus">
+void cgiHeaderStatus(int status, char *statusMessage)</a>
+</strong><br><dd>
+cgiHeaderStatus() should be called if the programmer wishes to
+output an HTTP error status code instead of a document. The status
+code is the first argument; the second argument is the status
+message to be displayed to the user.
+<p>
+If you wish to set cookies,
+<strong>you must make your calls to 
+<a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>
+and 
+<a href="#cgiHeaderCookieSetInteger">cgiHeaderCookieSetInteger</a>
+</strong> BEFORE invoking cgiHeaderStatus.
+<br><br><dt><strong><a name="cgiHeaderContentType">
+void cgiHeaderContentType(char *mimeType)</a>
+</strong><br><dd>
+cgiHeaderContentType() should be called if the programmer wishes to
+output a new document in response to the user's request. This is
+the normal case. The single argument is the MIME document type
+of the response; typical values are "text/html" for HTML documents, 
+"text/plain" for plain ASCII without HTML tags, "image/gif" for
+a GIF image and "audio/basic" for .au-format audio.
+<p>
+If you wish to set cookies,
+<strong>you must make your calls to 
+<a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>
+and 
+<a href="#cgiHeaderCookieSetInteger">cgiHeaderCookieSetInteger</a>
+</strong> BEFORE invoking cgiHeaderContentType.
+<br><br><dt><strong><a name="cgiHeaderCookieSetString">
+void cgiHeaderCookieSetString(char *name, char *value,
+  int secondsToLive, char *path, char *domain)</a>
+</strong><br><dd>
+cgiHeaderCookieSetString() should be called when the programmer wishes
+to store a piece of information in the user's browser, so that the
+stored information is again presented to the server on subsequent
+accesses to the relevant site. The first argument is the name of the
+cookie to be stored; for best results in all browsers, use a short
+name without spaces or unusual punctuation. The second argument is
+the value of the cookie to be stored. Again, for best results, use
+a short string; it is recommended that cookies be used to store a
+unique identifier which is then used to look up more detailed
+information in a database on the server side. Attempts to store
+elaborate information on the browser side are much more likely to fail.
+The third argument is the number of seconds that the cookie should
+be kept by the browser; 86400 is a single full day, 365*86400 is
+roughly one year. The fourth argument is the partial URL of the
+web site within which the cookie is relevant. If the cookie should
+be sent to the server for every access to the entire site, 
+set this argument to <code>/</code>. The final argument is the
+web site name or entire domain for which this cookie should be
+submitted; if you choose to have the cookie sent back for an
+entire domain, this argument must begin with a dot, such as
+<code>.boutell.com</code>. The cgic variables <a name="#cgiScriptName</a>
+and <a name="#cgiServerName">cgiServerName</a> are convenient
+values for the fourth and fifth arguments.
+See also <a href="#cgiHeaderCookieSetInteger">cgiHeaderCookieSetInteger</a>,
+<a href="#cgiCookieString">cgiCookieString</a>, 
+<a href="#cgiCookieString">cgiCookieInteger</a> and
+<a href="#cgiCookies">cgiCookies</a>.
+<br><br><dt><strong><a name="cgiHeaderCookieSetInteger">
+void cgiHeaderCookieSetInteger(char *name, int value,
+  int secondsToLive, char *path, char *domain)</a>
+</strong><br><dd>
+cgiHeaderCookieSetInteger() is identical to
+<a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>,
+except that the value to be set is an integer rather than a string.
+See <a href="#cgiHeaderCookieSetString">cgiHeaderCookieSetString</a>
+for complete information.
+<br>
+<br><dt><strong><a name="cgiCookieString">cgiFormResultType cgiCookieString(
+  char *name, char *result, int max)</a>
+</strong><br><dd>cgiFormString attempts to retrieve the string sent for the
+  specified cookie (browser-side persistent storage). The 
+  text will be copied into
+  the buffer specified by result, up to but not
+  exceeding max-1 bytes; a terminating null is then
+  added to complete the string.
+  cgiCookieString returns <a href="#cgiFormSuccess">cgiFormSuccess</a> if the string was 
+  successfully retrieved, 
+  <a href="#cgiFormTruncated">cgiFormTruncated</a> if the string was
+  retrieved but was truncated to fit the buffer,
+  cgiFormEmpty if the string was 
+  retrieved but was empty, and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no 
+  such cookie was submitted. In the last case, 
+  an empty string is copied to result. 
+<br><br><dt><strong><a name="cgiCookieInteger">cgiFormResultType cgiCookieInteger(
+  char *name, int *result, int defaultV)</a>
+  See also <a href="#cgiCookieString">cgiCookieInteger</a>,
+  <a href="#cgiCookies">cgiCookies</a>,
+  <a href="#cgiHeaderCookieSetString>cgiHeaderCookieSetString</a>, and
+  <a href="#cgiHeaderCookieSetInteger>cgiHeaderCookieSetInteger</a>.
+</strong><br><dd>cgiCookieInteger() attempts to retrieve the integer sent for the
+  specified cookie (browser-side persistent storage). The value 
+  pointed to by result will be set to the value submitted. 
+  cgiCookieInteger() returns 
+  cgiFormSuccess if the value was successfully retrieved,
+  cgiFormEmpty if the value submitted is an empty string,
+  cgiFormBadType if the value submitted is not an integer,
+  and <a href="#cgiFormNotFound">cgiFormNotFound</a> if no such 
+  input field was submitted. In the last three cases, the value 
+  pointed to by result is set to the specified default.
+  See also <a href="#cgiCookieString">cgiCookieString</a>,
+  <a href="#cgiCookies">cgiCookies</a>,
+  <a href="#cgiHeaderCookieSetString>cgiHeaderCookieSetString</a>, and
+  <a href="#cgiHeaderCookieSetInteger>cgiHeaderCookieSetInteger</a>.
+<br><br><dt><strong><a name="cgiCookies">cgiFormResultType cgiCookies(
+  char *name, char ***ptrToStringArray)</a>
+</strong><br><dd>cgiCookies is useful when the programmer cannot know the names
+  of all relevant cookies (browser-side persistent strings) in advance.
+  The value pointed to by result will be set to a pointer to an array 
+  of strings; the last
+  entry in the array will be a null pointer.  This array is allocated 
+  by the CGI library. Important: when done working with the array,
+  you must call cgiStringArrayFree() with the array pointer as the 
+  argument. cgiCookies() returns <a href="#cgiFormSuccess">cgiFormSuccess</a> except in the event of an out of memory error.
+  On success, ptrToStringArray is set to point to a 
+  valid array of strings, with the last element in the array being a 
+  null pointer; in the out-of-memory case ptrToStringArray is set to 
+  a null pointer, and 
+  <a href="#cgiFormOutOfMemory">cgiFormOutOfMemory</a> is returned.
+<br><br><dt><strong><a name="cgiHtmlEscape">
+cgiFormResultType cgiHtmlEscape(char *s)</a>
+</strong><br><dd>
+cgiHtmlEscape() outputs the specified null-terminated string to 
+<a href="#cgiOut">cgiOut</a>,
+escaping any &lt;, &amp;, and &gt; characters encountered correctly so that
+they do not interfere with HTML markup. Returns 
+<a href="#cgiFormSuccess">cgiFormSuccess</a>, or
+<a href="#cgiFormIO">cgiFormIO</a> in the event of an I/O error.
+<p> 
+<br><br><dt><strong><a name="cgiHtmlEscapeData">
+cgiFormResultType cgiHtmlEscapeData(char *data, int len)</a>
+</strong><br><dd>
+cgiHtmlEscapeData() is identical to <a href="#cgiHtmlEscape">cgiHtmlEscape</a>,
+except that the data is not null-terminated. This version of the function
+outputs <code>len</code> bytes. See <a href="#cgiHtmlEscape">cgiHtmlEscape</a>
+for more information.
+<br><br><dt><strong><a name="cgiValueEscape">
+cgiFormResultType cgiValueEscape(char *s)</a>
+</strong><br><dd>
+cgiValueEscape() outputs the specified null-terminated string to 
+<a href="#cgiOut">cgiOut</a>,
+escaping any " characters encountered correctly so that
+they do not interfere with the quotation marks of HTML attribute
+values. This is useful when outputting a string as part of the
+value attribute of an input tag, or the href attribute of a link
+or form tag. This function returns
+<a href="#cgiFormSuccess">cgiFormSuccess</a>, or
+<a href="#cgiFormIO">cgiFormIO</a> in the event of an I/O error.
+<p> 
+<br><br><dt><strong><a name="cgiValueEscapeData">
+cgiFormResultType cgiValueEscapeData(char *data, int len)</a>
+</strong><br><dd>
+cgiValueEscapeData() is identical to <a href="#cgiValueEscape">cgiValueEscape</a>,
+except that the data is not null-terminated. This version of the function
+outputs <code>len</code> bytes. See <a href="#cgiValueEscape">cgiValueEscape</a>
+for more information.
+<br><br><dt><strong><a name="cgiWriteEnvironment">
+cgiEnvironmentResultType cgiWriteEnvironment(char *filename)</a>
+</strong><br><dd>
+cgiWriteEnvironment() can
+  be used to write the entire CGI environment, including
+  form data, to the specified output file; <a href="#cgiReadEnvironment">
+  cgiReadEnvironment()</a> 
+  can then be used to restore that environment from the specified
+  input file for debugging. Of course, these will only work as expected
+  if you use the <a href="#variables">cgic copies of the CGI environment 
+  variables</a> and <a href="#cgiIn">cgiIn</a> and 
+  <a href="#cgiOut">cgiOut</a> rather than stdin and
+  stdout (also see above). These functions are useful in order 
+  to capture real CGI situations while the web server is running, then
+  recreate them in a debugging environment. Both functions
+  return <a href="#cgiEnvironmentSuccess">cgiEnvironmentSuccess</a> on 
+  success, <a href="#cgiEnvironmentIO">cgiEnvironmentIO</a> on an I/O 
+  error, and <a href="#cgiEnvironmentMemory">cgiEnvironmentMemory</a>
+  on an out-of-memory error.
+<br><br><dt><strong><a name="cgiReadEnvironment">
+cgiEnvironmentResultType cgiReadEnvironment(char *filename)</a>
+</strong><br><dd>
+cgiReadEnvironment() restores a CGI environment saved to the specified file by
+  <a href="#cgiWriteEnvironment">cgiWriteEnvironment().</a> 
+  Of course, these will only work as expected
+  if you use the <a href="#variables">cgic copies of the CGI environment 
+  variables</a> and <a href="#cgiIn">cgiIn</a> and 
+  <a href="#cgiOut">cgiOut</a> rather than stdin and
+  stdout (also see above). These functions are useful in order 
+  to capture real CGI situations while the web server is running, then
+  recreate them in a debugging environment. Both functions
+  return <a href="#cgiEnvironmentSuccess">cgiEnvironmentSuccess</a> on success, 
+  <a href="#cgiEnvironmentIO">cgiEnvironmentIO</a> on an I/O error, and 
+  <a href="#cgiEnvironmentMemory">cgiEnvironmentMemory</a>
+  on an out-of-memory error.
+<br><br><dt><strong><a name="cgiMain">int cgiMain()</a>
+</strong><br><dd><strong>The programmer must write this function</strong>, which performs 
+  the unique task of the program and is invoked by the true main() 
+  function, found in the cgic library itself. The return value from 
+  cgiMain will be the return value of the program. It is expected that 
+  the user will make numerous calls to the cgiForm functions
+  from within this function. See <a href="#howto">how to write
+  a cgic application</a> for details.
+</dl>
+<h3><a name="variables">cgic variable reference</a></h3>
+This section provides a reference guide to the various global
+variables provided by cgic for the programmer to utilize.
+These variables should always be used in preference to
+stdin, stdout, and calls to getenv() in order to ensure
+compatibility with the <a href="#debug">cgic CGI debugging features</a>.
+<p>
+Most of these variables are equivalent to various CGI environment
+variables. The most important difference is that the cgic
+environment string variables are never null pointers. They will always 
+point to valid C strings of zero or more characters.
+<dl>
+<br><dt><strong><a name="cgiServerSoftware">char *cgiServerSoftware</a>
+</strong><br><dd>Points to the name of the server software,
+or to an empty string if unknown.
+<br><dt><strong><a name="cgiServerName">char *cgiServerName</a>
+</strong><br><dd>Points to the name of the server,
+or to an empty string if unknown.
+<br><dt><strong><a name="cgiGatewayInterface">char *cgiGatewayInterface</a>
+</strong><br><dd>Points to the name of the gateway interface (usually CGI/1.1),
+or to an empty string if unknown.
+<br><dt><strong><a name="cgiServerProtocol">char *cgiServerProtocol</a>
+</strong><br><dd>Points to the protocol in use (usually HTTP/1.0),
+or to an empty string if unknown.
+<br><dt><strong><a name="cgiServerPort">char *cgiServerPort</a>
+</strong><br><dd>Points to the port number on which the server is listening
+for HTTP connections (usually 80), or an empty string if unknown.
+<br><dt><strong><a name="cgiRequestMethod">char *cgiRequestMethod</a>
+</strong><br><dd>Points to the method used in the request (usually GET or POST),
+or an empty string if unknown (this should not happen).
+<br><dt><strong><a name="cgiPathInfo">char *cgiPathInfo</a>
+</strong><br><dd>Most web servers recognize any additional path information in 
+the URL of the request beyond the name of the CGI program itself and
+pass that information on to the program. cgiPathInfo points to this
+additional path information.
+<br><dt><strong><a name="cgiPathTranslated">char *cgiPathTranslated</a>
+</strong><br><dd>Most web servers recognize any additional path information in 
+the URL of the request beyond the name of the CGI program itself and
+pass that information on to the program. cgiPathTranslated points
+to this additional path information, translated by the server into a 
+filesystem path on the local server.
+<br><dt><strong><a name="cgiScriptName">char *cgiScriptName</a>
+</strong><br><dd>Points to the name under which the program was invoked.
+<br><dt><strong><a name="cgiQueryString">char *cgiQueryString</a>
+</strong><br><dd>Contains any query information submitted by the user as a result
+of a GET-method form or an &lt;ISINDEX&gt; tag. Note that this
+information need not be parsed directly unless an &lt;ISINDEX&gt; tag
+was used; normally it is parsed automatically by the cgic library. Use 
+the cgiForm family of functions to retrieve the values associated
+with form input fields. See <a href="#howto">how to write
+a cgic application</a> for more information.
+<br><dt><strong><a name="cgiRemoteHost">char *cgiRemoteHost</a>
+</strong><br><dd>Points to the fully resolved hostname of the browser, if known,
+or an empty string if unknown.
+<br><dt><strong><a name="cgiRemoteAddr">char *cgiRemoteAddr</a>
+</strong><br><dd>Points to the dotted-decimal IP address of the browser, if known,
+or an empty string if unknown.
+<br><dt><strong><a name="cgiAuthType">char *cgiAuthType</a>
+</strong><br><dd>Points to the type of authorization used for the request,
+if any, or an empty string if none or unknown.
+<br><dt><strong><a name="cgiRemoteUser">char *cgiRemoteUser</a>
+</strong><br><dd>Points to the user name under which the user has 
+authenticated; an empty string if no authentication has
+taken place. The certainty of this information depends on
+the type of authorization in use; see
+<a href="#cgiAuthType">cgiAuthType</a>.
+<br><dt><strong><a name="cgiRemoteIdent">char *cgiRemoteIdent</a>
+</strong><br><dd>Points to the user name volunteered by the user via
+the user identification protocol; an empty
+string if unknown. This information is not secure.
+Identification demons can be installed by users on
+insecure systems such as Windows machines.
+<br><dt><strong><a name="cgiContentType">char *cgiContentType</a>
+</strong><br><dd>Points to the MIME content type of the information
+submitted by the user, if any; an empty string if no
+information was submitted. If this string is equal to
+<code>application/x-www-form-urlencoded</code> or
+<code>multipart/form-data</code>, the cgic
+library will automatically examine the form data submitted.
+If this string has any other non-empty value, a different
+type of data has been submitted. This is currently very rare,
+as most browsers can only submit forms and file uploads which
+cgic parses directly.
+<br><dt><strong><a name="cgiContentType">char *cgiCookie</a>
+</strong><br><dd>Points to the raw cookie (browser-side persistent storage)
+data submitted by the web browser. 
+Programmers should use the functions <a href="#cgiCookies">cgiCookies</a>,
+<a href="#cgiCookieString">cgiCookieString</a> and
+<a href="#cgiCookieInteger">cgiCookieInteger</a> instead of
+examining this string directly.
+<br><dt><strong><a name="cgiAccept">char *cgiAccept</a>
+</strong><br><dd>Points to a space-separated list of MIME content types
+acceptable to the browser (see <a href="#cgiHeaderContentType">
+cgiHeaderContentType()</a> ), or an empty string. Unfortunately, this variable
+is not supplied in a useful form by most current browsers. Programmers wishing
+to make decisions based on the capabilities of the browser
+are advised to check the <a href="#cgiUserAgent">cgiUserAgent</a>
+variable against a list of browsers and capabilities instead.
+<br><dt><strong><a name="cgiUserAgent">char *cgiUserAgent</a>
+</strong><br><dd>
+Points to the name of the browser in use, or an empty
+string if this information is not available. 
+<br><dt><strong><a name="cgiReferrer">char *cgiReferrer</a>
+</strong><br><dd>
+Points to the URL of the previous page visited by the user. This is
+often the URL of the form that brought the user to your program.
+Note that reporting this information is entirely up to the browser,
+which may choose not do so, and may choose not to do so truthfully.
+However, this variable is typically accurate. <strong>The frequently
+used misspelling cgiReferer is also supplied as a macro.</strong>
+<br><dt><strong><a name="cgiContentLength">int cgiContentLength</a>
+</strong><br><dd>The number of bytes of form or query data received.
+  Note that if the submission is a form or query submission
+  the library will read and parse all the information
+  directly from cgiIn and/or cgiQueryString. The programmer should
+  not do so, and indeed the cgiIn pointer will be at end-of-file
+  in such cases.
+<br><dt><strong><a name="cgiOut">FILE *cgiOut</a>
+</strong><br><dd>Pointer to CGI output. The cgiHeader functions, such as
+  <a href="#cgiHeaderContentType">cgiHeaderContentType</a>, should 
+  be used first to output the mime headers; the output HTML
+  page, GIF image or other web document should then be written
+  to cgiOut by the programmer using standard C I/O functions
+  such as fprintf() and fwrite(). cgiOut is normally equivalent
+  to stdout; however, it is recommended that cgiOut be used to
+  ensure compatibility with future versions of cgic for
+  specialized environments.
+<br><dt><strong><a name="cgiIn">FILE *cgiIn</a>
+</strong><br><dd>Pointer to CGI input. In 99.99% of cases, you will not 
+  need this. CGIC 2.0 supports both regular POST form submissions
+  and multipart/form-data file upload form submissions directly.
+</dl>
+<H3><a name="resultcodes">cgic result code reference</a></h3>
+<p>
+In most cases, cgic functions are designed to produce reasonable results
+even when browsers and users do unreasonable things. However, it is sometimes
+important to know precisely which unreasonable things took place, especially
+when assigning a default value or bounding a value is an inadequate
+solution. The following result codes are useful in making this determination.
+<dl>
+<br><dt><strong><a name="cgiFormSuccess">cgiFormSuccess</a>
+</strong><br><dd>Indicates that the function successfully performed at least one
+action (or retrieved at least one value, where applicable).
+<br><dt><strong><a name="cgiFormTruncated">cgiFormTruncated</a>
+</strong><br><dd>Indicates that a string value retrieved from the user was
+cut short to avoid overwriting the end of a buffer.
+<br><dt><strong><a name="cgiFormBadType">cgiFormBadType</a>
+</strong><br><dd>Indicates that a "numeric" value submitted by the user was
+in fact not a legal number.
+<br><dt><strong><a name="cgiFormEmpty">cgiFormEmpty</a>
+</strong><br><dd>Indicates that a field was retrieved but contained no data.
+<br><dt><strong><a name="cgiFormNotFound">cgiFormNotFound</a>
+</strong><br><dd>Indicates that no value was submitted for a particular field.
+<br><dt><strong><a name="cgiFormConstrained">cgiFormConstrained</a>
+</strong><br><dd>Indicates that a numeric value was beyond the specified bounds
+and was forced to the lower or upper bound as appropriate.
+<br><dt><strong><a name="cgiFormNoSuchChoice">cgiFormNoSuchChoice</a>
+</strong><br><dd>Indicates that the value submitted for a single-choice field
+(such as a radio-button group) was not one of the acceptable values.
+This usually indicates a discrepancy between the form and the program.
+<br><dt><strong><a name="cgiFormEOF">cgiFormEOF</a>
+</strong><br><dd>Returned by <a href="#cgiFormFileRead">cgiFormFileRead</a>
+when, at the start of the call, the cgiFilePtr object is already
+positioned at the end of the uploaded file data. 
+<br><dt><strong><a name="cgiFormEOF">cgiFormIO</a>
+</strong><br><dd>Returned by <a href="#cgiFormFileRead">cgiFormFileRead</a>
+when an I/O error occurs while reading uploaded file data.
+<br><dt><strong><a name="cgiFormNotAFile">cgiFormNotAFile</a>
+</strong><br><dd>Returned in response to an attempt to manipulate a form field
+that is not a file upload field using a file-related function.
+<br><dt><strong><a name="cgiFormNoContentType">cgiFormNoContentType</a>
+</strong><br><dd>Returned in response to an attempt to fetch the content type of
+a file-upload field when the content type is not specified by the browser.
+<br><dt><strong><a name="cgiFormNoFileName">cgiFormNoFileName</a>
+</strong><br><dd>Returned in response to an attempt to fetch the file name of
+a file-upload field when a file name is not specified by the browser.
+<br><dt><strong><a name="cgiFormOpenFailed">cgiFormOpenFailed</a>
+</strong><br><dd>Returned in response to an attempt to read from a null
+cgiFilePtr object, typically when the programmer has failed to
+check the result of a call to <a href="#cgiFormFileOpen">cgiFormFileOpen</a>.
+<br><dt><strong><a name="cgiEnvironmentMemory">cgiEnvironmentMemory</a>
+</strong><br><dd>Indicates that an attempt to read or write the CGI environment
+to or from a capture file failed due to an out-of-memory error.
+<br><dt><strong><a name="cgiEnvironmentSuccess">cgiEnvironmentSuccess</a>
+</strong><br><dd>Indicates that an attempt to read or write the CGI environment
+to or from a capture file was successful.
+<br><dt><strong><a name="cgiEnvironmentIO">cgiEnvironmentIO</a>
+</strong><br><dd>Indicates that an attempt to read or write the CGI environment
+to or from a capture file failed due to an I/O error. 
+<br><dt><strong><a name="cgiEnvironmentWrongVersion">cgiEnvironmentWrongVersion</a>
+</strong><br><dd>Indicates that an attempt to read from a saved debugging CGI environment
+produced by a pre-2.0 version of CGIC was made. 
+</dl>
+<h3><a name="index">cgic quick index</a></h3>
+<a href="#cgiAccept">cgiAccept</a> |
+<a href="#cgiAuthType">cgiAuthType</a> |
+<a href="#cgiContentLength">cgiContentLength</a> |
+<a href="#cgiContentType">cgiContentType</a> |
+<a href="#cgiEnvironmentIO">cgiEnvironmentIO</a> |
+<a href="#cgiEnvironmentMemory">cgiEnvironmentMemory</a> |
+<a href="#cgiEnvironmentSuccess">cgiEnvironmentSuccess</a> |
+<a href="#cgiCookieInteger">cgiCookieInteger</a> |
+<a href="#cgiCookies">cgiCookies</a> |
+<a href="#cgiCookieSetInteger">cgiCookieSetInteger</a> |
+<a href="#cgiCookieSetString">cgiCookieSetString</a> |
+<a href="#cgiCookieString">cgiCookieString</a> |
+<a href="#cgiHtmlEscape">cgiHtmlEscape</a> |
+<a href="#cgiHtmlEscapeData">cgiHtmlEscapeData</a> |
+<a href="#cgiValueEscape">cgiValueEscape</a> |
+<a href="#cgiValueEscapeData">cgiValueEscapeData</a> |
+<a href="#cgiFormBadType">cgiFormBadType</a> |
+<a href="#cgiFormCheckboxMultiple">cgiFormCheckboxMultiple()</a> |
+<a href="#cgiFormCheckboxSingle">cgiFormCheckboxSingle()</a> |
+<a href="#cgiFormConstrained">cgiFormConstrained</a> |
+<a href="#cgiFormDouble">cgiFormDouble()</a> |
+<a href="#cgiFormDoubleBounded">cgiFormDoubleBounded()</a> |
+<a href="#cgiFormEOF">cgiFormEOF</a> |
+<a href="#cgiFormEmpty">cgiFormEmpty</a> |
+<a href="#cgiFormEntries">cgiFormEntries</a> |
+<a href="#cgiFormFileClose">cgiFormFileClose</a> |
+<a href="#cgiFormFileContentType">cgiFormFileContentType</a> |
+<a href="#cgiFormFileName">cgiFormFileName</a> |
+<a href="#cgiFormFileOpen">cgiFormFileOpen</a> |
+<a href="#cgiFormFileRead">cgiFormFileRead</a> |
+<a href="#cgiFormFileSize">cgiFormFileSize</a> |
+<a href="#cgiFormInteger">cgiFormInteger()</a> |
+<a href="#cgiFormIntegerBounded">cgiFormIntegerBounded()</a> |
+<a href="#cgiFormNoContentType>cgiFormNoContentType</a> |
+<a href="#cgiFormNoFileName>cgiFormNoFileName</a> |
+<a href="#cgiFormNoSuchChoice">cgiFormNoSuchChoice</a> |
+<a href="#cgiFormNotAFile>cgiFormNotAFile</a> |
+<a href="#cgiFormNotFound">cgiFormNotFound</a> |
+<a href="#cgiFormRadio">cgiFormRadio()</a> |
+<a href="#cgiFormSelectMultiple">cgiFormSelectMultiple()</a> |
+<a href="#cgiFormSelectSingle">cgiFormSelectSingle()</a> |
+<a href="#cgiFormString">cgiFormString()</a> |
+<a href="#cgiFormStringMultiple">cgiFormStringMultiple()</a> |
+<a href="#cgiFormStringNoNewlines">cgiFormStringNoNewlines()</a> |
+<a href="#cgiFormStringSpaceNeeded">cgiFormStringSpaceNeeded()</a> |
+<a href="#cgiFormSuccess">cgiFormSuccess</a> |
+<a href="#cgiFormTruncated">cgiFormTruncated</a> |
+<a href="#cgiGatewayInterface">cgiGatewayInterface</a> |
+<a href="#cgiHeaderContentType">cgiHeaderContentType()</a> |
+<a href="#cgiHeaderLocation">cgiHeaderLocation()</a> |
+<a href="#cgiHeaderStatus">cgiHeaderStatus()</a> |
+<a href="#cgiIn">cgiIn</a> |
+<a href="#cgiMain">cgiMain()</a>
+<a href="#cgiOut">cgiOut</a> |
+<a href="#cgiPathInfo">cgiPathInfo</a> |
+<a href="#cgiPathTranslated">cgiPathTranslated</a> |
+<a href="#cgiQueryString">cgiQueryString</a> |
+<a href="#cgiReadEnvironment">cgiReadEnvironment()</a> |
+<a href="#cgiReferrer">cgiReferrer()</a> |
+<a href="#cgiRemoteAddr">cgiRemoteAddr</a> |
+<a href="#cgiRemoteHost">cgiRemoteHost</a> |
+<a href="#cgiRemoteIdent">cgiRemoteIdent</a> |
+<a href="#cgiRemoteUser">cgiRemoteUser</a> |
+<a href="#cgiRequestMethod">cgiRequestMethod</a> |
+<a href="#cgiScriptName">cgiScriptName</a> |
+<a href="#cgiServerName">cgiServerName</a> |
+<a href="#cgiServerPort">cgiServerPort</a> |
+<a href="#cgiServerProtocol">cgiServerProtocol</a> |
+<a href="#cgiServerSoftware">cgiServerSoftware</a> |
+<a href="#cgiStringArrayFree">cgiStringArrayFree()</a> |
+<a href="#cgiUserAgent">cgiUserAgent</a> |
+<a href="#cgiWriteEnvironment">cgiWriteEnvironment()</a>
+<p>
+<hr>
+<em><a href="http://www.boutell.com/">Boutell.Com, Inc.</a></em>
+</body>
+</html>
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgictest.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgictest.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/cgictest.c	(revision 672)
@@ -0,0 +1,222 @@
+
+/*
+  $Id: cgictest.c,v 1.2 2004/04/07 17:09:27 fox Exp $
+ */
+
+#include <stdio.h>
+#include "cgic.h"
+
+void Name();
+void Address();
+void Hungry();
+void Temperature();
+void Frogs();
+void Color();
+void Flavors();
+void NonExButtons();
+void RadioButtons();
+
+
+int cgiMain() {
+#if DEBUG
+	/* Load a saved CGI scenario if we're debugging */
+	cgiReadEnvironment("/home/boutell/public_html/capcgi.dat");
+#endif
+	dup2(cgiOut,stdout);
+	printf("Content-Type: text/html; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
+	//cgiHeaderContentType("text/html");
+	printf( "<HTML><HEAD>\n");
+	printf( "<TITLE>cgic test</TITLE></HEAD>\n");
+	printf( "<BODY><H1>cgic test</H1>\n");
+	Name();
+	Address();
+	Hungry();
+	Temperature();
+	Frogs();
+	Color();
+	Flavors();
+	NonExButtons();
+	RadioButtons();
+	printf( "</BODY></HTML>\n");
+	return 0;
+}
+
+void Name() {
+	char name[81];
+	int result = cgiFormStringNoNewlines("name", name, 81);
+	switch (result) {
+		case cgiFormSuccess:
+		printf( "Name fetched, result code: cgiFormSuccess<br>\n");
+		break;
+		case cgiFormTruncated:
+		printf( "Name fetched, result code: cgiFormTruncated<br>\n");
+		break;
+		case cgiFormEmpty:
+		printf( "Name fetched, result code: cgiFormEmpty<br>\n");
+		break;
+		case cgiFormNotFound:
+		printf( "Name fetched, result code: cgiFormNotFound<br>\n");
+		break;
+		case cgiFormMemory:
+		printf( "Name fetched, result code: cgiFormMemory<br>\n");
+		break;
+		default:
+		printf( "Name fetched, unexpected result code: %d\n", result);
+		break;
+	}	
+	printf( "Name: %s<BR>\n", name);
+}
+	
+void Address() {
+	char address[241];
+	cgiFormString("address", address, 241);
+	printf( "Address: <PRE>\n%s</PRE>\n", address);
+}
+
+void Hungry() {
+	if (cgiFormCheckboxSingle("hungry") == cgiFormSuccess) {
+		printf( "I'm Hungry!<BR>\n");
+	} else {
+		printf( "I'm Not Hungry!<BR>\n");
+	}
+}
+	
+void Temperature() {
+	double temperature;
+	cgiFormDoubleBounded("temperature", &temperature, 80.0, 120.0, 98.6);
+	printf( "My temperature is %f.<BR>\n", temperature);
+}
+	
+void Frogs() {
+	int frogsEaten;
+	cgiFormInteger("frogs", &frogsEaten, 0);
+	printf( "I have eaten %d frogs.<BR>\n", frogsEaten);
+}
+
+char *colors[] = {
+	"Red",
+	"Green",
+	"Blue"
+};
+
+void Color() {
+	int colorChoice;
+	cgiFormSelectSingle("colors", colors, 3, &colorChoice, 0);
+	printf( "I am: %s<BR>\n", colors[colorChoice]);
+}	 
+
+char *flavors[] = {
+	"pistachio",
+	"walnut",
+	"creme"
+};
+
+void Flavors() {
+	int flavorChoices[3];
+	int i;
+	int result;	
+	int invalid;
+	result = cgiFormSelectMultiple("flavors", flavors, 3, 
+		flavorChoices, &invalid);
+	if (result == cgiFormNotFound) {
+		printf( "I hate ice cream.<p>\n");
+	} else {	
+		printf( "My favorite ice cream flavors are:\n");
+		printf( "<ul>\n");
+		for (i=0; (i < 3); i++) {
+			if (flavorChoices[i]) {
+				printf( "<li>%s\n", flavors[i]);
+			}
+		}
+		printf( "</ul>\n");
+	}
+}
+
+char *ages[] = {
+	"1",
+	"2",
+	"3",
+	"4"
+};
+
+void RadioButtons() {
+	int ageChoice;
+	char ageText[10];
+	/* Approach #1: check for one of several valid responses. 
+		Good if there are a short list of possible button values and
+		you wish to enumerate them. */
+	cgiFormRadio("age", ages, 4, &ageChoice, 0);
+
+	printf( "Age of Truck: %s (method #1)<BR>\n", 
+		ages[ageChoice]);
+
+	/* Approach #2: just get the string. Good
+		if the information is not critical or if you wish
+		to verify it in some other way. Note that if
+		the information is numeric, cgiFormInteger,
+		cgiFormDouble, and related functions may be
+		used instead of cgiFormString. */	
+	cgiFormString("age", ageText, 10);
+
+	printf( "Age of Truck: %s (method #2)<BR>\n", ageText);
+}
+
+char *votes[] = {
+	"A",
+	"B",
+	"C",
+	"D"
+};
+
+void NonExButtons() {
+	int voteChoices[4];
+	int i;
+	int result;	
+	int invalid;
+
+	char **responses;
+
+	/* Method #1: check for valid votes. This is a good idea,
+		since votes for nonexistent candidates should probably
+		be discounted... */
+	printf( "Votes (method 1):<BR>\n");
+	result = cgiFormCheckboxMultiple("vote", votes, 4, 
+		voteChoices, &invalid);
+	if (result == cgiFormNotFound) {
+		printf( "I hate them all!<p>\n");
+	} else {	
+		printf( "My preferred candidates are:\n");
+		printf( "<ul>\n");
+		for (i=0; (i < 4); i++) {
+			if (voteChoices[i]) {
+				printf( "<li>%s\n", votes[i]);
+			}
+		}
+		printf( "</ul>\n");
+	}
+
+	/* Method #2: get all the names voted for and trust them.
+		This is good if the form will change more often
+		than the code and invented responses are not a danger
+		or can be checked in some other way. */
+	printf( "Votes (method 2):<BR>\n");
+	result = cgiFormStringMultiple("vote", &responses);
+	if (result == cgiFormNotFound) {	
+		printf( "I hate them all!<p>\n");
+	} else {
+		int i = 0;
+		printf( "My preferred candidates are:\n");
+		printf( "<ul>\n");
+		while (responses[i]) {
+			printf( "<li>%s\n", responses[i]);
+			i++;
+		}
+		printf( "</ul>\n");
+	}
+	/* We must be sure to free the string array or a memory
+		leak will occur. Simply calling free() would free
+		the array but not the individual strings. The
+		function cgiStringArrayFree() does the job completely. */	
+	cgiStringArrayFree(responses);
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/changelog
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/changelog	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/changelog	(revision 672)
@@ -0,0 +1,32 @@
+libcgic (2.06-1~trusty3) trusty; urgency=low
+
+  * New version to be used for ZOO-Kernel.
+
+ -- Angelos Tzotsos <gcpp.kalxas@gmail.com>  Tue, 10 Jun 2014 19:29:04 +0200
+
+libcgic (2.05-3) unstable; urgency=low
+
+  * debian/control: Suggests: httpd.  Closes: #600138.
+  * debian/control: Fixed debhelper-but-no-misc-depends.
+
+ -- Bart Martens <bartm@debian.org>  Sun, 13 May 2012 08:33:04 +0000
+
+libcgic (2.05-2) unstable; urgency=low
+
+  * debian/control: Standards-Version, Homepage.
+
+ -- Bart Martens <bartm@debian.org>  Sun, 13 Jul 2008 09:31:48 +0200
+
+libcgic (2.05-1) unstable; urgency=low
+
+  * New maitnainer.  Closes: #438643.
+  * New upstream release.
+  * debian/*: Repackaged with cdbs.
+  * debian/changelog-upstream.html: Removed.
+  * debian/Makefile.examples: Removed.
+  * debian/README.Debian: Removed.
+  * debian/copyright: Updated.
+  * debian/watch: Updated.
+
+ -- Bart Martens <bartm@knars.be>  Sun, 19 Aug 2007 09:18:53 +0200
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/compat
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/compat	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/compat	(revision 672)
@@ -0,0 +1,1 @@
+5
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/control
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/control	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/control	(revision 672)
@@ -0,0 +1,35 @@
+Source: libcgic
+Section: libs
+Priority: optional
+Maintainer: Bart Martens <bartm@debian.org>
+Build-Depends: cdbs, libfcgi-dev, debhelper (>= 5)
+Standards-Version: 3.9.3
+Homepage: http://www.boutell.com/cgic/
+
+Package: libcgic-dev
+Section: libdevel
+Architecture: any
+Depends: libc6-dev, ${misc:Depends}
+Suggests: httpd
+Conflicts: libcgicg1-dev
+Replaces: libcgicg1-dev
+Description: C library for developing CGI applications
+ Cgic is an ANSI-C library for the creation of CGI-based World Wide Web
+ applications.  Cgic provides the following:
+ .
+   * Parses form data, correcting for defective and/or inconsistent
+     browsers
+   * Transparently accepts both GET and POST form data
+   * Handles line breaks in form fields in a consistent manner
+   * Provides string, integer, floating-point, and single- and
+     multiple-choice functions to retrieve form data
+   * Provides bounds checking for numeric fields
+   * Loads CGI environment variables into C strings which are always
+     non-null
+   * Provides a way to capture CGI situations for replay in a debugging
+     environment
+ .
+ This package provides a static library version of cgic, examples of using
+ cgic (including a CGI application that captures a CGI environment for use
+ in debugging), and header files.
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/copyright
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/copyright	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/copyright	(revision 672)
@@ -0,0 +1,28 @@
+This package was debianized by Brian Bassett brian@butterfly.ml.org on
+Tue, 11 Nov 1997 17:28:04 -0800.
+
+It was downloaded from:
+
+    http://www.boutell.com/cgic/
+
+Upstream author:
+
+    Thomas Boutell <boutell@boutell.com>
+
+Copyright:
+
+    Copyright (C) 1996-2004 by Thomas Boutell and Boutell.Com, Inc.
+
+License:
+
+    CGIC, copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+    2004 by Thomas Boutell and Boutell.Com, Inc.. Permission is granted to
+    use CGIC in any application, commercial or noncommercial, at no cost.
+    HOWEVER, this copyright paragraph must appear on a "credits" page
+    accessible in the public online and offline documentation of the program.
+    Modified versions of the CGIC library should not be distributed without
+    the attachment of a clear statement regarding the author of the
+    modifications, and this notice may in no case be removed.
+    Modifications may also be submitted to the author for inclusion
+    in the main CGIC distribution.
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.docs
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.docs	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.docs	(revision 672)
@@ -0,0 +1,1 @@
+cgic.html
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.examples
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.examples	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.examples	(revision 672)
@@ -0,0 +1,2 @@
+capture.c
+cgictest.c
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.install
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.install	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.install	(revision 672)
@@ -0,0 +1,2 @@
+cgic.h usr/include/
+libcgic.a usr/lib/
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.links
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.links	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/libcgic-dev.links	(revision 672)
@@ -0,0 +1,1 @@
+/usr/lib/libcgic.so.2.06 /usr/lib/libcgic.so
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/rules
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/rules	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/rules	(revision 672)
@@ -0,0 +1,7 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/makefile.mk
+
+clean::
+	rm -f libcgic.so.2.06
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/watch
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/watch	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/debian/watch	(revision 672)
@@ -0,0 +1,4 @@
+version=3
+opts="uversionmangle=s/^(\d)(\d\d)$/$1.$2/" \
+http://www.boutell.com/cgic/ \
+cgic(.*)\.t.*
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/license.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/license.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/license.txt	(revision 672)
@@ -0,0 +1,109 @@
+CGIC License Terms
+------------------
+
+Basic License
+-------------
+
+CGIC, copyright 2009 GeoLabs SARL.
+CGIC, copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+2004 by Thomas Boutell and Boutell.Com, Inc.. Permission is granted to 
+use CGIC in any application, commercial or noncommercial, at no cost. 
+HOWEVER, this copyright paragraph must appear on a "credits" page 
+accessible in the public online and offline documentation of the program. 
+Modified versions of the CGIC library should not be distributed without 
+the attachment of a clear statement regarding the author of the 
+modifications, and this notice may in no case be removed. 
+Modifications may also be submitted to the author for inclusion 
+in the main CGIC distribution.                                 
+
+IF YOU WOULD PREFER NOT TO ATTACH THE ABOVE NOTICE to
+the public documentation of your application, consult the
+information which follows regarding the availability
+of a nonexclusive commercial license for CGIC.
+
+Commercial License
+------------------
+
+The price of a nonexclusive commercial license is $200 U.S. 
+To purchase the license:
+
+1. Print and sign two copies of the document below.
+
+2. Send both copies, along with Visa, Mastercard, Discover, or
+Amex card number, cardholder's name, and expiration date 
+OR a check for $200 in U.S. funds drawn on a U.S. bank, to:
+
+Boutell.Com, Inc.
+PO Box 63767
+Philadelphia, PA 19147 USA
+
+Credit card orders may alternatively be faxed to:
+
+Boutell.Com, Inc.
+(208) 445-0327
+
+BE SURE TO INCLUDE AN EMAIL ADDRESS, as well as
+a postal address and phone number.
+
+3. We will return one signed copy to you promptly.
+
+You will also receive swift notification of new
+versions of CGIC, in addition to ongoing
+email support.
+
+* * *
+
+CGIC Nonexclusive Commercial License
+
+The licensee named below is granted the right
+to utilize CGIC, major version 1 or 2, any minor
+version thereof, in CGI applications without the
+need for a credit notice of any kind. CGI applications
+developed by the holder of this license may be
+distributed freely in source code or binary form
+without additional fees or royalties. This license does 
+not grant the right to use CGIC to create a development tool 
+which passes on substantially all of the capabilities of the 
+CGIC library to the user of the tool, unless that tool is 
+to be used internally by the license holder only in order
+to develop CGI applications. This license may not
+be resold, but applications developed in accordance
+with the terms of the license may be distributed
+freely subject to the limitations described above.
+
+Future minor (2.x) versions of CGIC will be covered by this
+license free of charge. If significant defects of workmanship
+are discovered in version 2.x, minor releases to correct them
+will be made available before or at the same time that 
+those defects are addressed in any future major version. 
+Future "major" (3.x) versions will be available to
+licensees at an upgrade price of $50.
+
+If, for any reason, any portion of this license is found 
+to be invalid, that portion of the license only
+is invalidated and the remainder of the agreement
+remains in effect.
+
+If this license has not been signed by Thomas Boutell
+or M. L. Grant on behalf of Boutell. Com, Inc., 
+it is invalid.
+
+Licensee's Name:              _____________________
+
+Signed for Licensee:          _____________________
+
+Complete Mailing Address:     _____________________
+
+                              _____________________
+
+                              _____________________
+
+Phone Number:                 _____________________
+
+Email Address:                _____________________
+
+Signed for Boutell.Com, Inc.: _____________________
+
+Date:                         _____________________
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/makefile.vc	(revision 672)
@@ -0,0 +1,35 @@
+GEODIR=\MMBK\SRCS\fcgi-2.4.1-SNAP-0311112127\ 
+DESTDIR=..
+CFLAGS=-g -Wall
+CC=cl /TP
+LIBS=$(GEODIR)/libfcgi/Release/libfcgi.lib /nologo
+LIBS1=./libcgic.lib
+
+CFLAGS=/EHa /nologo /DCRT_SECURE_NO_WARNING /MD /W2 /O2 /D "WIN32" \
+	-I $(GEODIR)\include 
+
+all: libcgic.lib #cgictest.exe capture.exe 
+
+install: libcgic.lib
+	copy libcgic.lib  $(DESTDIR)\lib
+	copy cgic.h  $(DESTDIR)\include
+	@echo libcgic.lib is now installed in  $(DESTDIR)\lib and cgic.h is in  $(DESTDIR)\include.
+
+libcgic.lib: cgic.obj cgic.h
+	if exist cgic.lib del cgic.lib
+	lib /out:libcgic.lib cgic.obj $(LIBS)
+
+cgictest.obj: cgictest.c libcgic.lib
+	$(CC) $(CFLAGS) -c cgictest.c
+
+cgictest.exe: cgictest.obj 
+	link cgictest.obj $(LIBS) /out:cgictest.exe
+
+cgic.obj: 
+	$(CC) $(CFLAGS) -c cgic.c 
+
+capture.exe: capture.obj libcgic.lib
+	$(CC) $(CFLAGS) capture.c $(LIBS)
+
+clean:
+	erase *.obj *.lib *.exe *.manifest
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/readme.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/readme.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/readme.txt	(revision 672)
@@ -0,0 +1,14 @@
+This is the CGIC CGI development library for C programmers.
+Copyright 2009 GeoLabs SARL
+Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+2004, Thomas Boutell and Boutell.Com, Inc.
+
+See the file cgic.html for complete documentation in a single
+HTML hypertext file to be accessed with your web browser. If you
+preferer, there is a plaintext version in the file cgic.txt. 
+Or see http://www.boutell.com/cgic/ for the latest copy of 
+the documentation.
+
+See the files license.txt and support.txt for terms of use and
+technical support information.
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/support.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/support.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/cgic206/support.txt	(revision 672)
@@ -0,0 +1,46 @@
+Support for CGIC
+----------------
+
+   ____
+  /    \
+ | STOP |
+  \____/
+  
+    Are you getting a "server error," indicating that your web server
+    "cannot allow POST to this URL," or a similar message? YOU MUST
+    CONFIGURE YOUR WEB SERVER TO ALLOW CGI PROGRAMS, AND YOU MUST
+    INSTALL CGI PROGRAMS IN THE LOCATION (OR WITH THE EXTENSION) THAT
+    YOUR WEB SERVER EXPECTS TO SEE. Please don't send me email about
+    this, unless you are purchasing commercial support. It is strictly 
+    between you and your web server's documentation, or between you and 
+    your ISP. If you wish to purchase commercial support, we will gladly 
+    attempt to help you resolve such problems, but the cooperation of 
+    your web server administrator will be necessary in most cases. Thanks!
+
+Free Support
+------------
+ 
+Anyone can mail questions about the gd and cgic libraries to 
+boutell@boutell.com. However, I receive a very large volume of email on 
+many subjects, and while I do my best to respond to all queries this can 
+take some time. Sometimes the response must take the form of an eventual 
+new release or an addition to a FAQ or other document, as opposed to an 
+detailed individual response.
+
+Hourly Support
+--------------
+
+Those requiring support in detail may arrange for direct support
+from the author, Thomas Boutell, at the rate of $50/hr, billed
+directly by credit card. Purchase orders are also accepted from
+Fortune 500 corporations and institutions in good standing.
+To make arrangements, contact boutell@boutell.com. Alternatively,
+use our free-form secure message page at:
+
+https://www.boutell.com/freeform/
+
+To avoid delay and/or confusion, be sure to specifically mention that 
+you wish to purchase CGIC support at the hourly rate above.
+
+-Thomas Boutell, boutell@boutell.com
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/dirent-win32/dirent.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/dirent-win32/dirent.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/dirent-win32/dirent.h	(revision 672)
@@ -0,0 +1,373 @@
+/*****************************************************************************
+ * dirent.h - dirent API for Microsoft Visual Studio
+ *
+ * Copyright (C) 2006 Toni Ronkko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Mar 15, 2011, Toni Ronkko
+ * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
+ *
+ * Aug 11, 2010, Toni Ronkko
+ * Added d_type and d_namlen fields to dirent structure.  The former is
+ * especially useful for determining whether directory entry represents a
+ * file or a directory.  For more information, see
+ * http://www.delorie.com/gnu/docs/glibc/libc_270.html
+ *
+ * Aug 11, 2010, Toni Ronkko
+ * Improved conformance to the standards.  For example, errno is now set
+ * properly on failure and assert() is never used.  Thanks to Peter Brockam
+ * for suggestions.
+ *
+ * Aug 11, 2010, Toni Ronkko
+ * Fixed a bug in rewinddir(): when using relative directory names, change
+ * of working directory no longer causes rewinddir() to fail.
+ *
+ * Dec 15, 2009, John Cunningham
+ * Added rewinddir member function
+ *
+ * Jan 18, 2008, Toni Ronkko
+ * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
+ * between multi-byte and unicode representations.  This makes the
+ * code simpler and also allows the code to be compiled under MingW.  Thanks
+ * to Azriel Fasten for the suggestion.
+ *
+ * Mar 4, 2007, Toni Ronkko
+ * Bug fix: due to the strncpy_s() function this file only compiled in
+ * Visual Studio 2005.  Using the new string functions only when the
+ * compiler version allows.
+ *
+ * Nov  2, 2006, Toni Ronkko
+ * Major update: removed support for Watcom C, MS-DOS and Turbo C to
+ * simplify the file, updated the code to compile cleanly on Visual
+ * Studio 2005 with both unicode and multi-byte character strings,
+ * removed rewinddir() as it had a bug.
+ *
+ * Aug 20, 2006, Toni Ronkko
+ * Removed all remarks about MSVC 1.0, which is antiqued now.  Simplified
+ * comments by removing SGML tags.
+ *
+ * May 14 2002, Toni Ronkko
+ * Embedded the function definitions directly to the header so that no
+ * source modules need to be included in the Visual Studio project.  Removed
+ * all the dependencies to other projects so that this very header can be
+ * used independently.
+ *
+ * May 28 1998, Toni Ronkko
+ * First version.
+ *****************************************************************************/
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+# define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat() */
+#if defined(_MSC_VER)  &&  !defined(S_IREAD)
+# define S_IFMT   _S_IFMT                      /* file type mask */
+# define S_IFDIR  _S_IFDIR                     /* directory */
+# define S_IFCHR  _S_IFCHR                     /* character device */
+# define S_IFFIFO _S_IFFIFO                    /* pipe */
+# define S_IFREG  _S_IFREG                     /* regular file */
+# define S_IREAD  _S_IREAD                     /* read permission */
+# define S_IWRITE _S_IWRITE                    /* write permission */
+# define S_IEXEC  _S_IEXEC                     /* execute permission */
+#endif
+#define S_IFBLK   0                            /* block device */
+#define S_IFLNK   0                            /* link */
+#define S_IFSOCK  0                            /* socket */
+
+#if defined(_MSC_VER)
+# define S_IRUSR  S_IREAD                      /* read, user */
+# define S_IWUSR  S_IWRITE                     /* write, user */
+# define S_IXUSR  0                            /* execute, user */
+# define S_IRGRP  0                            /* read, group */
+# define S_IWGRP  0                            /* write, group */
+# define S_IXGRP  0                            /* execute, group */
+# define S_IROTH  0                            /* read, others */
+# define S_IWOTH  0                            /* write, others */
+# define S_IXOTH  0                            /* execute, others */
+#endif
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* File type flags for d_type */
+#define DT_LNK -100
+#define DT_UNKNOWN  0
+#define DT_REG      S_IFREG
+#define DT_DIR      S_IFDIR
+#define DT_FIFO     S_IFFIFO
+#define DT_SOCK     S_IFSOCK
+#define DT_CHR      S_IFCHR
+#define DT_BLK      S_IFBLK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+ * File type macros.  Note that block devices, sockets and links cannot be
+ * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+ * only defined for compatibility.  These macros should always return false
+ * on Windows.
+ */
+#define	S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
+#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
+#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
+#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
+#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
+#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct dirent
+{
+   char d_name[MAX_PATH + 1];                  /* File name */
+   size_t d_namlen;                            /* Length of name without \0 */
+   int d_type;                                 /* File type */
+} dirent;
+
+
+typedef struct DIR
+{
+   dirent           curentry;                  /* Current directory entry */
+   WIN32_FIND_DATAA find_data;                 /* Private file data */
+   int              cached;                    /* True if data is valid */
+   HANDLE           search_handle;             /* Win32 search handle */
+   char             patt[MAX_PATH + 3];        /* Initial directory name */
+} DIR;
+
+
+/* Forward declarations */
+static DIR *opendir(const char *dirname);
+static struct dirent *readdir(DIR *dirp);
+static int closedir(DIR *dirp);
+static void rewinddir(DIR* dirp);
+
+
+/* Use the new safe string functions introduced in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+# define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
+#else
+# define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size))
+#endif
+
+/* Set errno variable */
+#if defined(_MSC_VER)
+#define DIRENT_SET_ERRNO(x) _set_errno (x)
+#else
+#define DIRENT_SET_ERRNO(x) (errno = (x))
+#endif
+
+
+
+/*****************************************************************************
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+static DIR *opendir(const char *dirname)
+{
+   DIR *dirp;
+
+   /* ensure that the resulting search pattern will be a valid file name */
+   if (dirname == NULL) {
+      DIRENT_SET_ERRNO (ENOENT);
+      return NULL;
+   }
+   if (strlen (dirname) + 3 >= MAX_PATH) {
+      DIRENT_SET_ERRNO (ENAMETOOLONG);
+      return NULL;
+   }
+
+   /* construct new DIR structure */
+   dirp = (DIR*) malloc (sizeof (struct DIR));
+   if (dirp != NULL) {
+      int error;
+
+      /*
+       * Convert relative directory name to an absolute one.  This
+       * allows rewinddir() to function correctly when the current working
+       * directory is changed between opendir() and rewinddir().
+       */
+      if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) {
+         char *p;
+
+         /* append the search pattern "\\*\0" to the directory name */
+         p = strchr (dirp->patt, '\0');
+         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
+           *p++ = '\\';
+         }
+         *p++ = '*';
+         *p = '\0';
+
+         /* open directory stream and retrieve the first entry */
+         dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
+         if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+            /* a directory entry is now waiting in memory */
+            dirp->cached = 1;
+            error = 0;
+         } else {
+            /* search pattern is not a directory name? */
+            DIRENT_SET_ERRNO (ENOENT);
+            error = 1;
+         }
+      } else {
+         /* buffer too small */
+         DIRENT_SET_ERRNO (ENOMEM);
+         error = 1;
+      }
+
+      if (error) {
+         free (dirp);
+         dirp = NULL;
+      }
+   }
+
+   return dirp;
+}
+
+
+/*****************************************************************************
+ * Read a directory entry, and return a pointer to a dirent structure
+ * containing the name of the entry in d_name field.  Individual directory
+ * entries returned by this very function include regular files,
+ * sub-directories, pseudo-directories "." and "..", but also volume labels,
+ * hidden files and system files may be returned.
+ */
+static struct dirent *readdir(DIR *dirp)
+{
+   DWORD attr;
+   if (dirp == NULL) {
+      /* directory stream did not open */
+      DIRENT_SET_ERRNO (EBADF);
+      return NULL;
+   }
+
+   /* get next directory entry */
+   if (dirp->cached != 0) {
+      /* a valid directory entry already in memory */
+      dirp->cached = 0;
+   } else {
+      /* get the next directory entry from stream */
+      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
+         return NULL;
+      }
+      if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) {
+         /* the very last entry has been processed or an error occured */
+         FindClose (dirp->search_handle);
+         dirp->search_handle = INVALID_HANDLE_VALUE;
+         return NULL;
+      }
+   }
+
+   /* copy as a multibyte character string */
+   DIRENT_STRNCPY ( dirp->curentry.d_name,
+             dirp->find_data.cFileName,
+             sizeof(dirp->curentry.d_name) );
+   dirp->curentry.d_name[MAX_PATH] = '\0';
+
+   /* compute the length of name */
+   dirp->curentry.d_namlen = strlen (dirp->curentry.d_name);
+
+   /* determine file type */
+   attr = dirp->find_data.dwFileAttributes;
+   if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+      dirp->curentry.d_type = DT_CHR;
+   } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+      dirp->curentry.d_type = DT_DIR;
+   } else {
+      dirp->curentry.d_type = DT_REG;
+   }
+   return &dirp->curentry;
+}
+
+
+/*****************************************************************************
+ * Close directory stream opened by opendir() function.  Close of the
+ * directory stream invalidates the DIR structure as well as any previously
+ * read directory entry.
+ */
+static int closedir(DIR *dirp)
+{
+   if (dirp == NULL) {
+      /* invalid directory stream */
+      DIRENT_SET_ERRNO (EBADF);
+      return -1;
+   }
+
+   /* release search handle */
+   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+      FindClose (dirp->search_handle);
+      dirp->search_handle = INVALID_HANDLE_VALUE;
+   }
+
+   /* release directory structure */
+   free (dirp);
+   return 0;
+}
+
+
+/*****************************************************************************
+ * Resets the position of the directory stream to which dirp refers to the
+ * beginning of the directory.  It also causes the directory stream to refer
+ * to the current state of the corresponding directory, as a call to opendir()
+ * would have done.  If dirp does not refer to a directory stream, the effect
+ * is undefined.
+ */
+static void rewinddir(DIR* dirp)
+{
+   if (dirp != NULL) {
+      /* release search handle */
+      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+         FindClose (dirp->search_handle);
+      }
+
+      /* open new search handle and retrieve the first entry */
+      dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
+      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
+         /* a directory entry is now waiting in memory */
+         dirp->cached = 1;
+      } else {
+         /* failed to re-open directory: no directory entry in memory */
+         dirp->cached = 0;
+      }
+   }
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/include/unistd.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/include/unistd.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/include/unistd.h	(revision 672)
@@ -0,0 +1,41 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2013 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef __STRICT_AINSI__
+
+#include <io.h>
+#include <process.h>
+#define mode_t int
+#define strtok_r strtok_s
+#define S_IRWXU _S_IREAD|_S_IWRITE
+#define S_IRGRP _S_IREAD|_S_IWRITE
+#define S_IROTH _S_IREAD|_S_IWRITE
+#define S_IXGRP _S_IREAD|_S_IWRITE
+#define S_IXOTH _S_IREAD|_S_IWRITE
+#define S_IWOTH _S_IREAD|_S_IWRITE
+#define S_IRUSR _S_IREAD
+#define S_IXGRP _S_IREAD|_S_IWRITE
+#define S_IWGRP _S_IREAD|_S_IWRITE
+#define S_IWUSR _S_IREAD|_S_IWRITE
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/CMakeLists.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/CMakeLists.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/CMakeLists.txt	(revision 672)
@@ -0,0 +1,14 @@
+PROJECT(otb2zcfg)  
+ 
+cmake_minimum_required(VERSION 2.6)  
+ 
+FIND_PACKAGE(OTB)  
+IF(OTB_FOUND)  
+  INCLUDE(${OTB_USE_FILE})  
+ELSE(OTB_FOUND)  
+  MESSAGE(FATAL_ERROR  
+      "Cannot build OTB project without OTB.  Please set OTB_DIR.")  
+ENDIF(OTB_FOUND)  
+ 
+ADD_EXECUTABLE(otb2zcfg otb2zcfg.cxx )  
+TARGET_LINK_LIBRARIES(otb2zcfg OTBCommon OTBApplicationEngine OTBIO ${ITK_LIBRARIES}) 
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/README.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/README.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/README.txt	(revision 672)
@@ -0,0 +1,17 @@
+To build the otb2zcfg utility you should run the following command:
+
+ mkdir build
+ cd build
+ ccmake ..
+ make
+
+ 
+To generate the zcfgs for the OTB Applications available, you should run the following:
+
+ mkdir zcfgs
+ cd zcfgs
+ export ITK_AUTOLOAD_PATH=/your/path/to/otb/applications
+ ../build/otb2zcfg
+ cp *zcfg /location/to/your/cgi-bin
+
+This ITK_AUTOLOAD_PATH environment variable will be required in the [env] section of your main.cfg.
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/otb2zcfg.cxx
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/otb2zcfg.cxx	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/otb2zcfg/otb2zcfg.cxx	(revision 672)
@@ -0,0 +1,395 @@
+#include "otbWrapperApplicationRegistry.h"
+#include "otbWrapperApplication.h"
+#include "otbImage.h" 
+#include <iostream> 
+
+using namespace otb::Wrapper;
+
+std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
+    size_t start_pos = 0;
+    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
+        str.replace(start_pos, from.length(), to);
+        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+    }
+    return str;
+}
+
+void printDefaultOutput(){
+  std::cout << "  [Result]" << std::endl;
+  std::cout << "   Title = the result message" << std::endl;
+  std::cout << "   Abstract = the result message" << std::endl;
+  std::cout << "   <LiteralData>" << std::endl;
+  std::cout << "    dataType = string" << std::endl;
+  std::cout << "    <Default />" << std::endl;
+  std::cout << "   </LiteralData>" << std::endl;
+}
+
+void printAscii(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = text/plain" << std::endl;
+  std::cout << "     encoding = ascii" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+}
+
+void printXml(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = text/xml" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+}
+
+void printGeoid(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = application/octet-stream" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+}
+
+void printCSV(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = text/csv" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+}
+
+void printUnknown(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = text/xml" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = text/plain" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+}
+
+void printImages(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = image/tiff" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+#if defined(OTB_USE_JPEG2000)
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = image/jp2" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+#endif
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = image/jpeg" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = image/png" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+}
+
+void printKmz(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = application/vnd.google-earth.kmz" << std::endl;
+  std::cout << "     extension = kmz" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+}
+
+void printVector(){
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     mimeType = text/xml" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = application/vnd.google-earth.kml+xml" << std::endl;
+  std::cout << "     encoding = utf-8" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+  std::cout << "    <Supported>" << std::endl;
+  std::cout << "     mimeType = application/zip" << std::endl;
+  std::cout << "    </Supported>" << std::endl;
+}
+
+void printOutputImage(){
+  std::cout << "   <LiteralData>" << std::endl;
+  std::cout << "    dataType = string" << std::endl;
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     value = float" << std::endl;
+  std::cout << "     AllowedValues = uint8,uint16,int16n,int32,int32,float,double" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+  std::cout << "   </LiteralData>" << std::endl;
+}
+
+void printOutputComplexImage(){
+  std::cout << "   <LiteralData>" << std::endl;
+  std::cout << "    dataType = string" << std::endl;
+  std::cout << "    <Default>" << std::endl;
+  std::cout << "     value = cfloat" << std::endl;
+  std::cout << "     AllowedValues = cfloat,cdouble" << std::endl;
+  std::cout << "    </Default>" << std::endl;
+  std::cout << "   </LiteralData>" << std::endl;
+}
+
+int main(int itkNotUsed(argc), char * itkNotUsed(argv)[]) 
+{ 
+  typedef otb::Image<unsigned short, 2> ImageType; 
+ 
+  ImageType::Pointer image = ImageType::New(); 
+ 
+  const char * ITK_AUTOLOAD_PATH = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");
+  std::cerr << "ERROR: Module search path: " << (ITK_AUTOLOAD_PATH ? ITK_AUTOLOAD_PATH : "none (check ITK_AUTOLOAD_PATH)") << std::endl;
+
+  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
+  if (list.size() == 0)
+    std::cerr << "ERROR: Available modules : none." << std::endl;
+  else{
+    std::cerr << "ERROR: Available modules :" << std::endl;
+    for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it){
+      std::string filename= *it + ".zcfg";
+      std::ofstream out(filename.c_str(),std::ofstream::out);
+      std::streambuf *coutbuf = std::cout.rdbuf();
+      std::cout.rdbuf(out.rdbuf());
+
+      std::cerr << *it << std::endl;
+      std::cout << "[" << *it << "]" << std::endl;
+      Application::Pointer m_Application=ApplicationRegistry::CreateApplication(*it);
+      std::string s0 = m_Application->GetDescription();
+      s0=ReplaceAll(ReplaceAll(s0,std::string("\n"),std::string("")),std::string("\t"),std::string(""));
+      std::cout << " Title = " << s0 << std::endl;
+      s0 = m_Application->GetDocLongDescription();
+      s0=ReplaceAll(ReplaceAll(s0,std::string("\n"),std::string("")),std::string("\t"),std::string(""));
+      std::cout << " Abstract = " << s0 << std::endl;
+      const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
+      std::cout << " storeSupported = true"<< std::endl;
+      std::cout << " statusSupported = true" << std::endl;
+      std::cout << " serviceProvider = " << *it << std::endl;
+      std::cout << " serviceType = OTB" << std::endl;
+      std::cout << " <DataInputs>" << std::endl;
+      for (unsigned int i = 0; i < appKeyList.size(); i++){
+	const std::string paramKey(appKeyList[i]);
+	Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
+	ParameterType type = m_Application->GetParameterType(paramKey);
+	Role role = m_Application->GetParameterRole(paramKey);
+      
+	if(paramKey!="inxml" && paramKey!="outxml" && role==0 && type!=17 
+	   && type!=ParameterType_OutputFilename && type!=ParameterType_OutputVectorData){
+	  std::vector<std::string> values;
+	  std::string s = m_Application->GetParameterDescription(paramKey);
+	  s=ReplaceAll(ReplaceAll(ReplaceAll(s,std::string("\n"),std::string("")),std::string("\t"),std::string("")),std::string("<"),std::string("&lt;"));
+	  std::cout << "  [" << paramKey << "]" << std::endl;
+	  if(s.length()>0){
+	    std::cout << "   Title = " << s << std::endl;
+	    std::cout << "   Abstract = " << s << std::endl;
+	  }else{
+	    std::cout << "   Title = " << paramKey << std::endl;
+	    std::cout << "   Abstract = " << paramKey << std::endl;
+	  }
+	  std::cout << "   minOccurs = " << m_Application->IsMandatory(paramKey) << std::endl;
+	  /* Bounded and unbounded parameters */
+	  if(type == ParameterType_StringList || type == ParameterType_InputImageList
+	     || type == ParameterType_InputVectorDataList || type == ParameterType_InputFilenameList)
+	    std::cout << "   maxOccurs = 1024" << std::endl;
+	  else
+	    std::cout << "   maxOccurs = 1" << std::endl;
+	  std::replace( s.begin(), s.end(), '\n', ' ');
+	  
+	  if(type == ParameterType_StringList || type == ParameterType_String || type == ParameterType_Float
+	     || type == ParameterType_Int || type == ParameterType_Choice || type == ParameterType_ListView
+	     || type == ParameterType_RAM || type == ParameterType_Empty || type == ParameterType_Directory){
+	    std::cout << "   <LiteralData>" << std::endl;
+	    std::string lt;
+	    if(type == ParameterType_Int || type == ParameterType_RAM)
+	      lt="integer";
+	    if(type == ParameterType_Float)
+	      lt="float";
+	    if(type == ParameterType_String || type == ParameterType_StringList
+	       || type == ParameterType_Choice || type == ParameterType_Directory
+	       || type == ParameterType_ListView)
+	      lt="string";
+	    if(type == ParameterType_Empty)
+	      lt="boolean";
+	    std::cout << "    dataType = " << lt << std::endl;
+	    if(type == ParameterType_Choice || type == ParameterType_ListView){
+	      const std::vector<std::string> nList = m_Application->GetChoiceNames(paramKey);
+	      const std::vector<std::string> keysList = m_Application->GetChoiceKeys(paramKey);
+	      if(keysList.size()==0){
+		std::cout << "    <Default />" << std::endl;
+	      }
+	      for (unsigned int j = 0; j < keysList.size(); j++){
+		const std::string key(keysList[j]);
+		if(j==0){
+		  std::cout << "    <Default>" << std::endl;
+		  if(m_Application->HasValue(paramKey))
+		    std::cout << "    value = " << m_Application->GetParameterAsString(paramKey) << std::endl;
+		  else
+		    std::cout << "    value = " << key << std::endl;
+		}
+		else{
+		  if(j==1){
+		    std::cout << "    AllowedValues = "+keysList[0]+",";
+		  }
+		  std::cout << keysList[j];
+		  if(j+1>=keysList.size()){
+		    std::cout << std::endl;
+		    std::cout << "    </Default>" << std::endl;
+		  }
+		  else
+		    std::cout << ",";
+		}
+	      }
+	    }
+	    else{
+	      if(type!=17 && m_Application->HasValue(paramKey)){
+		std::cout << "    <Default>" << std::endl;
+		std::cout << "     value = " << m_Application->GetParameterAsString(paramKey) << std::endl;
+		std::cout << "    </Default>" << std::endl;
+	      }
+	      else
+		std::cout << "    <Default />" << std::endl;
+	    }
+	    std::cout << "   </LiteralData>" << std::endl;
+	  }
+	  else{
+	    if(type == ParameterType_OutputImage)
+	      printOutputImage();
+	    else{
+	      if(type == ParameterType_ComplexOutputImage){
+		printOutputComplexImage();
+	      }else{
+		std::cout << "   <ComplexData>" << std::endl;
+		if(type == ParameterType_InputImage || type == ParameterType_InputImageList || type == ParameterType_ComplexInputImage){
+		  printImages();
+		}
+		else
+		  if(type == ParameterType_InputVectorData || type == ParameterType_InputVectorDataList){
+		    printVector();
+		  }
+		  else
+		    if(type == ParameterType_InputFilename || type == ParameterType_OutputFilename){
+		      
+		      std::string geoid("geoid");
+		      if(paramKey.find(geoid)!= std::string::npos)
+			printGeoid();
+		      else{
+			std::string dtype("vector");
+			std::string descr(m_Application->GetParameterDescription(paramKey));
+			if(descr.find(dtype)!= std::string::npos)
+			  printVector();
+			else{
+			  std::string dtype1("ASCII");
+			  if(descr.find(dtype1)!= std::string::npos)
+			    printAscii();
+			  else{
+			    std::string dtype2("XML");
+			    std::string dtype3("xml");
+			    if(descr.find(dtype2)!= std::string::npos || descr.find(dtype3)!= std::string::npos)
+			      printXml();
+			    else
+			      printImages();
+			  }
+			}
+		      }
+		    }
+		std::cout << "   </ComplexData>" << std::endl;
+	      }
+	    }
+	  }
+
+
+	}
+      }
+      std::cout << " <DataInputs>" << std::endl;
+      std::cout << " <DataOutputs>" << std::endl;
+      int hasOutput=-1;
+      for (unsigned int i = 0; i < appKeyList.size(); i++){
+	const std::string paramKey(appKeyList[i]);
+	std::vector<std::string> values;
+	Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
+	ParameterType type = m_Application->GetParameterType(paramKey);
+	Role role = m_Application->GetParameterRole(paramKey);
+	
+	if(paramKey!="inxml" && paramKey!="outxml" &&
+	   ((type == ParameterType_OutputVectorData || type == ParameterType_OutputImage
+	     || type == ParameterType_OutputImage || type == ParameterType_ComplexOutputImage
+	     || type == ParameterType_OutputFilename) || role==1) && type != ParameterType_Group){
+	  hasOutput=1;
+	  std::vector<std::string> values;
+	  Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
+	  ParameterType type = m_Application->GetParameterType(paramKey);
+	  Role role = m_Application->GetParameterRole(paramKey);
+	  std::cout << "  [" << paramKey << "]" << std::endl;
+	  std::string s=m_Application->GetParameterDescription(paramKey);
+	  if(s.length()>0){
+	    std::cout << "   Title = " << s << std::endl;
+	    std::cout << "   Abstract = " << s << std::endl;
+	  }else{
+	    std::cout << "   Title = " << paramKey << std::endl;
+	    std::cout << "   Abstract = " << paramKey << std::endl;
+	  }
+
+	  if(type == ParameterType_OutputImage || type == ParameterType_ComplexOutputImage){
+	    std::cout << "   <ComplexData>" << std::endl;
+	    printImages();
+	    std::cout << "   </ComplexData>" << std::endl;
+	  }
+	  else
+	    if(type == ParameterType_OutputVectorData || type == ParameterType_OutputImage){
+	      std::cout << "   <ComplexData>" << std::endl;
+	      if(type == ParameterType_OutputImage)
+		printImages();
+	      else
+		printVector();
+	      std::cout << "   </ComplexData>" << std::endl;
+	    }
+	    else
+	      if(type == ParameterType_String || type == ParameterType_StringList
+		 || type == ParameterType_Float || type == ParameterType_Int){
+		std::cout << "   <LiteralData>" << std::endl;
+		std::string lt;
+		if(type == ParameterType_Int)
+		  lt="integer";
+		if(type == ParameterType_Float)
+		  lt="float";
+		if(type == ParameterType_String || type == ParameterType_StringList)
+		  lt="string";
+		std::cout << "    dataType = " << lt << std::endl;
+		std::cout << "    <Default />" << std::endl;
+		std::cout << "   </LiteralData>" << std::endl;
+	      }
+	      else
+		if(type == ParameterType_OutputFilename){
+		  std::cout << "   <ComplexData>" << std::endl;
+		  std::string descr(m_Application->GetParameterDescription(paramKey));
+		  std::string dtype("csv");
+		  std::string dtype1("CSV");
+		  if(descr.find(dtype)!= std::string::npos || descr.find(dtype1)!= std::string::npos)
+		    printCSV();
+		  else{
+		    std::string dtype2("text file");
+		    if(descr.find(dtype2)!= std::string::npos)
+		      printAscii();
+		    else{
+		      std::string dtype2("XML");
+		      std::string dtype3("xml");
+		      if(descr.find(dtype2)!= std::string::npos || descr.find(dtype3)!= std::string::npos)
+			printXml();
+		      else{
+			std::string dtype4("vector");
+			std::string dtype5("Vector");
+			if(descr.find(dtype4)!= std::string::npos || descr.find(dtype5)!= std::string::npos)
+			  printVector();
+		       	else{
+			  std::string dtype6("kmz");
+			  std::string dtype7("Kmz");
+			  if(descr.find(dtype6)!= std::string::npos || descr.find(dtype6)!= std::string::npos)
+			    printKmz();
+			  else
+			    printUnknown();
+			}
+		      }
+		    }
+		  }
+		  std::cout << "   </ComplexData>" << std::endl;
+		}
+	}
+      }
+      if(hasOutput<0)
+	printDefaultOutput();
+      std::cout << " </DataOutputs>" << std::endl;
+      std::cout.rdbuf(coutbuf);
+    }
+  }
+ 
+  return EXIT_SUCCESS; 
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/Makefile	(revision 672)
@@ -0,0 +1,14 @@
+ZRPATH=../../zoo-project
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+WXCXX=`wx-config --cxx`
+WXCFLAGS=`wx-config --cxxflags`
+WXLIBS=`wx-config --libs`
+
+saga2zcfg: saga2zcfg.c
+	${WXCXX} ${SAGA_CFLAGS} ${WXCFLAGS} ${CFLAGS} -fpic -o saga2zcfg ./saga2zcfg.c ${GDAL_LIBS} ${MACOS_LD_FLAGS}  ${WXLIBS} ${SAGA_LDFLAGS}
+
+clean:
+	rm -f saga2zcfg
Index: /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/saga2zcfg.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/saga2zcfg.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/thirds/saga2zcfg/saga2zcfg.c	(revision 672)
@@ -0,0 +1,393 @@
+#include <locale.h>
+
+#include <wx/app.h>
+#include <wx/utils.h>
+
+#include <api_core.h>
+#include <module_library.h>
+
+int Callback(TSG_UI_Callback_ID ID, CSG_UI_Parameter &Param_1, CSG_UI_Parameter &Param_2){
+  return( 1 );
+}
+
+TSG_PFNC_UI_Callback Get_Callback(void){
+  return( &Callback );
+}
+
+void cleanAbstract(CSG_String abstract,char**res){
+  char* tmp=strdup(abstract.b_str());
+  CSG_String val=CSG_String("")+tmp;
+  if(val.Contains("\r")){
+    val.Replace("\r","<br/>");
+  }
+  if(val.Contains("\n")){
+    val.Replace("\n","<br/>");
+  }
+  if(val.Contains("<")){
+    val.Replace("<","&lt;");
+  }
+  if(val.Contains(">")){
+    val.Replace(">","&gt;");
+  }
+  free(tmp);
+  if(val.is_Empty())
+    *res=NULL;
+  else
+    *res=strdup(val.b_str());
+}
+
+void printBasicMetadata(FILE* stdout,CSG_Parameter* param,bool out=false,bool range=false,bool min=true,bool tin=false,char* tname=NULL,char* ttitle=NULL){
+  fprintf(stdout," [%s]\n",(CSG_String(param->Get_Identifier())+(range?(min?"_MIN":"_MAX"):(tin?CSG_String("_")+tname:""))).b_str());
+  fprintf(stdout,"  Title = %s\n",(CSG_String(param->Get_Name())+(range?(min?" (min value)":" (max value)"):(tin&&ttitle!=NULL?ttitle:""))).b_str());
+  if(CSG_String(param->Get_Description()).is_Empty())
+    fprintf(stdout,"  Abstract = %s\n",CSG_String(param->Get_Name()).b_str());
+  else{
+    char* tmp=strdup(CSG_String(param->Get_Description()).b_str());
+    CSG_String val=CSG_String("")+tmp;
+    if(val.Contains("\r")){
+      val.Replace("\r","<br/>");
+    }
+    if(val.Contains("\n")){
+      val.Replace("\n","<br/>");
+    }
+    if(val.Contains("<")){
+      val.Replace("<","&lt;");
+    }
+    if(val.Contains(">")){
+      val.Replace(">","&gt;");
+    }
+    free(tmp);
+    fprintf(stdout,"  Abstract = %s\n",val.b_str());
+  }
+  if(!out){
+    if(param->is_Option() || param->is_Optional()){
+      fprintf(stdout,"  minOccurs = 0\n");
+      if(param->is_Option())
+	fprintf(stdout,"  maxOccurs = 1\n");
+      else{
+	if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("_list")))
+	  fprintf(stdout,"  maxOccurs = 1024\n");
+	else
+	  fprintf(stdout,"  maxOccurs = 1\n");
+      }
+    }else{
+      if(param->is_Input())
+	fprintf(stdout,"  minOccurs = 1\n");
+      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("_list")))
+	fprintf(stdout,"  maxOccurs = 1024\n");
+      else
+	fprintf(stdout,"  maxOccurs = 1\n");
+    }
+  }
+  if(range){
+    
+  }
+}
+
+void printGrids(FILE* stdout){
+  fprintf(stdout,"  <ComplexData>\n");
+  fprintf(stdout,"   <Default>\n");
+  fprintf(stdout,"    mimeType = image/tiff\n");
+  fprintf(stdout,"   </Default>\n");
+  fprintf(stdout,"   <Supported>\n");
+  fprintf(stdout,"    mimeType = application/x-ogc-envi\n");
+  fprintf(stdout,"   </Supported>\n");
+  fprintf(stdout,"   <Supported>\n");
+  fprintf(stdout,"    mimeType = application/x-ogc-aaigrid\n");
+  fprintf(stdout,"   </Supported>\n");
+  fprintf(stdout,"  </ComplexData>\n");
+}
+
+void printShapes(FILE* stdout){
+  fprintf(stdout,"  <ComplexData>\n");
+  fprintf(stdout,"   <Default>\n");
+  fprintf(stdout,"    mimeType = text/xml\n");
+  fprintf(stdout,"    encoding = utf-8\n");
+  fprintf(stdout,"   </Default>\n");
+  fprintf(stdout,"   <Supported>\n");
+  fprintf(stdout,"    mimeType = application/vnd.google-earth.kml+xml\n");
+  fprintf(stdout,"   </Supported>\n");
+  fprintf(stdout,"   <Supported>\n");
+  fprintf(stdout,"    mimeType = application/json\n");
+  fprintf(stdout,"   </Supported>\n");
+  fprintf(stdout,"  </ComplexData>\n");
+}
+
+void printTables(FILE* stdout){
+  fprintf(stdout,"  <ComplexData>\n");
+  fprintf(stdout,"   <Default>\n");
+  fprintf(stdout,"    mimeType = text/csv\n");
+  fprintf(stdout,"    encoding = utf-8\n");
+  fprintf(stdout,"   </Default>\n");
+  fprintf(stdout,"   <Supported>\n");
+  fprintf(stdout,"    mimeType = text/csv\n");
+  fprintf(stdout,"    encoding = base64\n");
+  fprintf(stdout,"   </Supported>\n");
+  fprintf(stdout,"  </ComplexData>\n");
+}
+
+void printPoints(FILE* stdout){
+  fprintf(stdout,"  <ComplexData>\n");
+  fprintf(stdout,"   <Default>\n");
+  fprintf(stdout,"    mimeType = application/x-ogc-lasf\n");
+  fprintf(stdout,"    extension = las\n");
+  fprintf(stdout,"   </Default>\n");
+  fprintf(stdout,"  </ComplexData>\n");
+}
+
+int main(int argc, char *argv[]) {
+  if( !wxInitialize() ){
+    fprintf(stderr,"initialisation failed");
+    return -1;
+  }
+  setlocale(LC_NUMERIC, "C");
+  static bool g_bShow_Messages = false;
+  SG_Set_UI_Callback(Get_Callback());
+  int n = SG_Get_Module_Library_Manager().Add_Directory(wxT(MODULE_LIBRARY_PATH),false);
+  if( SG_Get_Module_Library_Manager().Get_Count() <= 0 ){
+    fprintf(stderr,"could not load any tool library");
+    return -2;
+  }
+
+  for(int i=0;i<SG_Get_Module_Library_Manager().Get_Count();i++){
+    
+    CSG_Module_Library * library=SG_Get_Module_Library_Manager().Get_Library(i);
+    int lc=library->Get_Count();
+    if(!library->Get_Library_Name().Contains("io_")) {
+
+      for(int j=0;j<lc;j++){
+	CSG_Module * module=library->Get_Module(j);
+	if(module!=NULL && !module->needs_GUI() /*&& !module->is_Interactive()*/ ){
+
+	  mkdir(library->Get_Library_Name().b_str(),0755);
+
+	  FILE *stdout1=fopen((library->Get_Library_Name()+"/"+module->Get_ID()+".zcfg").b_str(),"w+");
+	  fprintf(stdout1,"[%d]\n",j);
+	  fprintf(stdout1," Title = %s\n",module->Get_Name().b_str());
+	  if(CSG_String(module->Get_Description()).is_Empty() ||
+	     module->Get_Description().Length()<module->Get_Name().Length() )
+	    fprintf(stdout1," Abstract = %s\n",module->Get_Name().b_str());
+	  else{
+	    char *val0;
+	    cleanAbstract(module->Get_Description(),&val0);
+	    if(val0==NULL)
+	      fprintf(stdout1," Abstract = %s\n",module->Get_Name().b_str());
+	    else{
+	      fprintf(stdout1," Abstract = %s\n",val0);
+	      free(val0);
+	    }
+	  }
+	  fprintf(stdout1," storeSupported = true\n");
+	  fprintf(stdout1," statusSupported = true\n");
+	  fprintf(stdout1," serviceType = SAGA\n");
+	  fprintf(stdout1," serviceProvider = %s\n",library->Get_Library_Name().b_str());
+	  CSG_Parameters * params=module->Get_Parameters();
+	  int pc=params->Get_Count();
+
+	  fprintf(stdout1," <DataInputs>\n");
+	  for(int k=0;k<pc;k++){
+	    CSG_Parameter * param=params->Get_Parameter(k);
+	  
+	    // Node should be used for defining Complex ComplexData
+	    if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("color"))){
+	      
+	    }
+	    else if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("range"),true)){
+
+	      param->Restore_Default();
+
+	      printBasicMetadata(stdout1,param,false,true,true);
+	      fprintf(stdout1,"  <LiteralData>\n");
+	      fprintf(stdout1,"   dataType = float\n");
+	      CSG_Parameter_Range *range=param->asRange();
+	      fprintf(stdout1,"   <Default>\n");
+	      fprintf(stdout1,"    value = %f\n",((CSG_Parameter_Range*)param->Get_Data())->Get_LoVal());
+	      fprintf(stdout1,"   </Default>\n");
+	      fprintf(stdout1,"  </LiteralData>\n");
+
+	      printBasicMetadata(stdout1,param,false,true,false);
+	      fprintf(stdout1,"  <LiteralData>\n");
+	      fprintf(stdout1,"   dataType = float\n");
+	      fprintf(stdout1,"   <Default>\n");
+	      fprintf(stdout1,"    value = %f\n",((CSG_Parameter_Range*)param->Get_Data())->Get_HiVal());
+	      fprintf(stdout1,"   </Default>\n");
+	      fprintf(stdout1,"  </LiteralData>\n");
+
+	    }
+	    else if(param!=NULL && !param->is_Output() 
+		    && 
+		    !CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("parameters"),true)
+		    && 
+		    !CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("grid_system"),true)
+		    && 
+		    !CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("node"),true)){
+	    
+	      printBasicMetadata(stdout1,param);
+
+	      if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("file"),true)){
+		if(CSG_String(param->Get_Description()).Contains(CSG_String("HTML"))){
+		  fprintf(stdout1,"  <ComplexData>\n");	       
+		  fprintf(stdout1,"   <Default>\n");
+		  fprintf(stdout1,"    mimeType = text/html\n");
+		  fprintf(stdout1,"    encoding = utf-8\n");
+		  fprintf(stdout1,"   </Default>\n");
+		  fprintf(stdout1,"  <ComplexData>\n");
+		}
+		else{
+		  fprintf(stdout1,"  <ComplexData>\n");	       
+		  fprintf(stdout1,"   <Default>\n");
+		  if(CSG_String(param->Get_Description()).Contains(CSG_String("HTML"))){
+		    fprintf(stdout1,"    mimeType = text/html\n");
+		  }else
+		    if(CSG_String(param->Get_Description()).Contains(CSG_String("SVG"))){
+		      fprintf(stdout1,"    mimeType = image/svg+xml\n");
+		    }else
+		      fprintf(stdout1,"    mimeType = text/plain\n");
+		  if(CSG_String(param->Get_Description()).Contains(CSG_String("ASCII"))){
+		    fprintf(stdout1,"    encoding = ascii\n");
+		  }else
+		    fprintf(stdout1,"    encoding = utf-8\n");
+		  fprintf(stdout1,"   </Default>\n");
+		  fprintf(stdout1,"  </ComplexData>\n");
+		}
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes")) ||
+		 CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin")) ){
+		printShapes(stdout1);
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).Contains("points")){
+		printPoints(stdout1);
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).Contains("grid") ||
+		 CSG_String(param->Get_Type_Identifier()).Contains("data_")){
+		printGrids(stdout1);
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
+		printTables(stdout1);
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("text"))){
+		fprintf(stdout1,"  <LiteralData>\n");
+		fprintf(stdout1,"   dataType = string\n");
+		fprintf(stdout1,"   <Default>\n");
+		if( !param->Get_Data()->Get_Default().is_Empty() ){
+		  fprintf(stdout1,"    value = %s\n",param->Get_Data()->Get_Default().b_str());
+		}
+		fprintf(stdout1,"   </Default>\n");
+		fprintf(stdout1,"  </LiteralData>\n");
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("double"),true)
+		 || 
+		 CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("degree"),true)
+		 || 
+		 CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("integer"),true)){
+		fprintf(stdout1,"  <LiteralData>\n");
+		if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("double"),true) || 
+		 CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("degree"),true))
+		  fprintf(stdout1,"   dataType = float\n");
+		else
+		  fprintf(stdout1,"   dataType = integer\n");
+
+		fprintf(stdout1,"   <Default>\n");
+		if( !param->Get_Data()->Get_Default().is_Empty() ){
+		  fprintf(stdout1,"    value = %s\n",param->Get_Data()->Get_Default().b_str());
+		}
+		if(param->asValue()->has_Minimum() && param->asValue()->has_Maximum()){
+		  fprintf(stdout1,"    rangeMin = %f\n",param->asValue()->Get_Minimum());
+		  fprintf(stdout1,"    rangeMax = %f\n",param->asValue()->Get_Maximum());
+		  fprintf(stdout1,"    rangeClosure = c\n");
+		}
+		fprintf(stdout1,"   </Default>\n");
+		fprintf(stdout1,"  </LiteralData>\n");
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("boolean"),true)){
+		fprintf(stdout1,"  <LiteralData>\n");
+		fprintf(stdout1,"   dataType = bool\n");
+		fprintf(stdout1,"   <Default>\n");
+		if( !param->Get_Data()->Get_Default().is_Empty() ){
+		  fprintf(stdout1,"    value = %s\n",(param->Get_Data()->Get_Default().Contains("0")?"false":"true"));
+		}
+		fprintf(stdout1,"   </Default>\n");
+		fprintf(stdout1,"  </LiteralData>\n");	
+	      }
+	      if(CSG_String(param->Get_Type_Identifier()).is_Same_As(CSG_String("choice"),true)){
+		CSG_Parameter_Choice* choice=param->asChoice();
+		if(choice!=NULL){
+		  fprintf(stdout1,"  <LiteralData>\n");
+		  fprintf(stdout1,"   dataType = string\n");
+		  fprintf(stdout1,"   AllowedValues = ");
+		  int clen=choice->Get_Count();
+		  if(clen>0){
+		    for(int l=0;l<clen;l++){
+		      //fprintf(stdout1,"%d",l);
+		      fprintf(stdout1,"%s",(CSG_String(choice->Get_Item(l))).b_str());
+		      if(l+1<clen)
+			fprintf(stdout1,",");
+		    }
+		    fprintf(stdout1,"\n");
+		  }
+		  fprintf(stdout1,"   <Default>\n");
+		  if( !param->Get_Data()->Get_Default().is_Empty() ){
+		    fprintf(stdout1,"    value = %s\n",CSG_String(choice->Get_Item(atoi(param->Get_Data()->Get_Default()))).b_str());
+		  }
+		  fprintf(stdout1,"   </Default>\n");
+		  fprintf(stdout1,"  </LiteralData>\n");
+		}
+	      }
+	    }
+	  }
+	  fprintf(stdout1," </DataInputs>\n");
+	  fprintf(stdout1," <DataOutputs>\n");
+
+	  bool hasOutput=false;
+
+	  for(int k=0;k<pc;k++){
+	    CSG_Parameter * param=params->Get_Parameter(k);
+	    if(param!=NULL && param->is_Output()){
+	      hasOutput=true;
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
+		char* tinOut[5]={
+		  (char*)"POINTS",
+		  (char*)"CENTER",
+		  (char*)"EDGES",
+		  (char*)"TRIANGLES",
+		  (char*)"POLYGONS"
+		};
+		for(int l=0;l<5;l++){
+		  char *ttitle=(char*)malloc((strlen(tinOut[l])+8)*sizeof(char));
+		  sprintf(ttitle,"%s Shapes",tinOut[l]);
+		  printBasicMetadata(stdout1,param,true,false,true,true,tinOut[l],ttitle);
+		  printShapes(stdout1);
+		}
+	      }
+	      else {
+		printBasicMetadata(stdout1,param,true);
+
+		if(CSG_String(param->Get_Type_Identifier()).Contains("points")){
+		  printPoints(stdout1);
+		}
+		if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes"))){
+		  printShapes(stdout1);
+		}
+		if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid")) ||
+		   CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("data_object"))){
+		  printGrids(stdout1);
+		}
+		if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
+		  printTables(stdout1);
+		}
+
+	      }
+	    }
+	  }
+	  fprintf(stdout1,"</DataOutputs>\n");
+	  fclose(stdout1);
+	  if(!hasOutput)
+	    unlink((library->Get_Library_Name()+"/"+module->Get_ID()+".zcfg").b_str());
+	}
+      }
+    }
+  }
+  wxUninitialize();
+
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/COMMITTERS
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/COMMITTERS	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/COMMITTERS	(revision 672)
@@ -0,0 +1,30 @@
+===========================================================
+List of ZOO-Project committers
+===========================================================
+
+Folks who have agreed to ZOO-Project Commiter Guildlines terms:
+
+SVN Login(s)  Name/Contact
+============  ============
+david         David SAGGIORATO
+	      dsaggiorato at free.fr
+djay          Gérald FENOY
+	      gerald.fenoy at geolabs.fr
+jmckenna      Jeff MCKENNA
+	      jmckenna at gatewaygeomatics.com
+kalxas        Angelos TZOTSOS
+	      gcpp.kalxas at gmail.com
+lucadelu      Luca DELUCCHI
+	      lucadeluge at gmail.com
+nbozon	      Nicolas BOZON
+	      nicolas.bozon@gmail.com
+neteler       Markus NETELER
+	      neteler at osgeo.org
+nmarco        Marco NEGRETTI
+	      marco.negretti at polimi.it
+knut	      Knut LANDMARK
+	      Knut.Landmark@ffi.no
+reluc         René-Luc D'HONT
+	      rldhont at gmail.com
+tclarke       Trevor CLARKE
+	      tclarke at ball.com
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/HISTORY.txt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/HISTORY.txt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/HISTORY.txt	(revision 672)
@@ -0,0 +1,128 @@
+Version 1.5.0-dev
+  * Initial support for WPS 2.0.0 including the Dismiss extension
+  * Fix concurrency access to status informations
+  * Use simple file rather than shared memory for storing status informations
+  * Add support for db backend to store status informations
+  * Add the lib_zoo_service shared library to be linked against C services
+  * Add ZOO-API for the PHP language (with documentation)
+  * Add doxygen comments in source code
+  * Add support for multiple Exception nodes
+  * Add a length key when creating MapArray
+  * Add OTB support for applications as a service
+  * Add the otb2zcfg utility to produce zcfg for otb applications
+  * Add OTB Application Observer to have progress status updates
+  * Fix maxOccurs handling
+  * Fix gesture of downloaded inputs when multiple values are given
+  * Add detection of generated_file key in outputs to read the file
+  generated by a service
+  * Add a minimal parsing API 
+  * Run validateRequest (download, default settings and decoding)
+  after fork if any
+  * Add SAGA-GIS support for modules as a service
+  * Add saga2zcfg utility to generate zcfg for SAGA-GIS modules
+  * Add SAGA-GIS Observer to have ongoing status updates
+
+Version 1.4.0
+  * Small fix for mimeType of results for CGAL services
+
+Version 1.4.0-rc1
+  * Binary support for PHP language
+  * ZOO-API for the Java language
+  * ZOO-Client Javascript API
+  * FastCGI fixes
+  * JavaScript ZOO-API enhancements (COOKIE use and Output in
+  generated XML)
+  * Add debian files
+  * Inputs passed by reference downloaded in parallel
+  * Conform behavior for DescribeProcess when the Identifier was not
+  found
+  * Add support of maximumMegabytes keywords for ComplexData Inputs
+  * Add the optional YAML ZCFG support #4 and the zcfg2yaml converter
+  * Return error messages that enable the service provider to quickly
+  identify the root cause of errors due to configuration file syntax
+  (ticket #90)
+  * Fix logic in addMapToMap (ticket #91)
+  * Enable AllowedValue and multiple Range definitions using default
+  and supported blocks
+  * Add the lastest revision number in version.h (available in Python
+  ZOO-API)
+  * Add the optional Ruby Language Support to the ZOO-Kernel with an
+  API similar to the Python ZOO-API
+  * Small rewrite of Python support
+  * Inputs can be requested over https protocol (ticket #86)
+  * Add capability to define both percentage of execution and a
+  message (ticket #87). 
+  * Add usid in lenv section used to generate an unique identifier
+  based on time and the process identifier.
+  * Add gdal_contour service
+  * Add dynamic definition of serverAddress from the main section
+
+Version 1.3.0-rc2
+  * Fix POST Request issue (ticket #34)
+  * Fix COOKIE gesture (ticket #79)
+  * Remove verbose messages when using MapServer W*S (ticket #80)
+  * Add COMMITTERS  and LICENSE files
+
+Version 1.3.0-rc1
+
+  * Updating ZOO.Class object with the OpenLayers.Class Updating
+    ZOO.Class with the (ticket #64)
+  * Correct the content of proj4js (ticket #63)
+  * Enhance the COOKIE gesture (ticket #68)
+  * Support for dataInputs URLEncoded and xlink:href (ticket #62)
+  * Use the same object structure for JavaScript arguments than for
+    Python
+  * Add the Normalized Difference Vegetation Index service
+  * Add importScripts function to JavaScript support (ticket #66)
+  * Add multiple inputs values for the same identifier (ticket #72)
+  * Add Python ZOO-API to access ZOO-Kernel internel functions
+  * Add a [headers] section in main.cfg file to add specifics to
+    header returned
+  * Add support for multiple outputs for both GET and POST requests
+  * Add Content-Length to the headers if the result is sized
+  * Add Content-Disposition to the headers if the result contains a
+    filename
+  * Add support for sending headers through JS ZOO-api
+  * Add support for multi-valued inputs in JS ZOO-api
+  * Fixing issue about invalid status document #73
+  * Add Python-3.3.0 support
+  * Update documentation
+  * Add MapServer W*S Support documentation #34
+
+Version 1.2.0-rc3
+
+  * add basic SOAP Envelope support (ticket #49)
+  * support request when Content-Length header is not set by the
+  * client (ticket #57)
+  * fix issue when POST request is empty (ticket #45)
+  * add minimalist cache system (ticket #51)
+  * fix Python support (ticket #29)
+
+Verseion 1.2.0-rc2
+
+  * fix for process to run in background
+  * add support for ALL identifier for !DescribeProcess
+  * add a small test suite in the testing directory to test ogr base-vect-ops
+  * big fix for storage of Session maps on disk
+  * support for {{{<Default />}}} node in ZCFG files
+  * fastcgi version now support both !GetCapabilities and !DescribeProcess requests
+
+Version 1.2.0-rc1
+
+  * add WIN32 support
+  * add GRASS support through wps-grass-bridge
+  * add languages support using libintl 
+  * binary support for inputs and outputs for both JAVA and Python
+  * automatic loading of ZOO-API and proj4js files (if present in the ZOO-Kernel directory) when loading JS Service Provider 
+  * numerous memory leaks removed
+  * add PERL support
+  * enhance speed for JAVA support 
+  * enhance POST request support
+  * add !BoundingBoxData support
+  * Python support is now optional as other languages
+  * add lenv section before running the service to store informations runtime specific 
+  * add COOKIE support and {{{senv}}} section to store informations session specific
+  * add {{{USE_GDB}}} compilation flag to remove signal handling for debuging purpose
+  * enhance base64 support when included in and XML POST request
+  * return !ExceptionReport when no protocol was specified for xlink:href value
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/LICENSE
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/LICENSE	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/LICENSE	(revision 672)
@@ -0,0 +1,166 @@
+ZOO-Project Licensing
+---------------------
+
+This file attempts to include all licenses that apply within the ZOO-Project
+source tree, in particular any that are supposed to be exposed to the end user
+for credit requirements for instance.
+
+ZOO-Kernel License
+------------------
+
+Copyright (c) 2009-2015 GeoLabs SARL
+Copyright 2010-2011 Fondazione Edmund Mach. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the “Software”), to deal
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies of this Software or works derived from this Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+ZOO-Kernel OTB Support
+----------------------
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+Some parts of this code are derived from ITK. See ITKCopyright.txt
+for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
+
+See Ref: http://hg.orfeo-toolbox.org/OTB/ Copyright
+
+ZOO-API License
+---------------
+
+Copyright 2011-2013 GeoLabs SARL. All rights reserved.
+Copyright 2010 3liz SARL. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Copyright (c) 2006-2011 by OpenLayers Contributors (see 
+https://github.com/openlayers/openlayers/blob/master/authors.txt for full 
+list of contributors). Published under the Clear BSD license.
+See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+full text of the license.
+
+qrencode ZOO-Services License
+-----------------------------
+
+Copyright (C) 2006-2012 Kentaro Fukuchi <kentaro@fukuchi.org>
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Other ZOO-Services License
+--------------------------
+
+Copyright (c) 2009-2013, GeoLabs SARL
+Copyright (c) 2006, 2009 Matthew Perry 
+Copyright (c) 2009 Even Rouault
+Copyright (c) 2007, Andrey Kiselev <dron@ak4719.spb.edu>
+Copyright (c) 1998, 1999, 2002, Frank Warmerdam
+Copyright (c) 2002, i3 - information integration and imaging Fort Collin, CO
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+CGIC License
+------------
+
+CGIC, copyright 2009 GeoLabs SARL.
+CGIC, copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+2004 by Thomas Boutell and Boutell.Com, Inc.. Permission is granted to 
+use CGIC in any application, commercial or noncommercial, at no cost. 
+HOWEVER, this copyright paragraph must appear on a "credits" page 
+accessible in the public online and offline documentation of the program. 
+Modified versions of the CGIC library should not be distributed without 
+the attachment of a clear statement regarding the author of the 
+modifications, and this notice may in no case be removed. 
+Modifications may also be submitted to the author for inclusion 
+in the main CGIC distribution.                                 
+
+IF YOU WOULD PREFER NOT TO ATTACH THE ABOVE NOTICE to
+the public documentation of your application, consult the
+information which follows regarding the availability
+of a nonexclusive commercial license for CGIC.
+
+dirent-win32 License
+--------------------
+
+Copyright (C) 2006 Toni Ronkko
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/Makefile	(revision 672)
@@ -0,0 +1,35 @@
+include ../../zoo-kernel/ZOOMakefile.opts
+
+OS:=$(shell uname -s)
+ext=so
+ifeq ($(OS),Darwin)
+	ext=dylib
+endif
+
+JAVA_FILES=../../zoo-kernel/${JAVA_FILE}
+
+ifeq ($(JS_ENABLED),-DUSE_JS)
+	JS_FILES=../../zoo-kernel/${JS_FILE},
+endif
+ifeq ($(MS_FILE),service_internal_ms.o)
+	MS_FILES=../../zoo-kernel/${MS_FILE},
+endif
+
+
+
+all: libZOO.${ext}
+
+ZOO.class: ZOO.java
+	javac ZOO.java
+
+ZOO.h: ZOO.java ZOO.class
+	javah ZOO
+
+zoo-api.o: zoo-api.c ZOO.h
+	gcc -fPIC -c zoo-api.c ${JAVACFLAGS} ${XML2CFLAGS} -I../../zoo-kernel/ -I../../../thirds/cgic206/
+
+libZOO.${ext}: zoo-api.o
+	gcc zoo-api.o -shared -o libZOO.${ext} -Wl,../../zoo-kernel/service_internal.o,${JAVA_FILES},${MS_FILES}${JS_FILES}../../zoo-kernel/ulinet.o ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lcrypto ${MS_LDFLAGS} ${MACOS_LD_FLAGS} -lcurl -lfcgi ${MACOS_LD_NET_FLAGS}
+
+clean:
+	rm -f *${ext} *o *.h *class
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/ZOO.java
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/ZOO.java	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/ZOO.java	(revision 672)
@@ -0,0 +1,10 @@
+import java.lang.*;
+import java.util.*;
+
+public class ZOO {
+    static { System.loadLibrary("ZOO"); }
+    public static Integer SERVICE_SUCCEEDED=3;
+    public static Integer SERVICE_FAILED=4;
+    public static native String _(String a);
+    public static native Integer updateStatus(HashMap conf,String pourcent,String message);
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/zoo-api.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/zoo-api.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/java/zoo-api.c	(revision 672)
@@ -0,0 +1,31 @@
+#include "ZOO.h"
+#include "service.h"
+#include "service_internal.h"
+#include "service_internal_java.h"
+
+JNIEXPORT jstring JNICALL Java_ZOO__1
+  (JNIEnv *env, jclass class, jstring msg){
+  const char *message = (*env)->GetStringUTFChars(env,msg, 0);
+  return (*env)->NewStringUTF(env, _(message));
+
+}
+
+JNIEXPORT jobject JNICALL Java_ZOO_updateStatus
+  (JNIEnv *env, jclass class, jobject conf, jstring pourc, jstring msg){
+
+  jclass scHashMapClass,scHashMap_class;
+#ifdef JAVA7
+  scHashMapClass = (*env).FindClass("java/util/HashMap");
+#else
+  scHashMapClass = (*env)->FindClass(env, "java/util/HashMap");
+#endif
+  const char *pourcent = (*env)->GetStringUTFChars(env,pourc, 0);
+  const char *message = (*env)->GetStringUTFChars(env,msg, 0);
+  maps* m = mapsFromHashMap(env,conf,scHashMapClass);
+  setMapInMaps(m,"lenv","status",pourcent);
+  setMapInMaps(m,"lenv","message",message);
+  _updateStatus(m);
+  freeMaps(&m);
+  free(m);
+  return (jint)0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-api.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-api.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-api.js	(revision 672)
@@ -0,0 +1,6322 @@
+/**
+ * Author : René-Luc D'Hont
+ *
+ * Copyright 2010 3liz SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Copyright (c) 2006-2011 by OpenLayers Contributors (see 
+ * https://github.com/openlayers/openlayers/blob/master/authors.txt for full 
+ * list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. 
+ */
+
+/**
+ * Class: ZOO
+ */
+ZOO = {
+  /**
+   * Constant: SERVICE_ACCEPTED
+   * {Integer} used for
+   */
+  SERVICE_ACCEPTED: 0,
+  /**
+   * Constant: SERVICE_STARTED
+   * {Integer} used for
+   */
+  SERVICE_STARTED: 1,
+  /**
+   * Constant: SERVICE_PAUSED
+   * {Integer} used for
+   */
+  SERVICE_PAUSED: 2,
+  /**
+   * Constant: SERVICE_SUCCEEDED
+   * {Integer} used for
+   */
+  SERVICE_SUCCEEDED: 3,
+  /**
+   * Constant: SERVICE_FAILED
+   * {Integer} used for
+   */
+  SERVICE_FAILED: 4,
+  /** 
+   * Function: removeItem
+   * Remove an object from an array. Iterates through the array
+   *     to find the item, then removes it.
+   *
+   * Parameters:
+   * array - {Array}
+   * item - {Object}
+   * 
+   * Return
+   * {Array} A reference to the array
+   */
+  removeItem: function(array, item) {
+    for(var i = array.length - 1; i >= 0; i--) {
+        if(array[i] == item) {
+            array.splice(i,1);
+        }
+    }
+    return array;
+  },
+  /** 
+   * Function: indexOf
+   * 
+   * Parameters:
+   * array - {Array}
+   * obj - {Object}
+   * 
+   * Returns:
+   * {Integer} The index at, which the first object was found in the array.
+   *           If not found, returns -1.
+   */
+  indexOf: function(array, obj) {
+    for(var i=0, len=array.length; i<len; i++) {
+      if (array[i] == obj)
+        return i;
+    }
+    return -1;   
+  },
+  /**
+   * Function: extend
+   * Copy all properties of a source object to a destination object. Modifies
+   *     the passed in destination object.  Any properties on the source object
+   *     that are set to undefined will not be (re)set on the destination object.
+   *
+   * Parameters:
+   * destination - {Object} The object that will be modified
+   * source - {Object} The object with properties to be set on the destination
+   *
+   * Returns:
+   * {Object} The destination object.
+   */
+  extend: function(destination, source) {
+    destination = destination || {};
+    if(source) {
+      for(var property in source) {
+        var value = source[property];
+        if(value !== undefined)
+          destination[property] = value;
+      }
+    }
+    return destination;
+  },
+  /**
+   * Function: rad
+   * 
+   * Parameters:
+   * x - {Float}
+   * 
+   * Returns:
+   * {Float}
+   */
+  rad: function(x) {return x*Math.PI/180;},
+  /**
+   * Function: distVincenty
+   * Given two objects representing points with geographic coordinates, this
+   *     calculates the distance between those points on the surface of an
+   *     ellipsoid.
+   * 
+   * Parameters:
+   * p1 - {<ZOO.Geometry.Point>} (or any object with both .x, .y properties)
+   * p2 - {<ZOO.Geometry.Point>} (or any object with both .x, .y properties)
+   * 
+   * Returns:
+   * {Float} The distance (in km) between the two input points as measured on an
+   *     ellipsoid.  Note that the input point objects must be in geographic
+   *     coordinates (decimal degrees) and the return distance is in kilometers.
+   */
+  distVincenty: function(p1, p2) {
+    var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;
+    var L = ZOO.rad(p2.x - p1.y);
+    var U1 = Math.atan((1-f) * Math.tan(ZOO.rad(p1.y)));
+    var U2 = Math.atan((1-f) * Math.tan(ZOO.rad(p2.y)));
+    var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
+    var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
+    var lambda = L, lambdaP = 2*Math.PI;
+    var iterLimit = 20;
+    while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) {
+        var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
+        var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
+        (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));
+        if (sinSigma==0) {
+            return 0;  // co-incident points
+        }
+        var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
+        var sigma = Math.atan2(sinSigma, cosSigma);
+        var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);
+        var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);
+        var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
+        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
+        lambdaP = lambda;
+        lambda = L + (1-C) * f * Math.sin(alpha) *
+        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
+    }
+    if (iterLimit==0) {
+        return NaN;  // formula failed to converge
+    }
+    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
+    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
+    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
+    var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+        B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
+    var s = b*A*(sigma-deltaSigma);
+    var d = s.toFixed(3)/1000; // round to 1mm precision
+    return d;
+  },
+  /**
+   * Function: Class
+   * Method used to create ZOO classes. Includes support for
+   *     multiple inheritance.
+   */
+  Class: function() {
+    var Class = function() {
+      this.initialize.apply(this, arguments);
+    };
+    var extended = {};
+    var parent;
+    for(var i=0; i<arguments.length; ++i) {
+      if(typeof arguments[i] == "function") {
+        // get the prototype of the superclass
+        parent = arguments[i].prototype;
+      } else {
+        // in this case we're extending with the prototype
+        parent = arguments[i];
+      }
+      ZOO.extend(extended, parent);
+    }
+    Class.prototype = extended;
+
+    return Class;
+  },
+  /**
+   * Function: UpdateStatus
+   * Method used to update the status of the process
+   *
+   * Parameters:
+   * env - {Object} The environment object
+   * value - {Float} the status value between 0 to 100
+   */
+  UpdateStatus: function(env,value) {
+    return ZOOUpdateStatus(env,value);
+  }
+};
+
+/**
+ * Class: ZOO.String
+ * Contains convenience methods for string manipulation
+ */
+ZOO.String = {
+  /**
+   * Function: startsWith
+   * Test whether a string starts with another string. 
+   * 
+   * Parameters:
+   * str - {String} The string to test.
+   * sub - {Sring} The substring to look for.
+   *  
+   * Returns:
+   * {Boolean} The first string starts with the second.
+   */
+  startsWith: function(str, sub) {
+    return (str.indexOf(sub) == 0);
+  },
+  /**
+   * Function: contains
+   * Test whether a string contains another string.
+   * 
+   * Parameters:
+   * str - {String} The string to test.
+   * sub - {String} The substring to look for.
+   * 
+   * Returns:
+   * {Boolean} The first string contains the second.
+   */
+  contains: function(str, sub) {
+    return (str.indexOf(sub) != -1);
+  },
+  /**
+   * Function: trim
+   * Removes leading and trailing whitespace characters from a string.
+   * 
+   * Parameters:
+   * str - {String} The (potentially) space padded string.  This string is not
+   *     modified.
+   * 
+   * Returns:
+   * {String} A trimmed version of the string with all leading and 
+   *     trailing spaces removed.
+   */
+  trim: function(str) {
+    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+  },
+  /**
+   * Function: camelize
+   * Camel-case a hyphenated string. 
+   *     Ex. "chicken-head" becomes "chickenHead", and
+   *     "-chicken-head" becomes "ChickenHead".
+   *
+   * Parameters:
+   * str - {String} The string to be camelized.  The original is not modified.
+   * 
+   * Returns:
+   * {String} The string, camelized
+   *
+   */
+  camelize: function(str) {
+    var oStringList = str.split('-');
+    var camelizedString = oStringList[0];
+    for (var i=1, len=oStringList.length; i<len; i++) {
+      var s = oStringList[i];
+      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+    }
+    return camelizedString;
+  },
+  /**
+   * Property: tokenRegEx
+   * Used to find tokens in a string.
+   * Examples: ${a}, ${a.b.c}, ${a-b}, ${5}
+   */
+  tokenRegEx:  /\$\{([\w.]+?)\}/g,
+  /**
+   * Property: numberRegEx
+   * Used to test strings as numbers.
+   */
+  numberRegEx: /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,
+  /**
+   * Function: isNumeric
+   * Determine whether a string contains only a numeric value.
+   *
+   * Examples:
+   * (code)
+   * ZOO.String.isNumeric("6.02e23") // true
+   * ZOO.String.isNumeric("12 dozen") // false
+   * ZOO.String.isNumeric("4") // true
+   * ZOO.String.isNumeric(" 4 ") // false
+   * (end)
+   *
+   * Returns:
+   * {Boolean} String contains only a number.
+   */
+  isNumeric: function(value) {
+    return ZOO.String.numberRegEx.test(value);
+  },
+  /**
+   * Function: numericIf
+   * Converts a string that appears to be a numeric value into a number.
+   * 
+   * Returns
+   * {Number|String} a Number if the passed value is a number, a String
+   *     otherwise. 
+   */
+  numericIf: function(value) {
+    return ZOO.String.isNumeric(value) ? parseFloat(value) : value;
+  }
+};
+
+/**
+ * Class: ZOO.Class
+ * Object for creating CLASS
+ */
+ZOO.Class = function() {
+  var len = arguments.length;
+  var P = arguments[0];
+  var F = arguments[len-1];
+  var C = typeof F.initialize == "function" ?
+    F.initialize :
+    function(){ P.prototype.initialize.apply(this, arguments); };
+
+  if (len > 1) {
+    var newArgs = [C, P].concat(
+          Array.prototype.slice.call(arguments).slice(1, len-1), F);
+    ZOO.inherit.apply(null, newArgs);
+  } else {
+    C.prototype = F;
+  }
+  return C;
+};
+/**
+ * Function: create
+ * Function for creating CLASS
+ */
+ZOO.Class.create = function() {
+  return function() {
+    if (arguments && arguments[0] != ZOO.Class.isPrototype) {
+      this.initialize.apply(this, arguments);
+    }
+  };
+};
+/**
+ * Function: inherit
+ * Function for inheriting CLASS
+ */
+ZOO.Class.inherit = function (P) {
+  var C = function() {
+   P.call(this);
+  };
+  var newArgs = [C].concat(Array.prototype.slice.call(arguments));
+  ZOO.inherit.apply(null, newArgs);
+  return C.prototype;
+};
+/**
+ * Function: inherit
+ * Function for inheriting CLASS
+ */
+ZOO.inherit = function(C, P) {
+  var F = function() {};
+  F.prototype = P.prototype;
+  C.prototype = new F;
+  var i, l, o;
+  for(i=2, l=arguments.length; i<l; i++) {
+    o = arguments[i];
+    if(typeof o === "function") {
+      o = o.prototype;
+    }
+    ZOO.Util.extend(C.prototype, o);
+  }
+};
+/**
+ * Class: ZOO.Util
+ * Object for utilities
+ */
+ZOO.Util = ZOO.Util || {};
+/**
+ * Function: extend
+ * Function for extending object
+ */
+ZOO.Util.extend = function(destination, source) {
+  destination = destination || {};
+  if (source) {
+    for (var property in source) {
+      var value = source[property];
+      if (value !== undefined) {
+        destination[property] = value;
+      }
+    }
+  }
+  return destination;
+};
+
+ZOO._=function(str){
+    return ZOOTranslate(str);
+};
+
+/**
+ * Class: ZOO.Request
+ * Contains convenience methods for working with ZOORequest which
+ *     replace XMLHttpRequest. Because of we are not in a browser
+ *     JavaScript environment, ZOO Project provides a method to 
+ *     query servers which is based on curl : ZOORequest.
+ */
+ZOO.Request = {
+  /**
+   * Function: GET
+   * Send an HTTP GET request.
+   *
+   * Parameters:
+   * url - {String} The URL to request.
+   * params - {Object} Params to add to the url
+   * 
+   * Returns:
+   * {String} Request result.
+   */
+  Get: function(url,params) {
+    var paramsArray = [];
+    for (var key in params) {
+      var value = params[key];
+      if ((value != null) && (typeof value != 'function')) {
+        var encodedValue;
+        if (typeof value == 'object' && value.constructor == Array) {
+          /* value is an array; encode items and separate with "," */
+          var encodedItemArray = [];
+          for (var itemIndex=0, len=value.length; itemIndex<len; itemIndex++) {
+            encodedItemArray.push(encodeURIComponent(value[itemIndex]));
+          }
+          encodedValue = encodedItemArray.join(",");
+        }
+        else {
+          /* value is a string; simply encode */
+          encodedValue = encodeURIComponent(value);
+        }
+        paramsArray.push(encodeURIComponent(key) + "=" + encodedValue);
+      }
+    }
+    var paramString = paramsArray.join("&");
+    if(paramString.length > 0) {
+      var separator = (url.indexOf('?') > -1) ? '&' : '?';
+      url += separator + paramString;
+    }
+    return ZOORequest('GET',url);
+  },
+  /**
+   * Function: POST
+   * Send an HTTP POST request.
+   *
+   * Parameters:
+   * url - {String} The URL to request.
+   * body - {String} The request's body to send.
+   * headers - {Object} A key-value object of headers to push to
+   *     the request's head
+   * 
+   * Returns:
+   * {String} Request result.
+   */
+  Post: function(url,body,headers) {
+    if(!(headers instanceof Array)) {
+      var headersArray = [];
+      for (var name in headers) {
+        headersArray.push(name+': '+headers[name]); 
+      }
+      headers = headersArray;
+    }
+    return ZOORequest('POST',url,body,headers);
+  }
+};
+
+/**
+ * Class: ZOO.Bounds
+ * Instances of this class represent bounding boxes.  Data stored as left,
+ *     bottom, right, top floats. All values are initialized to null,
+ *     however, you should make sure you set them before using the bounds
+ *     for anything.
+ */
+ZOO.Bounds = ZOO.Class({
+  /**
+   * Property: left
+   * {Number} Minimum horizontal coordinate.
+   */
+  left: null,
+  /**
+   * Property: bottom
+   * {Number} Minimum vertical coordinate.
+   */
+  bottom: null,
+  /**
+   * Property: right
+   * {Number} Maximum horizontal coordinate.
+   */
+  right: null,
+  /**
+   * Property: top
+   * {Number} Maximum vertical coordinate.
+   */
+  top: null,
+  /**
+   * Constructor: ZOO.Bounds
+   * Construct a new bounds object.
+   *
+   * Parameters:
+   * left - {Number} The left bounds of the box.  Note that for width
+   *        calculations, this is assumed to be less than the right value.
+   * bottom - {Number} The bottom bounds of the box.  Note that for height
+   *          calculations, this is assumed to be more than the top value.
+   * right - {Number} The right bounds.
+   * top - {Number} The top bounds.
+   */
+  initialize: function(left, bottom, right, top) {
+    if (left != null)
+      this.left = parseFloat(left);
+    if (bottom != null)
+      this.bottom = parseFloat(bottom);
+    if (right != null)
+      this.right = parseFloat(right);
+    if (top != null)
+      this.top = parseFloat(top);
+  },
+  /**
+   * Method: clone
+   * Create a cloned instance of this bounds.
+   *
+   * Returns:
+   * {<ZOO.Bounds>} A fresh copy of the bounds
+   */
+  clone:function() {
+    return new ZOO.Bounds(this.left, this.bottom, 
+                          this.right, this.top);
+  },
+  /**
+   * Method: equals
+   * Test a two bounds for equivalence.
+   *
+   * Parameters:
+   * bounds - {<ZOO.Bounds>}
+   *
+   * Returns:
+   * {Boolean} The passed-in bounds object has the same left,
+   *           right, top, bottom components as this.  Note that if bounds 
+   *           passed in is null, returns false.
+   */
+  equals:function(bounds) {
+    var equals = false;
+    if (bounds != null)
+        equals = ((this.left == bounds.left) && 
+                  (this.right == bounds.right) &&
+                  (this.top == bounds.top) && 
+                  (this.bottom == bounds.bottom));
+    return equals;
+  },
+  /** 
+   * Method: toString
+   * 
+   * Returns:
+   * {String} String representation of bounds object. 
+   *          (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>)
+   */
+  toString:function() {
+    return ( "left-bottom=(" + this.left + "," + this.bottom + ")"
+              + " right-top=(" + this.right + "," + this.top + ")" );
+  },
+  /**
+   * APIMethod: toArray
+   *
+   * Returns:
+   * {Array} array of left, bottom, right, top
+   */
+  toArray: function() {
+    return [this.left, this.bottom, this.right, this.top];
+  },
+  /** 
+   * Method: toBBOX
+   * 
+   * Parameters:
+   * decimal - {Integer} How many significant digits in the bbox coords?
+   *                     Default is 6
+   * 
+   * Returns:
+   * {String} Simple String representation of bounds object.
+   *          (ex. <i>"5,42,10,45"</i>)
+   */
+  toBBOX:function(decimal) {
+    if (decimal== null)
+      decimal = 6; 
+    var mult = Math.pow(10, decimal);
+    var bbox = Math.round(this.left * mult) / mult + "," + 
+               Math.round(this.bottom * mult) / mult + "," + 
+               Math.round(this.right * mult) / mult + "," + 
+               Math.round(this.top * mult) / mult;
+    return bbox;
+  },
+  /**
+   * Method: toGeometry
+   * Create a new polygon geometry based on this bounds.
+   *
+   * Returns:
+   * {<ZOO.Geometry.Polygon>} A new polygon with the coordinates
+   *     of this bounds.
+   */
+  toGeometry: function() {
+    return new ZOO.Geometry.Polygon([
+      new ZOO.Geometry.LinearRing([
+        new ZOO.Geometry.Point(this.left, this.bottom),
+        new ZOO.Geometry.Point(this.right, this.bottom),
+        new ZOO.Geometry.Point(this.right, this.top),
+        new ZOO.Geometry.Point(this.left, this.top)
+      ])
+    ]);
+  },
+  /**
+   * Method: getWidth
+   * 
+   * Returns:
+   * {Float} The width of the bounds
+   */
+  getWidth:function() {
+    return (this.right - this.left);
+  },
+  /**
+   * Method: getHeight
+   * 
+   * Returns:
+   * {Float} The height of the bounds (top minus bottom).
+   */
+  getHeight:function() {
+    return (this.top - this.bottom);
+  },
+  /**
+   * Method: add
+   * 
+   * Parameters:
+   * x - {Float}
+   * y - {Float}
+   * 
+   * Returns:
+   * {<ZOO.Bounds>} A new bounds whose coordinates are the same as
+   *     this, but shifted by the passed-in x and y values.
+   */
+  add:function(x, y) {
+    if ( (x == null) || (y == null) )
+      return null;
+    return new ZOO.Bounds(this.left + x, this.bottom + y,
+                                 this.right + x, this.top + y);
+  },
+  /**
+   * Method: extend
+   * Extend the bounds to include the point, lonlat, or bounds specified.
+   *     Note, this function assumes that left < right and bottom < top.
+   * 
+   * Parameters: 
+   * object - {Object} Can be Point, or Bounds
+   */
+  extend:function(object) {
+    var bounds = null;
+    if (object) {
+      // clear cached center location
+      switch(object.CLASS_NAME) {
+        case "ZOO.Geometry.Point":
+          bounds = new ZOO.Bounds(object.x, object.y,
+                                         object.x, object.y);
+          break;
+        case "ZOO.Bounds":    
+          bounds = object;
+          break;
+      }
+      if (bounds) {
+        if ( (this.left == null) || (bounds.left < this.left))
+          this.left = bounds.left;
+        if ( (this.bottom == null) || (bounds.bottom < this.bottom) )
+          this.bottom = bounds.bottom;
+        if ( (this.right == null) || (bounds.right > this.right) )
+          this.right = bounds.right;
+        if ( (this.top == null) || (bounds.top > this.top) )
+          this.top = bounds.top;
+      }
+    }
+  },
+  /**
+   * APIMethod: contains
+   * 
+   * Parameters:
+   * x - {Float}
+   * y - {Float}
+   * inclusive - {Boolean} Whether or not to include the border.
+   *     Default is true.
+   *
+   * Returns:
+   * {Boolean} Whether or not the passed-in coordinates are within this
+   *     bounds.
+   */
+  contains:function(x, y, inclusive) {
+     //set default
+     if (inclusive == null)
+       inclusive = true;
+     if (x == null || y == null)
+       return false;
+     x = parseFloat(x);
+     y = parseFloat(y);
+
+     var contains = false;
+     if (inclusive)
+       contains = ((x >= this.left) && (x <= this.right) && 
+                   (y >= this.bottom) && (y <= this.top));
+     else
+       contains = ((x > this.left) && (x < this.right) && 
+                   (y > this.bottom) && (y < this.top));
+     return contains;
+  },
+  /**
+   * Method: intersectsBounds
+   * Determine whether the target bounds intersects this bounds.  Bounds are
+   *     considered intersecting if any of their edges intersect or if one
+   *     bounds contains the other.
+   * 
+   * Parameters:
+   * bounds - {<ZOO.Bounds>} The target bounds.
+   * inclusive - {Boolean} Treat coincident borders as intersecting.  Default
+   *     is true.  If false, bounds that do not overlap but only touch at the
+   *     border will not be considered as intersecting.
+   *
+   * Returns:
+   * {Boolean} The passed-in bounds object intersects this bounds.
+   */
+  intersectsBounds:function(bounds, inclusive) {
+    if (inclusive == null)
+      inclusive = true;
+    var intersects = false;
+    var mightTouch = (
+        this.left == bounds.right ||
+        this.right == bounds.left ||
+        this.top == bounds.bottom ||
+        this.bottom == bounds.top
+    );
+    if (inclusive || !mightTouch) {
+      var inBottom = (
+          ((bounds.bottom >= this.bottom) && (bounds.bottom <= this.top)) ||
+          ((this.bottom >= bounds.bottom) && (this.bottom <= bounds.top))
+          );
+      var inTop = (
+          ((bounds.top >= this.bottom) && (bounds.top <= this.top)) ||
+          ((this.top > bounds.bottom) && (this.top < bounds.top))
+          );
+      var inLeft = (
+          ((bounds.left >= this.left) && (bounds.left <= this.right)) ||
+          ((this.left >= bounds.left) && (this.left <= bounds.right))
+          );
+      var inRight = (
+          ((bounds.right >= this.left) && (bounds.right <= this.right)) ||
+          ((this.right >= bounds.left) && (this.right <= bounds.right))
+          );
+      intersects = ((inBottom || inTop) && (inLeft || inRight));
+    }
+    return intersects;
+  },
+  /**
+   * Method: containsBounds
+   * Determine whether the target bounds is contained within this bounds.
+   * 
+   * bounds - {<ZOO.Bounds>} The target bounds.
+   * partial - {Boolean} If any of the target corners is within this bounds
+   *     consider the bounds contained.  Default is false.  If true, the
+   *     entire target bounds must be contained within this bounds.
+   * inclusive - {Boolean} Treat shared edges as contained.  Default is
+   *     true.
+   *
+   * Returns:
+   * {Boolean} The passed-in bounds object is contained within this bounds. 
+   */
+  containsBounds:function(bounds, partial, inclusive) {
+    if (partial == null)
+      partial = false;
+    if (inclusive == null)
+      inclusive = true;
+    var bottomLeft  = this.contains(bounds.left, bounds.bottom, inclusive);
+    var bottomRight = this.contains(bounds.right, bounds.bottom, inclusive);
+    var topLeft  = this.contains(bounds.left, bounds.top, inclusive);
+    var topRight = this.contains(bounds.right, bounds.top, inclusive);
+    return (partial) ? (bottomLeft || bottomRight || topLeft || topRight)
+                     : (bottomLeft && bottomRight && topLeft && topRight);
+  },
+  CLASS_NAME: 'ZOO.Bounds'
+});
+
+/**
+ * Class: ZOO.Projection
+ * Class for coordinate transforms between coordinate systems.
+ *     Depends on the zoo-proj4js library. zoo-proj4js library 
+ *     is loaded by the ZOO Kernel with zoo-api.
+ */
+ZOO.Projection = ZOO.Class({
+  /**
+   * Property: proj
+   * {Object} Proj4js.Proj instance.
+   */
+  proj: null,
+  /**
+   * Property: projCode
+   * {String}
+   */
+  projCode: null,
+  /**
+   * Constructor: ZOO.Projection
+   * This class offers several methods for interacting with a wrapped 
+   *     zoo-pro4js projection object. 
+   *
+   * Parameters:
+   * projCode - {String} A string identifying the Well Known Identifier for
+   *    the projection.
+   * options - {Object} An optional object to set additional properties.
+   *
+   * Returns:
+   * {<ZOO.Projection>} A projection object.
+   */
+  initialize: function(projCode, options) {
+    ZOO.extend(this, options);
+    this.projCode = projCode;
+    if (Proj4js) {
+      this.proj = new Proj4js.Proj(projCode);
+    }
+  },
+  /**
+   * Method: getCode
+   * Get the string SRS code.
+   *
+   * Returns:
+   * {String} The SRS code.
+   */
+  getCode: function() {
+    return this.proj ? this.proj.srsCode : this.projCode;
+  },
+  /**
+   * Method: getUnits
+   * Get the units string for the projection -- returns null if 
+   *     zoo-proj4js is not available.
+   *
+   * Returns:
+   * {String} The units abbreviation.
+   */
+  getUnits: function() {
+    return this.proj ? this.proj.units : null;
+  },
+  /**
+   * Method: toString
+   * Convert projection to string (getCode wrapper).
+   *
+   * Returns:
+   * {String} The projection code.
+   */
+  toString: function() {
+    return this.getCode();
+  },
+  /**
+   * Method: equals
+   * Test equality of two projection instances.  Determines equality based
+   *     soley on the projection code.
+   *
+   * Returns:
+   * {Boolean} The two projections are equivalent.
+   */
+  equals: function(projection) {
+    if (projection && projection.getCode)
+      return this.getCode() == projection.getCode();
+    else
+      return false;
+  },
+  /* Method: destroy
+   * Destroy projection object.
+   */
+  destroy: function() {
+    this.proj = null;
+    this.projCode = null;
+  },
+  CLASS_NAME: 'ZOO.Projection'
+});
+/**
+ * Method: transform
+ * Transform a point coordinate from one projection to another.  Note that
+ *     the input point is transformed in place.
+ * 
+ * Parameters:
+ * point - {{ZOO.Geometry.Point> | Object} An object with x and y
+ *     properties representing coordinates in those dimensions.
+ * sourceProj - {ZOO.Projection} Source map coordinate system
+ * destProj - {ZOO.Projection} Destination map coordinate system
+ *
+ * Returns:
+ * point - {object} A transformed coordinate.  The original point is modified.
+ */
+ZOO.Projection.transform = function(point, source, dest) {
+    if (source.proj && dest.proj)
+        point = Proj4js.transform(source.proj, dest.proj, point);
+    return point;
+};
+
+/**
+ * Class: ZOO.Format
+ * Base class for format reading/writing a variety of formats. Subclasses
+ *     of ZOO.Format are expected to have read and write methods.
+ */
+ZOO.Format = ZOO.Class({
+  /**
+   * Property: options
+   * {Object} A reference to options passed to the constructor.
+   */
+  options:null,
+  /**
+   * Property: externalProjection
+   * {<ZOO.Projection>} When passed a externalProjection and
+   *     internalProjection, the format will reproject the geometries it
+   *     reads or writes. The externalProjection is the projection used by
+   *     the content which is passed into read or which comes out of write.
+   *     In order to reproject, a projection transformation function for the
+   *     specified projections must be available. This support is provided 
+   *     via zoo-proj4js.
+   */
+  externalProjection: null,
+  /**
+   * Property: internalProjection
+   * {<ZOO.Projection>} When passed a externalProjection and
+   *     internalProjection, the format will reproject the geometries it
+   *     reads or writes. The internalProjection is the projection used by
+   *     the geometries which are returned by read or which are passed into
+   *     write.  In order to reproject, a projection transformation function
+   *     for the specified projections must be available. This support is 
+   *     provided via zoo-proj4js.
+   */
+  internalProjection: null,
+  /**
+   * Property: data
+   * {Object} When <keepData> is true, this is the parsed string sent to
+   *     <read>.
+   */
+  data: null,
+  /**
+   * Property: keepData
+   * {Object} Maintain a reference (<data>) to the most recently read data.
+   *     Default is false.
+   */
+  keepData: false,
+  /**
+   * Constructor: ZOO.Format
+   * Instances of this class are not useful.  See one of the subclasses.
+   *
+   * Parameters:
+   * options - {Object} An optional object with properties to set on the
+   *           format
+   *
+   * Valid options:
+   * keepData - {Boolean} If true, upon <read>, the data property will be
+   *     set to the parsed object (e.g. the json or xml object).
+   *
+   * Returns:
+   * An instance of ZOO.Format
+   */
+  initialize: function(options) {
+    ZOO.extend(this, options);
+    this.options = options;
+  },
+  /**
+   * Method: destroy
+   * Clean up.
+   */
+  destroy: function() {
+  },
+  /**
+   * Method: read
+   * Read data from a string, and return an object whose type depends on the
+   * subclass. 
+   * 
+   * Parameters:
+   * data - {string} Data to read/parse.
+   *
+   * Returns:
+   * Depends on the subclass
+   */
+  read: function(data) {
+  },
+  /**
+   * Method: write
+   * Accept an object, and return a string. 
+   *
+   * Parameters:
+   * object - {Object} Object to be serialized
+   *
+   * Returns:
+   * {String} A string representation of the object.
+   */
+  write: function(data) {
+  },
+  CLASS_NAME: 'ZOO.Format'
+});
+/**
+ * Class: ZOO.Format.WKT
+ * Class for reading and writing Well-Known Text. Create a new instance
+ * with the <ZOO.Format.WKT> constructor.
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
+ZOO.Format.WKT = ZOO.Class(ZOO.Format, {
+  /**
+   * Constructor: ZOO.Format.WKT
+   * Create a new parser for WKT
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *           this instance
+   *
+   * Returns:
+   * {<ZOO.Format.WKT>} A new WKT parser.
+   */
+  initialize: function(options) {
+    this.regExes = {
+      'typeStr': /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,
+      'spaces': /\s+/,
+      'parenComma': /\)\s*,\s*\(/,
+      'doubleParenComma': /\)\s*\)\s*,\s*\(\s*\(/,  // can't use {2} here
+      'trimParens': /^\s*\(?(.*?)\)?\s*$/
+    };
+    ZOO.Format.prototype.initialize.apply(this, [options]);
+  },
+  /**
+   * Method: read
+   * Deserialize a WKT string and return a vector feature or an
+   *     array of vector features.  Supports WKT for POINT, 
+   *     MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON, 
+   *     MULTIPOLYGON, and GEOMETRYCOLLECTION.
+   *
+   * Parameters:
+   * wkt - {String} A WKT string
+   *
+   * Returns:
+   * {<ZOO.Feature.Vector>|Array} A feature or array of features for
+   *     GEOMETRYCOLLECTION WKT.
+   */
+  read: function(wkt) {
+    var features, type, str;
+    var matches = this.regExes.typeStr.exec(wkt);
+    if(matches) {
+      type = matches[1].toLowerCase();
+      str = matches[2];
+      if(this.parse[type]) {
+        features = this.parse[type].apply(this, [str]);
+      }
+      if (this.internalProjection && this.externalProjection) {
+        if (features && 
+            features.CLASS_NAME == "ZOO.Feature") {
+          features.geometry.transform(this.externalProjection,
+                                      this.internalProjection);
+        } else if (features &&
+            type != "geometrycollection" &&
+            typeof features == "object") {
+          for (var i=0, len=features.length; i<len; i++) {
+            var component = features[i];
+            component.geometry.transform(this.externalProjection,
+                                         this.internalProjection);
+          }
+        }
+      }
+    }    
+    return features;
+  },
+  /**
+   * Method: write
+   * Serialize a feature or array of features into a WKT string.
+   *
+   * Parameters:
+   * features - {<ZOO.Feature.Vector>|Array} A feature or array of
+   *            features
+   *
+   * Returns:
+   * {String} The WKT string representation of the input geometries
+   */
+  write: function(features) {
+    var collection, geometry, type, data, isCollection;
+    if(features.constructor == Array) {
+      collection = features;
+      isCollection = true;
+    } else {
+      collection = [features];
+      isCollection = false;
+    }
+    var pieces = [];
+    if(isCollection)
+      pieces.push('GEOMETRYCOLLECTION(');
+    for(var i=0, len=collection.length; i<len; ++i) {
+      if(isCollection && i>0)
+        pieces.push(',');
+      geometry = collection[i].geometry;
+      type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
+      if(!this.extract[type])
+        return null;
+      if (this.internalProjection && this.externalProjection) {
+        geometry = geometry.clone();
+        geometry.transform(this.internalProjection, 
+                          this.externalProjection);
+      }                       
+      data = this.extract[type].apply(this, [geometry]);
+      pieces.push(type.toUpperCase() + '(' + data + ')');
+    }
+    if(isCollection)
+      pieces.push(')');
+    return pieces.join('');
+  },
+  /**
+   * Property: extract
+   * Object with properties corresponding to the geometry types.
+   * Property values are functions that do the actual data extraction.
+   */
+  extract: {
+    /**
+     * Return a space delimited string of point coordinates.
+     * @param {<ZOO.Geometry.Point>} point
+     * @returns {String} A string of coordinates representing the point
+     */
+    'point': function(point) {
+      return point.x + ' ' + point.y;
+    },
+    /**
+     * Return a comma delimited string of point coordinates from a multipoint.
+     * @param {<ZOO.Geometry.MultiPoint>} multipoint
+     * @returns {String} A string of point coordinate strings representing
+     *                  the multipoint
+     */
+    'multipoint': function(multipoint) {
+      var array = [];
+      for(var i=0, len=multipoint.components.length; i<len; ++i) {
+        array.push(this.extract.point.apply(this, [multipoint.components[i]]));
+      }
+      return array.join(',');
+    },
+    /**
+     * Return a comma delimited string of point coordinates from a line.
+     * @param {<ZOO.Geometry.LineString>} linestring
+     * @returns {String} A string of point coordinate strings representing
+     *                  the linestring
+     */
+    'linestring': function(linestring) {
+      var array = [];
+      for(var i=0, len=linestring.components.length; i<len; ++i) {
+        array.push(this.extract.point.apply(this, [linestring.components[i]]));
+      }
+      return array.join(',');
+    },
+    /**
+     * Return a comma delimited string of linestring strings from a multilinestring.
+     * @param {<ZOO.Geometry.MultiLineString>} multilinestring
+     * @returns {String} A string of of linestring strings representing
+     *                  the multilinestring
+     */
+    'multilinestring': function(multilinestring) {
+      var array = [];
+      for(var i=0, len=multilinestring.components.length; i<len; ++i) {
+        array.push('(' +
+            this.extract.linestring.apply(this, [multilinestring.components[i]]) +
+            ')');
+      }
+      return array.join(',');
+    },
+    /**
+     * Return a comma delimited string of linear ring arrays from a polygon.
+     * @param {<ZOO.Geometry.Polygon>} polygon
+     * @returns {String} An array of linear ring arrays representing the polygon
+     */
+    'polygon': function(polygon) {
+      var array = [];
+      for(var i=0, len=polygon.components.length; i<len; ++i) {
+        array.push('(' +
+            this.extract.linestring.apply(this, [polygon.components[i]]) +
+            ')');
+      }
+      return array.join(',');
+    },
+    /**
+     * Return an array of polygon arrays from a multipolygon.
+     * @param {<ZOO.Geometry.MultiPolygon>} multipolygon
+     * @returns {Array} An array of polygon arrays representing
+     *                  the multipolygon
+     */
+    'multipolygon': function(multipolygon) {
+      var array = [];
+      for(var i=0, len=multipolygon.components.length; i<len; ++i) {
+        array.push('(' +
+            this.extract.polygon.apply(this, [multipolygon.components[i]]) +
+            ')');
+      }
+      return array.join(',');
+    }
+  },
+  /**
+   * Property: parse
+   * Object with properties corresponding to the geometry types.
+   *     Property values are functions that do the actual parsing.
+   */
+  parse: {
+    /**
+     * Method: parse.point
+     * Return point feature given a point WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the point
+     * Returns:
+     * {<ZOO.Feature>} A point feature
+     */
+    'point': function(str) {
+       var coords = ZOO.String.trim(str).split(this.regExes.spaces);
+            return new ZOO.Feature(
+                new ZOO.Geometry.Point(coords[0], coords[1])
+            );
+    },
+    /**
+     * Method: parse.multipoint
+     * Return a multipoint feature given a multipoint WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multipoint
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multipoint feature
+     */
+    'multipoint': function(str) {
+       var points = ZOO.String.trim(str).split(',');
+       var components = [];
+       for(var i=0, len=points.length; i<len; ++i) {
+         components.push(this.parse.point.apply(this, [points[i]]).geometry);
+       }
+       return new ZOO.Feature(
+           new ZOO.Geometry.MultiPoint(components)
+           );
+    },
+    /**
+     * Method: parse.linestring
+     * Return a linestring feature given a linestring WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the linestring
+     *
+     * Returns:
+     * {<ZOO.Feature>} A linestring feature
+     */
+    'linestring': function(str) {
+      var points = ZOO.String.trim(str).split(',');
+      var components = [];
+      for(var i=0, len=points.length; i<len; ++i) {
+        components.push(this.parse.point.apply(this, [points[i]]).geometry);
+      }
+      return new ZOO.Feature(
+          new ZOO.Geometry.LineString(components)
+          );
+    },
+    /**
+     * Method: parse.multilinestring
+     * Return a multilinestring feature given a multilinestring WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multilinestring
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multilinestring feature
+     */
+    'multilinestring': function(str) {
+      var line;
+      var lines = ZOO.String.trim(str).split(this.regExes.parenComma);
+      var components = [];
+      for(var i=0, len=lines.length; i<len; ++i) {
+        line = lines[i].replace(this.regExes.trimParens, '$1');
+        components.push(this.parse.linestring.apply(this, [line]).geometry);
+      }
+      return new ZOO.Feature(
+          new ZOO.Geometry.MultiLineString(components)
+          );
+    },
+    /**
+     * Method: parse.polygon
+     * Return a polygon feature given a polygon WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the polygon
+     *
+     * Returns:
+     * {<ZOO.Feature>} A polygon feature
+     */
+    'polygon': function(str) {
+       var ring, linestring, linearring;
+       var rings = ZOO.String.trim(str).split(this.regExes.parenComma);
+       var components = [];
+       for(var i=0, len=rings.length; i<len; ++i) {
+         ring = rings[i].replace(this.regExes.trimParens, '$1');
+         linestring = this.parse.linestring.apply(this, [ring]).geometry;
+         linearring = new ZOO.Geometry.LinearRing(linestring.components);
+         components.push(linearring);
+       }
+       return new ZOO.Feature(
+           new ZOO.Geometry.Polygon(components)
+           );
+    },
+    /**
+     * Method: parse.multipolygon
+     * Return a multipolygon feature given a multipolygon WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multipolygon
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multipolygon feature
+     */
+    'multipolygon': function(str) {
+      var polygon;
+      var polygons = ZOO.String.trim(str).split(this.regExes.doubleParenComma);
+      var components = [];
+      for(var i=0, len=polygons.length; i<len; ++i) {
+        polygon = polygons[i].replace(this.regExes.trimParens, '$1');
+        components.push(this.parse.polygon.apply(this, [polygon]).geometry);
+      }
+      return new ZOO.Feature(
+          new ZOO.Geometry.MultiPolygon(components)
+          );
+    },
+    /**
+     * Method: parse.geometrycollection
+     * Return an array of features given a geometrycollection WKT fragment.
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the geometrycollection
+     *
+     * Returns:
+     * {Array} An array of ZOO.Feature
+     */
+    'geometrycollection': function(str) {
+      // separate components of the collection with |
+      str = str.replace(/,\s*([A-Za-z])/g, '|$1');
+      var wktArray = ZOO.String.trim(str).split('|');
+      var components = [];
+      for(var i=0, len=wktArray.length; i<len; ++i) {
+        components.push(ZOO.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
+      }
+      return components;
+    }
+  },
+  CLASS_NAME: 'ZOO.Format.WKT'
+});
+/**
+ * Class: ZOO.Format.JSON
+ * A parser to read/write JSON safely. Create a new instance with the
+ *     <ZOO.Format.JSON> constructor.
+ *
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
+ZOO.Format.JSON = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: indent
+   * {String} For "pretty" printing, the indent string will be used once for
+   *     each indentation level.
+   */
+  indent: "    ",
+  /**
+   * Property: space
+   * {String} For "pretty" printing, the space string will be used after
+   *     the ":" separating a name/value pair.
+   */
+  space: " ",
+  /**
+   * Property: newline
+   * {String} For "pretty" printing, the newline string will be used at the
+   *     end of each name/value pair or array item.
+   */
+  newline: "\n",
+  /**
+   * Property: level
+   * {Integer} For "pretty" printing, this is incremented/decremented during
+   *     serialization.
+   */
+  level: 0,
+  /**
+   * Property: pretty
+   * {Boolean} Serialize with extra whitespace for structure.  This is set
+   *     by the <write> method.
+   */
+  pretty: false,
+  /**
+   * Constructor: ZOO.Format.JSON
+   * Create a new parser for JSON.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
+  initialize: function(options) {
+    ZOO.Format.prototype.initialize.apply(this, [options]);
+  },
+  /**
+   * Method: read
+   * Deserialize a json string.
+   *
+   * Parameters:
+   * json - {String} A JSON string
+   * filter - {Function} A function which will be called for every key and
+   *     value at every level of the final result. Each value will be
+   *     replaced by the result of the filter function. This can be used to
+   *     reform generic objects into instances of classes, or to transform
+   *     date strings into Date objects.
+   *     
+   * Returns:
+   * {Object} An object, array, string, or number .
+   */
+  read: function(json, filter) {
+    /**
+     * Parsing happens in three stages. In the first stage, we run the text
+     *     against a regular expression which looks for non-JSON
+     *     characters. We are especially concerned with '()' and 'new'
+     *     because they can cause invocation, and '=' because it can cause
+     *     mutation. But just to be safe, we will reject all unexpected
+     *     characters.
+     */
+    try {
+      if (/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g, '@').
+                          replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+                          replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+        /**
+         * In the second stage we use the eval function to compile the
+         *     text into a JavaScript structure. The '{' operator is
+         *     subject to a syntactic ambiguity in JavaScript - it can
+         *     begin a block or an object literal. We wrap the text in
+         *     parens to eliminate the ambiguity.
+         */
+        var object = eval('(' + json + ')');
+        /**
+         * In the optional third stage, we recursively walk the new
+         *     structure, passing each name/value pair to a filter
+         *     function for possible transformation.
+         */
+        if(typeof filter === 'function') {
+          function walk(k, v) {
+            if(v && typeof v === 'object') {
+              for(var i in v) {
+                if(v.hasOwnProperty(i)) {
+                  v[i] = walk(i, v[i]);
+                }
+              }
+            }
+            return filter(k, v);
+          }
+          object = walk('', object);
+        }
+        if(this.keepData) {
+          this.data = object;
+        }
+        return object;
+      }
+    } catch(e) {
+      // Fall through if the regexp test fails.
+    }
+    return null;
+  },
+  /**
+   * Method: write
+   * Serialize an object into a JSON string.
+   *
+   * Parameters:
+   * value - {String} The object, array, string, number, boolean or date
+   *     to be serialized.
+   * pretty - {Boolean} Structure the output with newlines and indentation.
+   *     Default is false.
+   *
+   * Returns:
+   * {String} The JSON string representation of the input value.
+   */
+  write: function(value, pretty) {
+    this.pretty = !!pretty;
+    var json = null;
+    var type = typeof value;
+    if(this.serialize[type]) {
+      try {
+        json = this.serialize[type].apply(this, [value]);
+      } catch(err) {
+        //OpenLayers.Console.error("Trouble serializing: " + err);
+      }
+    }
+    return json;
+  },
+  /**
+   * Method: writeIndent
+   * Output an indentation string depending on the indentation level.
+   *
+   * Returns:
+   * {String} An appropriate indentation string.
+   */
+  writeIndent: function() {
+    var pieces = [];
+    if(this.pretty) {
+      for(var i=0; i<this.level; ++i) {
+        pieces.push(this.indent);
+      }
+    }
+    return pieces.join('');
+  },
+  /**
+   * Method: writeNewline
+   * Output a string representing a newline if in pretty printing mode.
+   *
+   * Returns:
+   * {String} A string representing a new line.
+   */
+  writeNewline: function() {
+    return (this.pretty) ? this.newline : '';
+  },
+  /**
+   * Method: writeSpace
+   * Output a string representing a space if in pretty printing mode.
+   *
+   * Returns:
+   * {String} A space.
+   */
+  writeSpace: function() {
+    return (this.pretty) ? this.space : '';
+  },
+  /**
+   * Property: serialize
+   * Object with properties corresponding to the serializable data types.
+   *     Property values are functions that do the actual serializing.
+   */
+  serialize: {
+    /**
+     * Method: serialize.object
+     * Transform an object into a JSON string.
+     *
+     * Parameters:
+     * object - {Object} The object to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the object.
+     */
+    'object': function(object) {
+       // three special objects that we want to treat differently
+       if(object == null)
+         return "null";
+       if(object.constructor == Date)
+         return this.serialize.date.apply(this, [object]);
+       if(object.constructor == Array)
+         return this.serialize.array.apply(this, [object]);
+       var pieces = ['{'];
+       this.level += 1;
+       var key, keyJSON, valueJSON;
+
+       var addComma = false;
+       for(key in object) {
+         if(object.hasOwnProperty(key)) {
+           // recursive calls need to allow for sub-classing
+           keyJSON = ZOO.Format.JSON.prototype.write.apply(this,
+                                                           [key, this.pretty]);
+           valueJSON = ZOO.Format.JSON.prototype.write.apply(this,
+                                                             [object[key], this.pretty]);
+           if(keyJSON != null && valueJSON != null) {
+             if(addComma)
+               pieces.push(',');
+             pieces.push(this.writeNewline(), this.writeIndent(),
+                         keyJSON, ':', this.writeSpace(), valueJSON);
+             addComma = true;
+           }
+         }
+       }
+       this.level -= 1;
+       pieces.push(this.writeNewline(), this.writeIndent(), '}');
+       return pieces.join('');
+    },
+    /**
+     * Method: serialize.array
+     * Transform an array into a JSON string.
+     *
+     * Parameters:
+     * array - {Array} The array to be serialized
+     * 
+     * Returns:
+     * {String} A JSON string representing the array.
+     */
+    'array': function(array) {
+      var json;
+      var pieces = ['['];
+      this.level += 1;
+      for(var i=0, len=array.length; i<len; ++i) {
+        // recursive calls need to allow for sub-classing
+        json = ZOO.Format.JSON.prototype.write.apply(this,
+                                                     [array[i], this.pretty]);
+        if(json != null) {
+          if(i > 0)
+            pieces.push(',');
+          pieces.push(this.writeNewline(), this.writeIndent(), json);
+        }
+      }
+      this.level -= 1;    
+      pieces.push(this.writeNewline(), this.writeIndent(), ']');
+      return pieces.join('');
+    },
+    /**
+     * Method: serialize.string
+     * Transform a string into a JSON string.
+     *
+     * Parameters:
+     * string - {String} The string to be serialized
+     * 
+     * Returns:
+     * {String} A JSON string representing the string.
+     */
+    'string': function(string) {
+      var m = {
+                '\b': '\\b',
+                '\t': '\\t',
+                '\n': '\\n',
+                '\f': '\\f',
+                '\r': '\\r',
+                '"' : '\\"',
+                '\\': '\\\\'
+      };
+      if(/["\\\x00-\x1f]/.test(string)) {
+        return '"' + string.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+            var c = m[b];
+            if(c)
+              return c;
+            c = b.charCodeAt();
+            return '\\u00' +
+            Math.floor(c / 16).toString(16) +
+            (c % 16).toString(16);
+        }) + '"';
+      }
+      return '"' + string + '"';
+    },
+    /**
+     * Method: serialize.number
+     * Transform a number into a JSON string.
+     *
+     * Parameters:
+     * number - {Number} The number to be serialized.
+     *
+     * Returns:
+     * {String} A JSON string representing the number.
+     */
+    'number': function(number) {
+      return isFinite(number) ? String(number) : "null";
+    },
+    /**
+     * Method: serialize.boolean
+     * Transform a boolean into a JSON string.
+     *
+     * Parameters:
+     * bool - {Boolean} The boolean to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the boolean.
+     */
+    'boolean': function(bool) {
+      return String(bool);
+    },
+    /**
+     * Method: serialize.date
+     * Transform a date into a JSON string.
+     *
+     * Parameters:
+     * date - {Date} The date to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the date.
+     */
+    'date': function(date) {    
+      function format(number) {
+        // Format integers to have at least two digits.
+        return (number < 10) ? '0' + number : number;
+      }
+      return '"' + date.getFullYear() + '-' +
+        format(date.getMonth() + 1) + '-' +
+        format(date.getDate()) + 'T' +
+        format(date.getHours()) + ':' +
+        format(date.getMinutes()) + ':' +
+        format(date.getSeconds()) + '"';
+    }
+  },
+  CLASS_NAME: 'ZOO.Format.JSON'
+});
+/**
+ * Class: ZOO.Format.GeoJSON
+ * Read and write GeoJSON. Create a new parser with the
+ *     <ZOO.Format.GeoJSON> constructor.
+ *
+ * Inherits from:
+ *  - <ZOO.Format.JSON>
+ */
+ZOO.Format.GeoJSON = ZOO.Class(ZOO.Format.JSON, {
+  /**
+   * Constructor: ZOO.Format.GeoJSON
+   * Create a new parser for GeoJSON.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
+  initialize: function(options) {
+    ZOO.Format.JSON.prototype.initialize.apply(this, [options]);
+  },
+  /**
+   * Method: read
+   * Deserialize a GeoJSON string.
+   *
+   * Parameters:
+   * json - {String} A GeoJSON string
+   * type - {String} Optional string that determines the structure of
+   *     the output.  Supported values are "Geometry", "Feature", and
+   *     "FeatureCollection".  If absent or null, a default of
+   *     "FeatureCollection" is assumed.
+   * filter - {Function} A function which will be called for every key and
+   *     value at every level of the final result. Each value will be
+   *     replaced by the result of the filter function. This can be used to
+   *     reform generic objects into instances of classes, or to transform
+   *     date strings into Date objects.
+   *
+   * Returns: 
+   * {Object} The return depends on the value of the type argument. If type
+   *     is "FeatureCollection" (the default), the return will be an array
+   *     of <ZOO.Feature>. If type is "Geometry", the input json
+   *     must represent a single geometry, and the return will be an
+   *     <ZOO.Geometry>.  If type is "Feature", the input json must
+   *     represent a single feature, and the return will be an
+   *     <ZOO.Feature>.
+   */
+  read: function(json, type, filter) {
+    type = (type) ? type : "FeatureCollection";
+    var results = null;
+    var obj = null;
+    if (typeof json == "string")
+      obj = ZOO.Format.JSON.prototype.read.apply(this,[json, filter]);
+    else
+      obj = json;
+    if(!obj) {
+      //ZOO.Console.error("Bad JSON: " + json);
+    } else if(typeof(obj.type) != "string") {
+      //ZOO.Console.error("Bad GeoJSON - no type: " + json);
+    } else if(this.isValidType(obj, type)) {
+      switch(type) {
+        case "Geometry":
+          try {
+            results = this.parseGeometry(obj);
+          } catch(err) {
+            //ZOO.Console.error(err);
+          }
+          break;
+        case "Feature":
+          try {
+            results = this.parseFeature(obj);
+            results.type = "Feature";
+          } catch(err) {
+            //ZOO.Console.error(err);
+          }
+          break;
+        case "FeatureCollection":
+          // for type FeatureCollection, we allow input to be any type
+          results = [];
+          switch(obj.type) {
+            case "Feature":
+              try {
+                results.push(this.parseFeature(obj));
+              } catch(err) {
+                results = null;
+                //ZOO.Console.error(err);
+              }
+              break;
+            case "FeatureCollection":
+              for(var i=0, len=obj.features.length; i<len; ++i) {
+                try {
+                  results.push(this.parseFeature(obj.features[i]));
+                } catch(err) {
+                  results = null;
+                  //ZOO.Console.error(err);
+                }
+              }
+              break;
+            default:
+              try {
+                var geom = this.parseGeometry(obj);
+                results.push(new ZOO.Feature(geom));
+              } catch(err) {
+                results = null;
+                //ZOO.Console.error(err);
+              }
+          }
+          break;
+      }
+    }
+    return results;
+  },
+  /**
+   * Method: isValidType
+   * Check if a GeoJSON object is a valid representative of the given type.
+   *
+   * Returns:
+   * {Boolean} The object is valid GeoJSON object of the given type.
+   */
+  isValidType: function(obj, type) {
+    var valid = false;
+    switch(type) {
+      case "Geometry":
+        if(ZOO.indexOf(
+              ["Point", "MultiPoint", "LineString", "MultiLineString",
+              "Polygon", "MultiPolygon", "Box", "GeometryCollection"],
+              obj.type) == -1) {
+          // unsupported geometry type
+          //ZOO.Console.error("Unsupported geometry type: " +obj.type);
+        } else {
+          valid = true;
+        }
+        break;
+      case "FeatureCollection":
+        // allow for any type to be converted to a feature collection
+        valid = true;
+        break;
+      default:
+        // for Feature types must match
+        if(obj.type == type) {
+          valid = true;
+        } else {
+          //ZOO.Console.error("Cannot convert types from " +obj.type + " to " + type);
+        }
+    }
+    return valid;
+  },
+  /**
+   * Method: parseFeature
+   * Convert a feature object from GeoJSON into an
+   *     <ZOO.Feature>.
+   *
+   * Parameters:
+   * obj - {Object} An object created from a GeoJSON object
+   *
+   * Returns:
+   * {<ZOO.Feature>} A feature.
+   */
+  parseFeature: function(obj) {
+    var feature, geometry, attributes, bbox;
+    attributes = (obj.properties) ? obj.properties : {};
+    bbox = (obj.geometry && obj.geometry.bbox) || obj.bbox;
+    try {
+      geometry = this.parseGeometry(obj.geometry);
+    } catch(err) {
+      // deal with bad geometries
+      throw err;
+    }
+    feature = new ZOO.Feature(geometry, attributes);
+    if(bbox)
+      feature.bounds = ZOO.Bounds.fromArray(bbox);
+    if(obj.id)
+      feature.fid = obj.id;
+    return feature;
+  },
+  /**
+   * Method: parseGeometry
+   * Convert a geometry object from GeoJSON into an <ZOO.Geometry>.
+   *
+   * Parameters:
+   * obj - {Object} An object created from a GeoJSON object
+   *
+   * Returns: 
+   * {<ZOO.Geometry>} A geometry.
+   */
+  parseGeometry: function(obj) {
+    if (obj == null)
+      return null;
+    var geometry, collection = false;
+    if(obj.type == "GeometryCollection") {
+      if(!(obj.geometries instanceof Array)) {
+        throw "GeometryCollection must have geometries array: " + obj;
+      }
+      var numGeom = obj.geometries.length;
+      var components = new Array(numGeom);
+      for(var i=0; i<numGeom; ++i) {
+        components[i] = this.parseGeometry.apply(
+            this, [obj.geometries[i]]
+            );
+      }
+      geometry = new ZOO.Geometry.Collection(components);
+      collection = true;
+    } else {
+      if(!(obj.coordinates instanceof Array)) {
+        throw "Geometry must have coordinates array: " + obj;
+      }
+      if(!this.parseCoords[obj.type.toLowerCase()]) {
+        throw "Unsupported geometry type: " + obj.type;
+      }
+      try {
+        geometry = this.parseCoords[obj.type.toLowerCase()].apply(
+            this, [obj.coordinates]
+            );
+      } catch(err) {
+        // deal with bad coordinates
+        throw err;
+      }
+    }
+        // We don't reproject collections because the children are reprojected
+        // for us when they are created.
+    if (this.internalProjection && this.externalProjection && !collection) {
+      geometry.transform(this.externalProjection, 
+          this.internalProjection); 
+    }                       
+    return geometry;
+  },
+  /**
+   * Property: parseCoords
+   * Object with properties corresponding to the GeoJSON geometry types.
+   *     Property values are functions that do the actual parsing.
+   */
+  parseCoords: {
+    /**
+     * Method: parseCoords.point
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Point>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A geometry.
+     */
+    "point": function(array) {
+      if(array.length != 2) {
+        throw "Only 2D points are supported: " + array;
+      }
+      return new ZOO.Geometry.Point(array[0], array[1]);
+    },
+    /**
+     * Method: parseCoords.multipoint
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiPoint>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPoint>} A geometry.
+     */
+    "multipoint": function(array) {
+      var points = [];
+      var p = null;
+      for(var i=0, len=array.length; i<len; ++i) {
+        try {
+          p = this.parseCoords["point"].apply(this, [array[i]]);
+        } catch(err) {
+          throw err;
+        }
+        points.push(p);
+      }
+      return new ZOO.Geometry.MultiPoint(points);
+    },
+    /**
+     * Method: parseCoords.linestring
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.LineString>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A geometry.
+     */
+    "linestring": function(array) {
+      var points = [];
+      var p = null;
+      for(var i=0, len=array.length; i<len; ++i) {
+        try {
+          p = this.parseCoords["point"].apply(this, [array[i]]);
+        } catch(err) {
+          throw err;
+        }
+        points.push(p);
+      }
+      return new ZOO.Geometry.LineString(points);
+    },
+    /**
+     * Method: parseCoords.multilinestring
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiLineString>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiLineString>} A geometry.
+     */
+    "multilinestring": function(array) {
+      var lines = [];
+      var l = null;
+      for(var i=0, len=array.length; i<len; ++i) {
+        try {
+          l = this.parseCoords["linestring"].apply(this, [array[i]]);
+        } catch(err) {
+          throw err;
+        }
+        lines.push(l);
+      }
+      return new ZOO.Geometry.MultiLineString(lines);
+    },
+    /**
+     * Method: parseCoords.polygon
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Polygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A geometry.
+     */
+    "polygon": function(array) {
+      var rings = [];
+      var r, l;
+      for(var i=0, len=array.length; i<len; ++i) {
+        try {
+          l = this.parseCoords["linestring"].apply(this, [array[i]]);
+        } catch(err) {
+          throw err;
+        }
+        r = new ZOO.Geometry.LinearRing(l.components);
+        rings.push(r);
+      }
+      return new ZOO.Geometry.Polygon(rings);
+    },
+    /**
+     * Method: parseCoords.multipolygon
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiPolygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPolygon>} A geometry.
+     */
+    "multipolygon": function(array) {
+      var polys = [];
+      var p = null;
+      for(var i=0, len=array.length; i<len; ++i) {
+        try {
+          p = this.parseCoords["polygon"].apply(this, [array[i]]);
+        } catch(err) {
+          throw err;
+        }
+        polys.push(p);
+      }
+      return new ZOO.Geometry.MultiPolygon(polys);
+    },
+    /**
+     * Method: parseCoords.box
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Polygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A geometry.
+     */
+    "box": function(array) {
+      if(array.length != 2) {
+        throw "GeoJSON box coordinates must have 2 elements";
+      }
+      return new ZOO.Geometry.Polygon([
+          new ZOO.Geometry.LinearRing([
+            new ZOO.Geometry.Point(array[0][0], array[0][1]),
+            new ZOO.Geometry.Point(array[1][0], array[0][1]),
+            new ZOO.Geometry.Point(array[1][0], array[1][1]),
+            new ZOO.Geometry.Point(array[0][0], array[1][1]),
+            new Z0O.Geometry.Point(array[0][0], array[0][1])
+          ])
+      ]);
+    }
+  },
+  /**
+   * Method: write
+   * Serialize a feature, geometry, array of features into a GeoJSON string.
+   *
+   * Parameters:
+   * obj - {Object} An <ZOO.Feature>, <ZOO.Geometry>,
+   *     or an array of features.
+   * pretty - {Boolean} Structure the output with newlines and indentation.
+   *     Default is false.
+   *
+   * Returns:
+   * {String} The GeoJSON string representation of the input geometry,
+   *     features, or array of features.
+   */
+  write: function(obj, pretty) {
+    var geojson = {
+      "type": null
+    };
+    if(obj instanceof Array) {
+      geojson.type = "FeatureCollection";
+      var numFeatures = obj.length;
+      geojson.features = new Array(numFeatures);
+      for(var i=0; i<numFeatures; ++i) {
+        var element = obj[i];
+        if(!element instanceof ZOO.Feature) {
+          var msg = "FeatureCollection only supports collections " +
+            "of features: " + element;
+          throw msg;
+        }
+        geojson.features[i] = this.extract.feature.apply(this, [element]);
+      }
+    } else if (obj.CLASS_NAME.indexOf("ZOO.Geometry") == 0) {
+      geojson = this.extract.geometry.apply(this, [obj]);
+    } else if (obj instanceof ZOO.Feature) {
+      geojson = this.extract.feature.apply(this, [obj]);
+      /*
+      if(obj.layer && obj.layer.projection) {
+        geojson.crs = this.createCRSObject(obj);
+      }
+      */
+    }
+    return ZOO.Format.JSON.prototype.write.apply(this,
+                                                 [geojson, pretty]);
+  },
+  /**
+   * Method: createCRSObject
+   * Create the CRS object for an object.
+   *
+   * Parameters:
+   * object - {<ZOO.Feature>} 
+   *
+   * Returns:
+   * {Object} An object which can be assigned to the crs property
+   * of a GeoJSON object.
+   */
+  createCRSObject: function(object) {
+    //var proj = object.layer.projection.toString();
+    var proj = object.projection.toString();
+    var crs = {};
+    if (proj.match(/epsg:/i)) {
+      var code = parseInt(proj.substring(proj.indexOf(":") + 1));
+      if (code == 4326) {
+        crs = {
+          "type": "OGC",
+          "properties": {
+            "urn": "urn:ogc:def:crs:OGC:1.3:CRS84"
+          }
+        };
+      } else {    
+        crs = {
+          "type": "EPSG",
+          "properties": {
+            "code": code 
+          }
+        };
+      }    
+    }
+    return crs;
+  },
+  /**
+   * Property: extract
+   * Object with properties corresponding to the GeoJSON types.
+   *     Property values are functions that do the actual value extraction.
+   */
+  extract: {
+    /**
+     * Method: extract.feature
+     * Return a partial GeoJSON object representing a single feature.
+     *
+     * Parameters:
+     * feature - {<ZOO.Feature>}
+     *
+     * Returns:
+     * {Object} An object representing the point.
+     */
+    'feature': function(feature) {
+      var geom = this.extract.geometry.apply(this, [feature.geometry]);
+      return {
+        "type": "Feature",
+        "id": feature.fid == null ? feature.id : feature.fid,
+        "properties": feature.attributes,
+        "geometry": geom
+      };
+    },
+    /**
+     * Method: extract.geometry
+     * Return a GeoJSON object representing a single geometry.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry>}
+     *
+     * Returns:
+     * {Object} An object representing the geometry.
+     */
+    'geometry': function(geometry) {
+      if (geometry == null)
+        return null;
+      if (this.internalProjection && this.externalProjection) {
+        geometry = geometry.clone();
+        geometry.transform(this.internalProjection, 
+            this.externalProjection);
+      }                       
+      var geometryType = geometry.CLASS_NAME.split('.')[2];
+      var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
+      var json;
+      if(geometryType == "Collection")
+        json = {
+          "type": "GeometryCollection",
+          "geometries": data
+        };
+      else
+        json = {
+          "type": geometryType,
+          "coordinates": data
+        };
+      return json;
+    },
+    /**
+     * Method: extract.point
+     * Return an array of coordinates from a point.
+     *
+     * Parameters:
+     * point - {<ZOO.Geometry.Point>}
+     *
+     * Returns: 
+     * {Array} An array of coordinates representing the point.
+     */
+    'point': function(point) {
+      return [point.x, point.y];
+    },
+    /**
+     * Method: extract.multipoint
+     * Return an array of coordinates from a multipoint.
+     *
+     * Parameters:
+     * multipoint - {<ZOO.Geometry.MultiPoint>}
+     *
+     * Returns: 
+     * {Array} An array of point coordinate arrays representing
+     *     the multipoint.
+     */
+    'multipoint': function(multipoint) {
+      var array = [];
+      for(var i=0, len=multipoint.components.length; i<len; ++i) {
+        array.push(this.extract.point.apply(this, [multipoint.components[i]]));
+      }
+      return array;
+    },
+    /**
+     * Method: extract.linestring
+     * Return an array of coordinate arrays from a linestring.
+     *
+     * Parameters:
+     * linestring - {<ZOO.Geometry.LineString>}
+     *
+     * Returns:
+     * {Array} An array of coordinate arrays representing
+     *     the linestring.
+     */
+    'linestring': function(linestring) {
+      var array = [];
+      for(var i=0, len=linestring.components.length; i<len; ++i) {
+        array.push(this.extract.point.apply(this, [linestring.components[i]]));
+      }
+      return array;
+    },
+    /**
+     * Method: extract.multilinestring
+     * Return an array of linestring arrays from a linestring.
+     * 
+     * Parameters:
+     * multilinestring - {<ZOO.Geometry.MultiLineString>}
+     * 
+     * Returns:
+     * {Array} An array of linestring arrays representing
+     *     the multilinestring.
+     */
+    'multilinestring': function(multilinestring) {
+      var array = [];
+      for(var i=0, len=multilinestring.components.length; i<len; ++i) {
+        array.push(this.extract.linestring.apply(this, [multilinestring.components[i]]));
+      }
+      return array;
+    },
+    /**
+     * Method: extract.polygon
+     * Return an array of linear ring arrays from a polygon.
+     *
+     * Parameters:
+     * polygon - {<ZOO.Geometry.Polygon>}
+     * 
+     * Returns:
+     * {Array} An array of linear ring arrays representing the polygon.
+     */
+    'polygon': function(polygon) {
+      var array = [];
+      for(var i=0, len=polygon.components.length; i<len; ++i) {
+        array.push(this.extract.linestring.apply(this, [polygon.components[i]]));
+      }
+      return array;
+    },
+    /**
+     * Method: extract.multipolygon
+     * Return an array of polygon arrays from a multipolygon.
+     * 
+     * Parameters:
+     * multipolygon - {<ZOO.Geometry.MultiPolygon>}
+     * 
+     * Returns:
+     * {Array} An array of polygon arrays representing
+     *     the multipolygon
+     */
+    'multipolygon': function(multipolygon) {
+      var array = [];
+      for(var i=0, len=multipolygon.components.length; i<len; ++i) {
+        array.push(this.extract.polygon.apply(this, [multipolygon.components[i]]));
+      }
+      return array;
+    },
+    /**
+     * Method: extract.collection
+     * Return an array of geometries from a geometry collection.
+     * 
+     * Parameters:
+     * collection - {<ZOO.Geometry.Collection>}
+     * 
+     * Returns:
+     * {Array} An array of geometry objects representing the geometry
+     *     collection.
+     */
+    'collection': function(collection) {
+      var len = collection.components.length;
+      var array = new Array(len);
+      for(var i=0; i<len; ++i) {
+        array[i] = this.extract.geometry.apply(
+            this, [collection.components[i]]
+            );
+      }
+      return array;
+    }
+  },
+  CLASS_NAME: 'ZOO.Format.GeoJSON'
+});
+/**
+ * Class: ZOO.Format.KML
+ * Read/Write KML. Create a new instance with the <ZOO.Format.KML>
+ *     constructor. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
+ZOO.Format.KML = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: kmlns
+   * {String} KML Namespace to use. Defaults to 2.2 namespace.
+   */
+  kmlns: "http://www.opengis.net/kml/2.2",
+  /** 
+   * Property: foldersName
+   * {String} Name of the folders.  Default is "ZOO export".
+   *          If set to null, no name element will be created.
+   */
+  foldersName: "ZOO export",
+  /** 
+   * Property: foldersDesc
+   * {String} Description of the folders. Default is "Exported on [date]."
+   *          If set to null, no description element will be created.
+   */
+  foldersDesc: "Created on " + new Date(),
+  /** 
+   * Property: placemarksDesc
+   * {String} Name of the placemarks.  Default is "No description available".
+   */
+  placemarksDesc: "No description available",
+  /**
+   * Property: extractAttributes
+   * {Boolean} Extract attributes from KML.  Default is true.
+   *           Extracting styleUrls requires this to be set to true
+   */
+  extractAttributes: true,
+  /**
+   * Constructor: ZOO.Format.KML
+   * Create a new parser for KML.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
+  initialize: function(options) {
+    // compile regular expressions once instead of every time they are used
+    this.regExes = {
+           trimSpace: (/^\s*|\s*$/g),
+           removeSpace: (/\s*/g),
+           splitSpace: (/\s+/),
+           trimComma: (/\s*,\s*/g),
+           kmlColor: (/(\w{2})(\w{2})(\w{2})(\w{2})/),
+           kmlIconPalette: (/root:\/\/icons\/palette-(\d+)(\.\w+)/),
+           straightBracket: (/\$\[(.*?)\]/g)
+    };
+    // KML coordinates are always in longlat WGS84
+    this.externalProjection = new ZOO.Projection("EPSG:4326");
+    ZOO.Format.prototype.initialize.apply(this, [options]);
+  },
+  /**
+   * APIMethod: read
+   * Read data from a string, and return a list of features. 
+   * 
+   * Parameters: 
+   * data    - {String} data to read/parse.
+   *
+   * Returns:
+   * {Array(<ZOO.Feature>)} List of features.
+   */
+  read: function(data) {
+    this.features = [];
+    data = data.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "");
+    data = new XML(data);
+    var placemarks = data..*::Placemark;
+    this.parseFeatures(placemarks);
+    return this.features;
+  },
+  /**
+   * Method: parseFeatures
+   * Loop through all Placemark nodes and parse them.
+   * Will create a list of features
+   * 
+   * Parameters: 
+   * nodes    - {Array} of {E4XElement} data to read/parse.
+   * options  - {Object} Hash of options
+   * 
+   */
+  parseFeatures: function(nodes) {
+    var features = new Array(nodes.length());
+    for(var i=0, len=nodes.length(); i<len; i++) {
+      var featureNode = nodes[i];
+      var feature = this.parseFeature.apply(this,[featureNode]) ;
+      features[i] = feature;
+    }
+    this.features = this.features.concat(features);
+  },
+  /**
+   * Method: parseFeature
+   * This function is the core of the KML parsing code in ZOO.
+   *     It creates the geometries that are then attached to the returned
+   *     feature, and calls parseAttributes() to get attribute data out.
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {<ZOO.Feature>} A vector feature.
+   */
+  parseFeature: function(node) {
+    // only accept one geometry per feature - look for highest "order"
+    var order = ["MultiGeometry", "Polygon", "LineString", "Point"];
+    var type, nodeList, geometry, parser;
+    for(var i=0, len=order.length; i<len; ++i) {
+      type = order[i];
+      nodeList = node.descendants(QName(null,type));
+      if (nodeList.length()> 0) {
+        var parser = this.parseGeometry[type.toLowerCase()];
+        if(parser) {
+          geometry = parser.apply(this, [nodeList[0]]);
+          if (this.internalProjection && this.externalProjection) {
+            geometry.transform(this.externalProjection, 
+                               this.internalProjection); 
+          }                       
+        }
+        // stop looking for different geometry types
+        break;
+      }
+    }
+    // construct feature (optionally with attributes)
+    var attributes;
+    if(this.extractAttributes) {
+      attributes = this.parseAttributes(node);
+    }
+    var feature = new ZOO.Feature(geometry, attributes);
+    var fid = node.@id || node.@name;
+    if(fid != null)
+      feature.fid = fid;
+    return feature;
+  },
+  /**
+   * Property: parseGeometry
+   * Properties of this object are the functions that parse geometries based
+   *     on their type.
+   */
+  parseGeometry: {
+    /**
+     * Method: parseGeometry.point
+     * Given a KML node representing a point geometry, create a ZOO
+     *     point geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML Point node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A point geometry.
+     */
+    'point': function(node) {
+      var coordString = node.*::coordinates.toString();
+      coordString = coordString.replace(this.regExes.removeSpace, "");
+      coords = coordString.split(",");
+      var point = null;
+      if(coords.length > 1) {
+        // preserve third dimension
+        if(coords.length == 2) {
+          coords[2] = null;
+        }
+        point = new ZOO.Geometry.Point(coords[0], coords[1], coords[2]);
+      }
+      return point;
+    },
+    /**
+     * Method: parseGeometry.linestring
+     * Given a KML node representing a linestring geometry, create a
+     *     ZOO linestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML LineString node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A linestring geometry.
+     */
+    'linestring': function(node, ring) {
+      var line = null;
+      var coordString = node.*::coordinates.toString();
+      coordString = coordString.replace(this.regExes.trimSpace,
+          "");
+      coordString = coordString.replace(this.regExes.trimComma,
+          ",");
+      var pointList = coordString.split(this.regExes.splitSpace);
+      var numPoints = pointList.length;
+      var points = new Array(numPoints);
+      var coords, numCoords;
+      for(var i=0; i<numPoints; ++i) {
+        coords = pointList[i].split(",");
+        numCoords = coords.length;
+        if(numCoords > 1) {
+          if(coords.length == 2) {
+            coords[2] = null;
+          }
+          points[i] = new ZOO.Geometry.Point(coords[0],
+                                             coords[1],
+                                             coords[2]);
+        }
+      }
+      if(numPoints) {
+        if(ring) {
+          line = new ZOO.Geometry.LinearRing(points);
+        } else {
+          line = new ZOO.Geometry.LineString(points);
+        }
+      } else {
+        throw "Bad LineString coordinates: " + coordString;
+      }
+      return line;
+    },
+    /**
+     * Method: parseGeometry.polygon
+     * Given a KML node representing a polygon geometry, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML Polygon node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
+    'polygon': function(node) {
+      var nodeList = node..*::LinearRing;
+      var numRings = nodeList.length();
+      var components = new Array(numRings);
+      if(numRings > 0) {
+        // this assumes exterior ring first, inner rings after
+        var ring;
+        for(var i=0, len=nodeList.length(); i<len; ++i) {
+          ring = this.parseGeometry.linestring.apply(this,
+                                                     [nodeList[i], true]);
+          if(ring) {
+            components[i] = ring;
+          } else {
+            throw "Bad LinearRing geometry: " + i;
+          }
+        }
+      }
+      return new ZOO.Geometry.Polygon(components);
+    },
+    /**
+     * Method: parseGeometry.multigeometry
+     * Given a KML node representing a multigeometry, create a
+     *     ZOO geometry collection.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML MultiGeometry node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Collection>} A geometry collection.
+     */
+    'multigeometry': function(node) {
+      var child, parser;
+      var parts = [];
+      var children = node.*::*;
+      for(var i=0, len=children.length(); i<len; ++i ) {
+        child = children[i];
+        var type = child.localName();
+        var parser = this.parseGeometry[type.toLowerCase()];
+        if(parser) {
+          parts.push(parser.apply(this, [child]));
+        }
+      }
+      return new ZOO.Geometry.Collection(parts);
+    }
+  },
+  /**
+   * Method: parseAttributes
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
+  parseAttributes: function(node) {
+    var attributes = {};
+    var edNodes = node.*::ExtendedData;
+    if (edNodes.length() > 0) {
+      attributes = this.parseExtendedData(edNodes[0])
+    }
+    var child, grandchildren;
+    var children = node.*::*;
+    for(var i=0, len=children.length(); i<len; ++i) {
+      child = children[i];
+      grandchildren = child..*::*;
+      if(grandchildren.length() == 1) {
+        var name = child.localName();
+        var value = child.toString();
+        if (value) {
+          value = value.replace(this.regExes.trimSpace, "");
+          attributes[name] = value;
+        }
+      }
+    }
+    return attributes;
+  },
+  /**
+   * Method: parseExtendedData
+   * Parse ExtendedData from KML. Limited support for schemas/datatypes.
+   *     See http://code.google.com/apis/kml/documentation/kmlreference.html#extendeddata
+   *     for more information on extendeddata.
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
+  parseExtendedData: function(node) {
+    var attributes = {};
+    var dataNodes = node.*::Data;
+    for (var i = 0, len = dataNodes.length(); i < len; i++) {
+      var data = dataNodes[i];
+      var key = data.@name;
+      var ed = {};
+      var valueNode = data.*::value;
+      if (valueNode.length() > 0)
+        ed['value'] = valueNode[0].toString();
+      var nameNode = data.*::displayName;
+      if (nameNode.length() > 0)
+        ed['displayName'] = valueNode[0].toString();
+      attributes[key] = ed;
+    }
+    return attributes;
+  },
+  /**
+   * Method: write
+   * Accept Feature Collection, and return a string. 
+   * 
+   * Parameters:
+   * features - {Array(<ZOO.Feature>} An array of features.
+   *
+   * Returns:
+   * {String} A KML string.
+   */
+  write: function(features) {
+    if(!(features instanceof Array))
+      features = [features];
+    var kml = new XML('<kml xmlns="'+this.kmlns+'"></kml>');
+    var folder = kml.Document.Folder;
+    folder.name = this.foldersName;
+    folder.description = this.foldersDesc;
+    for(var i=0, len=features.length; i<len; ++i) {
+      folder.Placemark[i] = this.createPlacemark(features[i]);
+    }
+    return kml.toXMLString();
+  },
+  /**
+   * Method: createPlacemark
+   * Creates and returns a KML placemark node representing the given feature. 
+   * 
+   * Parameters:
+   * feature - {<ZOO.Feature>}
+   * 
+   * Returns:
+   * {E4XElement}
+   */
+  createPlacemark: function(feature) {
+    var placemark = new XML('<Placemark xmlns="'+this.kmlns+'"></Placemark>');
+    placemark.name = (feature.attributes.name) ?
+                    feature.attributes.name : feature.id;
+    placemark.description = (feature.attributes.description) ?
+                             feature.attributes.description : this.placemarksDesc;
+    if(feature.fid != null)
+      placemark.@id = feature.fid;
+    placemark.*[2] = this.buildGeometryNode(feature.geometry);
+    return placemark;
+  },
+  /**
+   * Method: buildGeometryNode
+   * Builds and returns a KML geometry node with the given geometry.
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   * 
+   * Returns:
+   * {E4XElement}
+   */
+  buildGeometryNode: function(geometry) {
+    if (this.internalProjection && this.externalProjection) {
+      geometry = geometry.clone();
+      geometry.transform(this.internalProjection, 
+                         this.externalProjection);
+    }
+    var className = geometry.CLASS_NAME;
+    var type = className.substring(className.lastIndexOf(".") + 1);
+    var builder = this.buildGeometry[type.toLowerCase()];
+    var node = null;
+    if(builder) {
+      node = builder.apply(this, [geometry]);
+    }
+    return node;
+  },
+  /**
+   * Property: buildGeometry
+   * Object containing methods to do the actual geometry node building
+   *     based on geometry type.
+   */
+  buildGeometry: {
+    /**
+     * Method: buildGeometry.point
+     * Given a ZOO point geometry, create a KML point.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A point geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML point node.
+     */
+    'point': function(geometry) {
+      var kml = new XML('<Point xmlns="'+this.kmlns+'"></Point>');
+      kml.coordinates = this.buildCoordinatesNode(geometry);
+      return kml;
+    },
+    /**
+     * Method: buildGeometry.multipoint
+     * Given a ZOO multipoint geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
+    'multipoint': function(geometry) {
+      return this.buildGeometry.collection.apply(this, [geometry]);
+    },
+    /**
+     * Method: buildGeometry.linestring
+     * Given a ZOO linestring geometry, create a KML linestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LineString>} A linestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML linestring node.
+     */
+    'linestring': function(geometry) {
+      var kml = new XML('<LineString xmlns="'+this.kmlns+'"></LineString>');
+      kml.coordinates = this.buildCoordinatesNode(geometry);
+      return kml;
+    },
+    /**
+     * Method: buildGeometry.multilinestring
+     * Given a ZOO multilinestring geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiLineString>} A multilinestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
+    'multilinestring': function(geometry) {
+      return this.buildGeometry.collection.apply(this, [geometry]);
+    },
+    /**
+     * Method: buildGeometry.linearring
+     * Given a ZOO linearring geometry, create a KML linearring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LinearRing>} A linearring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML linearring node.
+     */
+    'linearring': function(geometry) {
+      var kml = new XML('<LinearRing xmlns="'+this.kmlns+'"></LinearRing>');
+      kml.coordinates = this.buildCoordinatesNode(geometry);
+      return kml;
+    },
+    /**
+     * Method: buildGeometry.polygon
+     * Given a ZOO polygon geometry, create a KML polygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Polygon>} A polygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML polygon node.
+     */
+    'polygon': function(geometry) {
+      var kml = new XML('<Polygon xmlns="'+this.kmlns+'"></Polygon>');
+      var rings = geometry.components;
+      var ringMember, ringGeom, type;
+      for(var i=0, len=rings.length; i<len; ++i) {
+        type = (i==0) ? "outerBoundaryIs" : "innerBoundaryIs";
+        ringMember = new XML('<'+type+' xmlns="'+this.kmlns+'"></'+type+'>');
+        ringMember.LinearRing = this.buildGeometry.linearring.apply(this,[rings[i]]);
+        kml.*[i] = ringMember;
+      }
+      return kml;
+    },
+    /**
+     * Method: buildGeometry.multipolygon
+     * Given a ZOO multipolygon geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A multipolygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
+    'multipolygon': function(geometry) {
+      return this.buildGeometry.collection.apply(this, [geometry]);
+    },
+    /**
+     * Method: buildGeometry.collection
+     * Given a ZOO geometry collection, create a KML MultiGeometry.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Collection>} A geometry collection.
+     *
+     * Returns:
+     * {E4XElement} A KML MultiGeometry node.
+     */
+    'collection': function(geometry) {
+      var kml = new XML('<MultiGeometry xmlns="'+this.kmlns+'"></MultiGeometry>');
+      var child;
+      for(var i=0, len=geometry.components.length; i<len; ++i) {
+        kml.*[i] = this.buildGeometryNode.apply(this,[geometry.components[i]]);
+      }
+      return kml;
+    }
+  },
+  /**
+   * Method: buildCoordinatesNode
+   * Builds and returns the KML coordinates node with the given geometry
+   *     <coordinates>...</coordinates>
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   * 
+   * Return:
+   * {E4XElement}
+   */
+  buildCoordinatesNode: function(geometry) {
+    var cooridnates = new XML('<coordinates xmlns="'+this.kmlns+'"></coordinates>');
+    var points = geometry.components;
+    if(points) {
+      // LineString or LinearRing
+      var point;
+      var numPoints = points.length;
+      var parts = new Array(numPoints);
+      for(var i=0; i<numPoints; ++i) {
+        point = points[i];
+        parts[i] = point.x + "," + point.y;
+      }
+      coordinates = parts.join(" ");
+    } else {
+      // Point
+      coordinates = geometry.x + "," + geometry.y;
+    }
+    return coordinates;
+  },
+  CLASS_NAME: 'ZOO.Format.KML'
+});
+/**
+ * Class: ZOO.Format.GML
+ * Read/Write GML. Create a new instance with the <ZOO.Format.GML>
+ *     constructor.  Supports the GML simple features profile.
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
+ZOO.Format.GML = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: schemaLocation
+   * {String} Schema location for a particular minor version.
+   */
+  schemaLocation: "http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",
+  /**
+   * Property: namespaces
+   * {Object} Mapping of namespace aliases to namespace URIs.
+   */
+  namespaces: {
+    ogr: "http://ogr.maptools.org/",
+    gml: "http://www.opengis.net/gml",
+    xlink: "http://www.w3.org/1999/xlink",
+    xsi: "http://www.w3.org/2001/XMLSchema-instance",
+    wfs: "http://www.opengis.net/wfs" // this is a convenience for reading wfs:FeatureCollection
+  },
+  /**
+   * Property: defaultPrefix
+   */
+  defaultPrefix: 'ogr',
+  /** 
+   * Property: collectionName
+   * {String} Name of featureCollection element.
+   */
+  collectionName: "FeatureCollection",
+  /*
+   * Property: featureName
+   * {String} Element name for features. Default is "sql_statement".
+   */
+  featureName: "sql_statement",
+  /**
+   * Property: geometryName
+   * {String} Name of geometry element.  Defaults to "geometryProperty".
+   */
+  geometryName: "geometryProperty",
+  /**
+   * Property: xy
+   * {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
+   * Changing is not recommended, a new Format should be instantiated.
+   */
+  xy: true,
+  /**
+   * Property: extractAttributes
+   * {Boolean} Could we extract attributes
+   */
+  extractAttributes: true,
+  /**
+   * Constructor: ZOO.Format.GML
+   * Create a new parser for GML.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
+  initialize: function(options) {
+    // compile regular expressions once instead of every time they are used
+    this.regExes = {
+      trimSpace: (/^\s*|\s*$/g),
+      removeSpace: (/\s*/g),
+      splitSpace: (/\s+/),
+      trimComma: (/\s*,\s*/g)
+    };
+    ZOO.Format.prototype.initialize.apply(this, [options]);
+  },
+  /**
+   * Method: read
+   * Read data from a string, and return a list of features. 
+   * 
+   * Parameters:
+   * data - {String} data to read/parse.
+   *
+   * Returns:
+   * {Array(<ZOO.Feature>)} An array of features.
+   */
+  read: function(data) {
+    this.features = [];
+    data = data.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "");
+    data = new XML(data);
+
+    var gmlns = Namespace(this.namespaces['gml']);
+    var featureNodes = data..gmlns::featureMember;
+    if (data.localName() == 'featureMember')
+      featureNodes = data;
+    var features = [];
+    for(var i=0,len=featureNodes.length(); i<len; i++) {
+      var feature = this.parseFeature(featureNodes[i]);
+      if(feature) {
+        features.push(feature);
+      }
+    }
+    return features;
+  },
+  /**
+   * Method: parseFeature
+   * This function is the core of the GML parsing code in ZOO.
+   *    It creates the geometries that are then attached to the returned
+   *    feature, and calls parseAttributes() to get attribute data out.
+   *    
+   * Parameters:
+   * node - {E4XElement} A GML feature node. 
+   */
+  parseFeature: function(node) {
+    // only accept one geometry per feature - look for highest "order"
+    var gmlns = Namespace(this.namespaces['gml']);
+    var order = ["MultiPolygon", "Polygon",
+                 "MultiLineString", "LineString",
+                 "MultiPoint", "Point", "Envelope", "Box"];
+    var type, nodeList, geometry, parser;
+    for(var i=0; i<order.length; ++i) {
+      type = order[i];
+      nodeList = node.descendants(QName(gmlns,type));
+      if (nodeList.length() > 0) {
+        var parser = this.parseGeometry[type.toLowerCase()];
+        if(parser) {
+          geometry = parser.apply(this, [nodeList[0]]);
+          if (this.internalProjection && this.externalProjection) {
+            geometry.transform(this.externalProjection, 
+                               this.internalProjection); 
+          }                       
+        }
+        // stop looking for different geometry types
+        break;
+      }
+    }
+    var attributes;
+    if(this.extractAttributes) {
+      attributes = this.parseAttributes(node);
+    }
+    var feature = new ZOO.Feature(geometry, attributes);
+    return feature;
+  },
+  /**
+   * Property: parseGeometry
+   * Properties of this object are the functions that parse geometries based
+   *     on their type.
+   */
+  parseGeometry: {
+    /**
+     * Method: parseGeometry.point
+     * Given a GML node representing a point geometry, create a ZOO
+     *     point geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A point geometry.
+     */
+    'point': function(node) {
+      /**
+       * Three coordinate variations to consider:
+       * 1) <gml:pos>x y z</gml:pos>
+       * 2) <gml:coordinates>x, y, z</gml:coordinates>
+       * 3) <gml:coord><gml:X>x</gml:X><gml:Y>y</gml:Y></gml:coord>
+       */
+      var nodeList, coordString;
+      var coords = [];
+      // look for <gml:pos>
+      var nodeList = node..*::pos;
+      if(nodeList.length() > 0) {
+        coordString = nodeList[0].toString();
+        coordString = coordString.replace(this.regExes.trimSpace, "");
+        coords = coordString.split(this.regExes.splitSpace);
+      }
+      // look for <gml:coordinates>
+      if(coords.length == 0) {
+        nodeList = node..*::coordinates;
+        if(nodeList.length() > 0) {
+          coordString = nodeList[0].toString();
+          coordString = coordString.replace(this.regExes.removeSpace,"");
+          coords = coordString.split(",");
+        }
+      }
+      // look for <gml:coord>
+      if(coords.length == 0) {
+        nodeList = node..*::coord;
+        if(nodeList.length() > 0) {
+          var xList = nodeList[0].*::X;
+          var yList = nodeList[0].*::Y;
+          if(xList.length() > 0 && yList.length() > 0)
+            coords = [xList[0].toString(),
+                      yList[0].toString()];
+        }
+      }
+      // preserve third dimension
+      if(coords.length == 2)
+        coords[2] = null;
+      if (this.xy)
+        return new ZOO.Geometry.Point(coords[0],coords[1],coords[2]);
+      else
+        return new ZOO.Geometry.Point(coords[1],coords[0],coords[2]);
+    },
+    /**
+     * Method: parseGeometry.multipoint
+     * Given a GML node representing a multipoint geometry, create a
+     *     ZOO multipoint geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     */
+    'multipoint': function(node) {
+      var nodeList = node..*::Point;
+      var components = [];
+      if(nodeList.length() > 0) {
+        var point;
+        for(var i=0, len=nodeList.length(); i<len; ++i) {
+          point = this.parseGeometry.point.apply(this, [nodeList[i]]);
+          if(point)
+            components.push(point);
+        }
+      }
+      return new ZOO.Geometry.MultiPoint(components);
+    },
+    /**
+     * Method: parseGeometry.linestring
+     * Given a GML node representing a linestring geometry, create a
+     *     ZOO linestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A linestring geometry.
+     */
+    'linestring': function(node, ring) {
+      /**
+       * Two coordinate variations to consider:
+       * 1) <gml:posList dimension="d">x0 y0 z0 x1 y1 z1</gml:posList>
+       * 2) <gml:coordinates>x0, y0, z0 x1, y1, z1</gml:coordinates>
+       */
+      var nodeList, coordString;
+      var coords = [];
+      var points = [];
+      // look for <gml:posList>
+      nodeList = node..*::posList;
+      if(nodeList.length() > 0) {
+        coordString = nodeList[0].toString();
+        coordString = coordString.replace(this.regExes.trimSpace, "");
+        coords = coordString.split(this.regExes.splitSpace);
+        var dim = parseInt(nodeList[0].@dimension);
+        var j, x, y, z;
+        for(var i=0; i<coords.length/dim; ++i) {
+          j = i * dim;
+          x = coords[j];
+          y = coords[j+1];
+          z = (dim == 2) ? null : coords[j+2];
+          if (this.xy)
+            points.push(new ZOO.Geometry.Point(x, y, z));
+          else
+            points.push(new Z0O.Geometry.Point(y, x, z));
+        }
+      }
+      // look for <gml:coordinates>
+      if(coords.length == 0) {
+        nodeList = node..*::coordinates;
+        if(nodeList.length() > 0) {
+          coordString = nodeList[0].toString();
+          coordString = coordString.replace(this.regExes.trimSpace,"");
+          coordString = coordString.replace(this.regExes.trimComma,",");
+          var pointList = coordString.split(this.regExes.splitSpace);
+          for(var i=0; i<pointList.length; ++i) {
+            coords = pointList[i].split(",");
+            if(coords.length == 2)
+              coords[2] = null;
+            if (this.xy)
+              points.push(new ZOO.Geometry.Point(coords[0],coords[1],coords[2]));
+            else
+              points.push(new ZOO.Geometry.Point(coords[1],coords[0],coords[2]));
+          }
+        }
+      }
+      var line = null;
+      if(points.length != 0) {
+        if(ring)
+          line = new ZOO.Geometry.LinearRing(points);
+        else
+          line = new ZOO.Geometry.LineString(points);
+      }
+      return line;
+    },
+    /**
+     * Method: parseGeometry.multilinestring
+     * Given a GML node representing a multilinestring geometry, create a
+     *     ZOO multilinestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiLineString>} A multilinestring geometry.
+     */
+    'multilinestring': function(node) {
+      var nodeList = node..*::LineString;
+      var components = [];
+      if(nodeList.length() > 0) {
+        var line;
+        for(var i=0, len=nodeList.length(); i<len; ++i) {
+          line = this.parseGeometry.linestring.apply(this, [nodeList[i]]);
+          if(point)
+            components.push(point);
+        }
+      }
+      return new ZOO.Geometry.MultiLineString(components);
+    },
+    /**
+     * Method: parseGeometry.polygon
+     * Given a GML node representing a polygon geometry, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
+    'polygon': function(node) {
+      nodeList = node..*::LinearRing;
+      var components = [];
+      if(nodeList.length() > 0) {
+        // this assumes exterior ring first, inner rings after
+        var ring;
+        for(var i=0, len = nodeList.length(); i<len; ++i) {
+          ring = this.parseGeometry.linestring.apply(this,[nodeList[i], true]);
+          if(ring)
+            components.push(ring);
+        }
+      }
+      return new ZOO.Geometry.Polygon(components);
+    },
+    /**
+     * Method: parseGeometry.multipolygon
+     * Given a GML node representing a multipolygon geometry, create a
+     *     ZOO multipolygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPolygon>} A multipolygon geometry.
+     */
+    'multipolygon': function(node) {
+      var nodeList = node..*::Polygon;
+      var components = [];
+      if(nodeList.length() > 0) {
+        var polygon;
+        for(var i=0, len=nodeList.length(); i<len; ++i) {
+          polygon = this.parseGeometry.polygon.apply(this, [nodeList[i]]);
+          if(polygon)
+            components.push(polygon);
+        }
+      }
+      return new ZOO.Geometry.MultiPolygon(components);
+    },
+    /**
+     * Method: parseGeometry.envelope
+     * Given a GML node representing an envelope, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
+    'envelope': function(node) {
+      var components = [];
+      var coordString;
+      var envelope;
+      var lpoint = node..*::lowerCorner;
+      if (lpoint.length() > 0) {
+        var coords = [];
+        if(lpoint.length() > 0) {
+          coordString = lpoint[0].toString();
+          coordString = coordString.replace(this.regExes.trimSpace, "");
+          coords = coordString.split(this.regExes.splitSpace);
+        }
+        if(coords.length == 2)
+          coords[2] = null;
+        if (this.xy)
+          var lowerPoint = new ZOO.Geometry.Point(coords[0], coords[1],coords[2]);
+        else
+          var lowerPoint = new ZOO.Geometry.Point(coords[1], coords[0],coords[2]);
+      }
+      var upoint = node..*::upperCorner;
+      if (upoint.length() > 0) {
+        var coords = [];
+        if(upoint.length > 0) {
+          coordString = upoint[0].toString();
+          coordString = coordString.replace(this.regExes.trimSpace, "");
+          coords = coordString.split(this.regExes.splitSpace);
+        }
+        if(coords.length == 2)
+          coords[2] = null;
+        if (this.xy)
+          var upperPoint = new ZOO.Geometry.Point(coords[0], coords[1],coords[2]);
+        else
+          var upperPoint = new ZOO.Geometry.Point(coords[1], coords[0],coords[2]);
+      }
+      if (lowerPoint && upperPoint) {
+        components.push(new ZOO.Geometry.Point(lowerPoint.x, lowerPoint.y));
+        components.push(new ZOO.Geometry.Point(upperPoint.x, lowerPoint.y));
+        components.push(new ZOO.Geometry.Point(upperPoint.x, upperPoint.y));
+        components.push(new ZOO.Geometry.Point(lowerPoint.x, upperPoint.y));
+        components.push(new ZOO.Geometry.Point(lowerPoint.x, lowerPoint.y));
+        var ring = new ZOO.Geometry.LinearRing(components);
+        envelope = new ZOO.Geometry.Polygon([ring]);
+      }
+      return envelope;
+    }
+  },
+  /**
+   * Method: parseAttributes
+   *
+   * Parameters:
+   * node - {<E4XElement>}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
+  parseAttributes: function(node) {
+    var attributes = {};
+    // assume attributes are children of the first type 1 child
+    var childNode = node.*::*[0];
+    var child, grandchildren;
+    var children = childNode.*::*;
+    for(var i=0, len=children.length(); i<len; ++i) {
+      child = children[i];
+      grandchildren = child..*::*;
+      if(grandchildren.length() == 1) {
+        var name = child.localName();
+        var value = child.toString();
+        if (value) {
+          value = value.replace(this.regExes.trimSpace, "");
+          attributes[name] = value;
+        } else
+          attributes[name] = null;
+      }
+    }
+    return attributes;
+  },
+  /**
+   * Method: write
+   * Generate a GML document string given a list of features. 
+   * 
+   * Parameters:
+   * features - {Array(<ZOO.Feature>)} List of features to
+   *     serialize into a string.
+   *
+   * Returns:
+   * {String} A string representing the GML document.
+   */
+  write: function(features) {
+    if(!(features instanceof Array)) {
+      features = [features];
+    }
+    var pfx = this.defaultPrefix;
+    var name = pfx+':'+this.collectionName;
+    var gml = new XML('<'+name+' xmlns:'+pfx+'="'+this.namespaces[pfx]+'" xmlns:gml="'+this.namespaces['gml']+'" xmlns:xsi="'+this.namespaces['xsi']+'" xsi:schemaLocation="'+this.schemaLocation+'"></'+name+'>');
+    for(var i=0; i<features.length; i++) {
+      gml.*::*[i] = this.createFeature(features[i]);
+    }
+    return gml.toXMLString();
+  },
+  /** 
+   * Method: createFeature
+   * Accept an ZOO.Feature, and build a GML node for it.
+   *
+   * Parameters:
+   * feature - {<ZOO.Feature>} The feature to be built as GML.
+   *
+   * Returns:
+   * {E4XElement} A node reprensting the feature in GML.
+   */
+  createFeature: function(feature) {
+    var pfx = this.defaultPrefix;
+    var name = pfx+':'+this.featureName;
+    var fid = feature.fid || feature.id;
+    var gml = new XML('<gml:featureMember xmlns:gml="'+this.namespaces['gml']+'"><'+name+' xmlns:'+pfx+'="'+this.namespaces[pfx]+'" fid="'+fid+'"></'+name+'></gml:featureMember>');
+    var geometry = feature.geometry;
+    gml.*::*[0].*::* = this.buildGeometryNode(geometry);
+    for(var attr in feature.attributes) {
+      var attrNode = new XML('<'+pfx+':'+attr+' xmlns:'+pfx+'="'+this.namespaces[pfx]+'">'+feature.attributes[attr]+'</'+pfx+':'+attr+'>');
+      gml.*::*[0].appendChild(attrNode);
+    }
+    return gml;
+  },
+  /**
+   * Method: buildGeometryNode
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} The geometry to be built as GML.
+   *
+   * Returns:
+   * {E4XElement} A node reprensting the geometry in GML.
+   */
+  buildGeometryNode: function(geometry) {
+    if (this.externalProjection && this.internalProjection) {
+      geometry = geometry.clone();
+      geometry.transform(this.internalProjection, 
+          this.externalProjection);
+    }    
+    var className = geometry.CLASS_NAME;
+    var type = className.substring(className.lastIndexOf(".") + 1);
+    var builder = this.buildGeometry[type.toLowerCase()];
+    var pfx = this.defaultPrefix;
+    var name = pfx+':'+this.geometryName;
+    var gml = new XML('<'+name+' xmlns:'+pfx+'="'+this.namespaces[pfx]+'"></'+name+'>');
+    if (builder)
+      gml.*::* = builder.apply(this, [geometry]);
+    return gml;
+  },
+  /**
+   * Property: buildGeometry
+   * Object containing methods to do the actual geometry node building
+   *     based on geometry type.
+   */
+  buildGeometry: {
+    /**
+     * Method: buildGeometry.point
+     * Given a ZOO point geometry, create a GML point.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A point geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML point node.
+     */
+    'point': function(geometry) {
+      var gml = new XML('<gml:Point xmlns:gml="'+this.namespaces['gml']+'"></gml:Point>');
+      gml.*::*[0] = this.buildCoordinatesNode(geometry);
+      return gml;
+    },
+    /**
+     * Method: buildGeometry.multipoint
+     * Given a ZOO multipoint geometry, create a GML multipoint.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multipoint node.
+     */
+    'multipoint': function(geometry) {
+      var gml = new XML('<gml:MultiPoint xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiPoint>');
+      var points = geometry.components;
+      var pointMember;
+      for(var i=0; i<points.length; i++) { 
+        pointMember = new XML('<gml:pointMember xmlns:gml="'+this.namespaces['gml']+'"></gml:pointMember>');
+        pointMember.*::* = this.buildGeometry.point.apply(this,[points[i]]);
+        gml.*::*[i] = pointMember;
+      }
+      return gml;            
+    },
+    /**
+     * Method: buildGeometry.linestring
+     * Given a ZOO linestring geometry, create a GML linestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LineString>} A linestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML linestring node.
+     */
+    'linestring': function(geometry) {
+      var gml = new XML('<gml:LineString xmlns:gml="'+this.namespaces['gml']+'"></gml:LineString>');
+      gml.*::*[0] = this.buildCoordinatesNode(geometry);
+      return gml;
+    },
+    /**
+     * Method: buildGeometry.multilinestring
+     * Given a ZOO multilinestring geometry, create a GML
+     *     multilinestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiLineString>} A multilinestring
+     *     geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multilinestring node.
+     */
+    'multilinestring': function(geometry) {
+      var gml = new XML('<gml:MultiLineString xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiLineString>');
+      var lines = geometry.components;
+      var lineMember;
+      for(var i=0; i<lines.length; i++) { 
+        lineMember = new XML('<gml:lineStringMember xmlns:gml="'+this.namespaces['gml']+'"></gml:lineStringMember>');
+        lineMember.*::* = this.buildGeometry.linestring.apply(this,[lines[i]]);
+        gml.*::*[i] = lineMember;
+      }
+      return gml;            
+    },
+    /**
+     * Method: buildGeometry.linearring
+     * Given a ZOO linearring geometry, create a GML linearring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LinearRing>} A linearring geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML linearring node.
+     */
+    'linearring': function(geometry) {
+      var gml = new XML('<gml:LinearRing xmlns:gml="'+this.namespaces['gml']+'"></gml:LinearRing>');
+      gml.*::*[0] = this.buildCoordinatesNode(geometry);
+      return gml;
+    },
+    /**
+     * Method: buildGeometry.polygon
+     * Given an ZOO polygon geometry, create a GML polygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Polygon>} A polygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML polygon node.
+     */
+    'polygon': function(geometry) {
+      var gml = new XML('<gml:Polygon xmlns:gml="'+this.namespaces['gml']+'"></gml:Polygon>');
+      var rings = geometry.components;
+      var ringMember, type;
+      for(var i=0; i<rings.length; ++i) {
+        type = (i==0) ? "outerBoundaryIs" : "innerBoundaryIs";
+        var ringMember = new XML('<gml:'+type+' xmlns:gml="'+this.namespaces['gml']+'"></gml:'+type+'>');
+        ringMember.*::* = this.buildGeometry.linearring.apply(this,[rings[i]]);
+        gml.*::*[i] = ringMember;
+      }
+      return gml;
+    },
+    /**
+     * Method: buildGeometry.multipolygon
+     * Given a ZOO multipolygon geometry, create a GML multipolygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPolygon>} A multipolygon
+     *     geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multipolygon node.
+     */
+    'multipolygon': function(geometry) {
+      var gml = new XML('<gml:MultiPolygon xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiPolygon>');
+      var polys = geometry.components;
+      var polyMember;
+      for(var i=0; i<polys.length; i++) { 
+        polyMember = new XML('<gml:polygonMember xmlns:gml="'+this.namespaces['gml']+'"></gml:polygonMember>');
+        polyMember.*::* = this.buildGeometry.polygon.apply(this,[polys[i]]);
+        gml.*::*[i] = polyMember;
+      }
+      return gml;            
+    }
+  },
+  /**
+   * Method: buildCoordinatesNode
+   * builds the coordinates XmlNode
+   * (code)
+   * <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
+   * (end)
+   * Parameters: 
+   * geometry - {<ZOO.Geometry>} 
+   *
+   * Returns:
+   * {E4XElement} created E4XElement
+   */
+  buildCoordinatesNode: function(geometry) {
+    var parts = [];
+    if(geometry instanceof ZOO.Bounds){
+      parts.push(geometry.left + "," + geometry.bottom);
+      parts.push(geometry.right + "," + geometry.top);
+    } else {
+      var points = (geometry.components) ? geometry.components : [geometry];
+      for(var i=0; i<points.length; i++) {
+        parts.push(points[i].x + "," + points[i].y);                
+      }            
+    }
+    return new XML('<gml:coordinates xmlns:gml="'+this.namespaces['gml']+'" decimal="." cs=", " ts=" ">'+parts.join(" ")+'</gml:coordinates>');
+  },
+  CLASS_NAME: 'ZOO.Format.GML'
+});
+/**
+ * Class: ZOO.Format.WPS
+ * Read/Write WPS. Create a new instance with the <ZOO.Format.WPS>
+ *     constructor. Supports only parseExecuteResponse.
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
+ZOO.Format.WPS = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: schemaLocation
+   * {String} Schema location for a particular minor version.
+   */
+  schemaLocation: "http://www.opengis.net/wps/1.0.0/../wpsExecute_request.xsd",
+  /**
+   * Property: namespaces
+   * {Object} Mapping of namespace aliases to namespace URIs.
+   */
+  namespaces: {
+    ows: "http://www.opengis.net/ows/1.1",
+    wps: "http://www.opengis.net/wps/1.0.0",
+    xlink: "http://www.w3.org/1999/xlink",
+    xsi: "http://www.w3.org/2001/XMLSchema-instance",
+  },
+  /**
+   * Method: read
+   *
+   * Parameters:
+   * data - {String} A WPS xml document
+   *
+   * Returns:
+   * {Object} Execute response.
+   */
+  read:function(data) {
+    data = data.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "");
+    data = new XML(data);
+    switch (data.localName()) {
+      case 'ExecuteResponse':
+        return this.parseExecuteResponse(data);
+      default:
+        return null;
+    }
+  },
+  /**
+   * Method: parseExecuteResponse
+   *
+   * Parameters:
+   * node - {E4XElement} A WPS ExecuteResponse document
+   *
+   * Returns:
+   * {Object} Execute response.
+   */
+  parseExecuteResponse: function(node) {
+    var outputs = node.*::ProcessOutputs.*::Output;
+    if (outputs.length() > 0) {
+      var res=[];
+      for(var i=0;i<outputs.length();i++){
+        var data = outputs[i].*::Data.*::*[0];
+	if(!data){
+          data = outputs[i].*::Reference;
+	}
+	var builder = this.parseData[data.localName().toLowerCase()];
+	if (builder)
+	  res.push(builder.apply(this,[data]));
+	else
+	  res.push(null);
+      }
+      return res.length>1?res:res[0];
+    } else
+      return null;
+  },
+  /**
+   * Property: parseData
+   * Object containing methods to analyse data response.
+   */
+  parseData: {
+    /**
+     * Method: parseData.complexdata
+     * Given an Object representing the WPS complex data response.
+     *
+     * Parameters:
+     * node - {E4XElement} A WPS node.
+     *
+     * Returns:
+     * {Object} A WPS complex data response.
+     */
+    'complexdata': function(node) {
+      var result = {value:node.toString()};
+      if (node.@mimeType.length()>0)
+        result.mimeType = node.@mimeType;
+      if (node.@encoding.length()>0)
+        result.encoding = node.@encoding;
+      if (node.@schema.length()>0)
+        result.schema = node.@schema;
+      return result;
+    },
+    /**
+     * Method: parseData.literaldata
+     * Given an Object representing the WPS literal data response.
+     *
+     * Parameters:
+     * node - {E4XElement} A WPS node.
+     *
+     * Returns:
+     * {Object} A WPS literal data response.
+     */
+    'literaldata': function(node) {
+      var result = {value:node.toString()};
+      if (node.@dataType.length()>0)
+        result.dataType = node.@dataType;
+      if (node.@uom.length()>0)
+        result.uom = node.@uom;
+      return result;
+    },
+    /**
+     * Method: parseData.reference
+     * Given an Object representing the WPS reference response.
+     *
+     * Parameters:
+     * node - {E4XElement} A WPS node.
+     *
+     * Returns:
+     * {Object} A WPS reference response.
+     */
+    'reference': function(node) {
+      var result = {type:'reference',value:node.@href};
+      return result;
+    }
+  },
+  CLASS_NAME: 'ZOO.Format.WPS'
+});
+
+/**
+ * Class: ZOO.Feature
+ * Vector features use the ZOO.Geometry classes as geometry description.
+ * They have an 'attributes' property, which is the data object
+ */
+ZOO.Feature = ZOO.Class({
+  /** 
+   * Property: fid 
+   * {String} 
+   */
+  fid: null,
+  /** 
+   * Property: geometry 
+   * {<ZOO.Geometry>} 
+   */
+  geometry: null,
+  /** 
+   * Property: attributes 
+   * {Object} This object holds arbitrary properties that describe the
+   *     feature.
+   */
+  attributes: null,
+  /**
+   * Property: bounds
+   * {<ZOO.Bounds>} The box bounding that feature's geometry, that
+   *     property can be set by an <ZOO.Format> object when
+   *     deserializing the feature, so in most cases it represents an
+   *     information set by the server. 
+   */
+  bounds: null,
+  /** 
+   * Constructor: ZOO.Feature
+   * Create a vector feature. 
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} The geometry that this feature
+   *     represents.
+   * attributes - {Object} An optional object that will be mapped to the
+   *     <attributes> property. 
+   */
+  initialize: function(geometry, attributes) {
+    this.geometry = geometry ? geometry : null;
+    this.attributes = {};
+    if (attributes)
+      this.attributes = ZOO.extend(this.attributes,attributes);
+  },
+  /** 
+   * Method: destroy
+   * nullify references to prevent circular references and memory leaks
+   */
+  destroy: function() {
+    this.geometry = null;
+  },
+  /**
+   * Method: clone
+   * Create a clone of this vector feature.  Does not set any non-standard
+   *     properties.
+   *
+   * Returns:
+   * {<ZOO.Feature>} An exact clone of this vector feature.
+   */
+  clone: function () {
+    return new ZOO.Feature(this.geometry ? this.geometry.clone() : null,
+            this.attributes);
+  },
+  /**
+   * Method: move
+   * Moves the feature and redraws it at its new location
+   *
+   * Parameters:
+   * x - {Float}
+   * y - {Float}
+   */
+  move: function(x, y) {
+    if(!this.geometry.move)
+      return;
+
+    this.geometry.move(x,y);
+    return this.geometry;
+  },
+  CLASS_NAME: 'ZOO.Feature'
+});
+
+/**
+ * Class: ZOO.Geometry
+ * A Geometry is a description of a geographic object. Create an instance
+ * of this class with the <ZOO.Geometry> constructor. This is a base class,
+ * typical geometry types are described by subclasses of this class.
+ */
+ZOO.Geometry = ZOO.Class({
+  /**
+   * Property: id
+   * {String} A unique identifier for this geometry.
+   */
+  id: null,
+  /**
+   * Property: parent
+   * {<ZOO.Geometry>}This is set when a Geometry is added as component
+   * of another geometry
+   */
+  parent: null,
+  /**
+   * Property: bounds 
+   * {<ZOO.Bounds>} The bounds of this geometry
+   */
+  bounds: null,
+  /**
+   * Constructor: ZOO.Geometry
+   * Creates a geometry object.  
+   */
+  initialize: function() {
+    //generate unique id
+  },
+  /**
+   * Method: destroy
+   * Destroy this geometry.
+   */
+  destroy: function() {
+    this.id = null;
+    this.bounds = null;
+  },
+  /**
+   * Method: clone
+   * Create a clone of this geometry.  Does not set any non-standard
+   *     properties of the cloned geometry.
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} An exact clone of this geometry.
+   */
+  clone: function() {
+    return new ZOO.Geometry();
+  },
+  /**
+   * Method: extendBounds
+   * Extend the existing bounds to include the new bounds. 
+   * If geometry's bounds is not yet set, then set a new Bounds.
+   * 
+   * Parameters:
+   * newBounds - {<ZOO.Bounds>} 
+   */
+  extendBounds: function(newBounds){
+    var bounds = this.getBounds();
+    if (!bounds)
+      this.setBounds(newBounds);
+    else
+      this.bounds.extend(newBounds);
+  },
+  /**
+   * Set the bounds for this Geometry.
+   * 
+   * Parameters:
+   * bounds - {<ZOO.Bounds>} 
+   */
+  setBounds: function(bounds) {
+    if (bounds)
+      this.bounds = bounds.clone();
+  },
+  /**
+   * Method: clearBounds
+   * Nullify this components bounds and that of its parent as well.
+   */
+  clearBounds: function() {
+    this.bounds = null;
+    if (this.parent)
+      this.parent.clearBounds();
+  },
+  /**
+   * Method: getBounds
+   * Get the bounds for this Geometry. If bounds is not set, it 
+   * is calculated again, this makes queries faster.
+   * 
+   * Returns:
+   * {<ZOO.Bounds>}
+   */
+  getBounds: function() {
+    if (this.bounds == null) {
+      this.calculateBounds();
+    }
+    return this.bounds;
+  },
+  /** 
+   * Method: calculateBounds
+   * Recalculate the bounds for the geometry. 
+   */
+  calculateBounds: function() {
+    // This should be overridden by subclasses.
+    return this.bounds;
+  },
+  distanceTo: function(geometry, options) {
+  },
+  getVertices: function(nodes) {
+  },
+  getLength: function() {
+    return 0.0;
+  },
+  getArea: function() {
+    return 0.0;
+  },
+  getCentroid: function() {
+    return null;
+  },
+  /**
+   * Method: toString
+   * Returns the Well-Known Text representation of a geometry
+   *
+   * Returns:
+   * {String} Well-Known Text
+   */
+  toString: function() {
+    return ZOO.Format.WKT.prototype.write(
+        new ZOO.Feature(this)
+    );
+  },
+  CLASS_NAME: 'ZOO.Geometry'
+});
+/**
+ * Function: ZOO.Geometry.fromWKT
+ * Generate a geometry given a Well-Known Text string.
+ *
+ * Parameters:
+ * wkt - {String} A string representing the geometry in Well-Known Text.
+ *
+ * Returns:
+ * {<ZOO.Geometry>} A geometry of the appropriate class.
+ */
+ZOO.Geometry.fromWKT = function(wkt) {
+  var format = arguments.callee.format;
+  if(!format) {
+    format = new ZOO.Format.WKT();
+    arguments.callee.format = format;
+  }
+  var geom;
+  var result = format.read(wkt);
+  if(result instanceof ZOO.Feature) {
+    geom = result.geometry;
+  } else if(result instanceof Array) {
+    var len = result.length;
+    var components = new Array(len);
+    for(var i=0; i<len; ++i) {
+      components[i] = result[i].geometry;
+    }
+    geom = new ZOO.Geometry.Collection(components);
+  }
+  return geom;
+};
+ZOO.Geometry.segmentsIntersect = function(seg1, seg2, options) {
+  var point = options && options.point;
+  var tolerance = options && options.tolerance;
+  var intersection = false;
+  var x11_21 = seg1.x1 - seg2.x1;
+  var y11_21 = seg1.y1 - seg2.y1;
+  var x12_11 = seg1.x2 - seg1.x1;
+  var y12_11 = seg1.y2 - seg1.y1;
+  var y22_21 = seg2.y2 - seg2.y1;
+  var x22_21 = seg2.x2 - seg2.x1;
+  var d = (y22_21 * x12_11) - (x22_21 * y12_11);
+  var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);
+  var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);
+  if(d == 0) {
+    // parallel
+    if(n1 == 0 && n2 == 0) {
+      // coincident
+      intersection = true;
+    }
+  } else {
+    var along1 = n1 / d;
+    var along2 = n2 / d;
+    if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {
+      // intersect
+      if(!point) {
+        intersection = true;
+      } else {
+        // calculate the intersection point
+        var x = seg1.x1 + (along1 * x12_11);
+        var y = seg1.y1 + (along1 * y12_11);
+        intersection = new ZOO.Geometry.Point(x, y);
+      }
+    }
+  }
+  if(tolerance) {
+    var dist;
+    if(intersection) {
+      if(point) {
+        var segs = [seg1, seg2];
+        var seg, x, y;
+        // check segment endpoints for proximity to intersection
+        // set intersection to first endpoint within the tolerance
+        outer: for(var i=0; i<2; ++i) {
+          seg = segs[i];
+          for(var j=1; j<3; ++j) {
+            x = seg["x" + j];
+            y = seg["y" + j];
+            dist = Math.sqrt(
+                Math.pow(x - intersection.x, 2) +
+                Math.pow(y - intersection.y, 2)
+            );
+            if(dist < tolerance) {
+              intersection.x = x;
+              intersection.y = y;
+              break outer;
+            }
+          }
+        }
+      }
+    } else {
+      // no calculated intersection, but segments could be within
+      // the tolerance of one another
+      var segs = [seg1, seg2];
+      var source, target, x, y, p, result;
+      // check segment endpoints for proximity to intersection
+      // set intersection to first endpoint within the tolerance
+      outer: for(var i=0; i<2; ++i) {
+        source = segs[i];
+        target = segs[(i+1)%2];
+        for(var j=1; j<3; ++j) {
+          p = {x: source["x"+j], y: source["y"+j]};
+          result = ZOO.Geometry.distanceToSegment(p, target);
+          if(result.distance < tolerance) {
+            if(point) {
+              intersection = new ZOO.Geometry.Point(p.x, p.y);
+            } else {
+              intersection = true;
+            }
+            break outer;
+          }
+        }
+      }
+    }
+  }
+  return intersection;
+};
+ZOO.Geometry.distanceToSegment = function(point, segment) {
+  var x0 = point.x;
+  var y0 = point.y;
+  var x1 = segment.x1;
+  var y1 = segment.y1;
+  var x2 = segment.x2;
+  var y2 = segment.y2;
+  var dx = x2 - x1;
+  var dy = y2 - y1;
+  var along = ((dx * (x0 - x1)) + (dy * (y0 - y1))) /
+               (Math.pow(dx, 2) + Math.pow(dy, 2));
+  var x, y;
+  if(along <= 0.0) {
+    x = x1;
+    y = y1;
+  } else if(along >= 1.0) {
+    x = x2;
+    y = y2;
+  } else {
+    x = x1 + along * dx;
+    y = y1 + along * dy;
+  }
+  return {
+    distance: Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)),
+    x: x, y: y
+  };
+};
+/**
+ * Class: ZOO.Geometry.Collection
+ * A Collection is exactly what it sounds like: A collection of different 
+ * Geometries. These are stored in the local parameter <components> (which
+ * can be passed as a parameter to the constructor). 
+ * 
+ * As new geometries are added to the collection, they are NOT cloned. 
+ * When removing geometries, they need to be specified by reference (ie you 
+ * have to pass in the *exact* geometry to be removed).
+ * 
+ * The <getArea> and <getLength> functions here merely iterate through
+ * the components, summing their respective areas and lengths.
+ *
+ * Create a new instance with the <ZOO.Geometry.Collection> constructor.
+ *
+ * Inerhits from:
+ *  - <ZOO.Geometry> 
+ */
+ZOO.Geometry.Collection = ZOO.Class(ZOO.Geometry, {
+  /**
+   * Property: components
+   * {Array(<ZOO.Geometry>)} The component parts of this geometry
+   */
+  components: null,
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of
+   * components that the collection can include.  A null value means the
+   * component types are not restricted.
+   */
+  componentTypes: null,
+  /**
+   * Constructor: ZOO.Geometry.Collection
+   * Creates a Geometry Collection -- a list of geoms.
+   *
+   * Parameters: 
+   * components - {Array(<ZOO.Geometry>)} Optional array of geometries
+   *
+   */
+  initialize: function (components) {
+    ZOO.Geometry.prototype.initialize.apply(this, arguments);
+    this.components = [];
+    if (components != null) {
+      this.addComponents(components);
+    }
+  },
+  /**
+   * Method: destroy
+   * Destroy this geometry.
+   */
+  destroy: function () {
+    this.components.length = 0;
+    this.components = null;
+  },
+  /**
+   * Method: clone
+   * Clone this geometry.
+   *
+   * Returns:
+   * {<ZOO.Geometry.Collection>} An exact clone of this collection
+   */
+  clone: function() {
+    var geometry = eval("new " + this.CLASS_NAME + "()");
+    for(var i=0, len=this.components.length; i<len; i++) {
+      geometry.addComponent(this.components[i].clone());
+    }
+    return geometry;
+  },
+  /**
+   * Method: getComponentsString
+   * Get a string representing the components for this collection
+   * 
+   * Returns:
+   * {String} A string representation of the components of this geometry
+   */
+  getComponentsString: function(){
+    var strings = [];
+    for(var i=0, len=this.components.length; i<len; i++) {
+      strings.push(this.components[i].toShortString()); 
+    }
+    return strings.join(",");
+  },
+  /**
+   * Method: calculateBounds
+   * Recalculate the bounds by iterating through the components and 
+   * calling extendBounds() on each item.
+   */
+  calculateBounds: function() {
+    this.bounds = null;
+    if ( this.components && this.components.length > 0) {
+      this.setBounds(this.components[0].getBounds());
+      for (var i=1, len=this.components.length; i<len; i++) {
+        this.extendBounds(this.components[i].getBounds());
+      }
+    }
+    return this.bounds
+  },
+  /**
+   * APIMethod: addComponents
+   * Add components to this geometry.
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry>)} An array of geometries to add
+   */
+  addComponents: function(components){
+    if(!(components instanceof Array))
+      components = [components];
+    for(var i=0, len=components.length; i<len; i++) {
+      this.addComponent(components[i]);
+    }
+  },
+  /**
+   * Method: addComponent
+   * Add a new component (geometry) to the collection.  If this.componentTypes
+   * is set, then the component class name must be in the componentTypes array.
+   *
+   * The bounds cache is reset.
+   * 
+   * Parameters:
+   * component - {<ZOO.Geometry>} A geometry to add
+   * index - {int} Optional index into the array to insert the component
+   *
+   * Returns:
+   * {Boolean} The component geometry was successfully added
+   */
+  addComponent: function(component, index) {
+    var added = false;
+    if(component) {
+      if(this.componentTypes == null ||
+          (ZOO.indexOf(this.componentTypes,
+                       component.CLASS_NAME) > -1)) {
+        if(index != null && (index < this.components.length)) {
+          var components1 = this.components.slice(0, index);
+          var components2 = this.components.slice(index, 
+                                                  this.components.length);
+          components1.push(component);
+          this.components = components1.concat(components2);
+        } else {
+          this.components.push(component);
+        }
+        component.parent = this;
+        this.clearBounds();
+        added = true;
+      }
+    }
+    return added;
+  },
+  /**
+   * Method: removeComponents
+   * Remove components from this geometry.
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry>)} The components to be removed
+   */
+  removeComponents: function(components) {
+    if(!(components instanceof Array))
+      components = [components];
+    for(var i=components.length-1; i>=0; --i) {
+      this.removeComponent(components[i]);
+    }
+  },
+  /**
+   * Method: removeComponent
+   * Remove a component from this geometry.
+   *
+   * Parameters:
+   * component - {<ZOO.Geometry>} 
+   */
+  removeComponent: function(component) {      
+    ZOO.removeItem(this.components, component);
+    // clearBounds() so that it gets recalculated on the next call
+    // to this.getBounds();
+    this.clearBounds();
+  },
+  /**
+   * Method: getLength
+   * Calculate the length of this geometry
+   *
+   * Returns:
+   * {Float} The length of the geometry
+   */
+  getLength: function() {
+    var length = 0.0;
+    for (var i=0, len=this.components.length; i<len; i++) {
+      length += this.components[i].getLength();
+    }
+    return length;
+  },
+  /**
+   * APIMethod: getArea
+   * Calculate the area of this geometry. Note how this function is 
+   * overridden in <ZOO.Geometry.Polygon>.
+   *
+   * Returns:
+   * {Float} The area of the collection by summing its parts
+   */
+  getArea: function() {
+    var area = 0.0;
+    for (var i=0, len=this.components.length; i<len; i++) {
+      area += this.components[i].getArea();
+    }
+    return area;
+  },
+  /** 
+   * APIMethod: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate geodesic area of the geometry in square meters.
+   */
+  getGeodesicArea: function(projection) {
+    var area = 0.0;
+    for(var i=0, len=this.components.length; i<len; i++) {
+      area += this.components[i].getGeodesicArea(projection);
+    }
+    return area;
+  },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the collection
+   */
+  getCentroid: function() {
+    return this.components.length && this.components[0].getCentroid();
+  },
+  /**
+   * Method: getGeodesicLength
+   * Calculate the approximate length of the geometry were it projected onto
+   *     the earth.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Returns:
+   * {Float} The appoximate geodesic length of the geometry in meters.
+   */
+  getGeodesicLength: function(projection) {
+    var length = 0.0;
+    for(var i=0, len=this.components.length; i<len; i++) {
+      length += this.components[i].getGeodesicLength(projection);
+    }
+    return length;
+  },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
+  move: function(x, y) {
+    for(var i=0, len=this.components.length; i<len; i++) {
+      this.components[i].move(x, y);
+    }
+  },
+  /**
+   * Method: rotate
+   * Rotate a geometry around some origin
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
+  rotate: function(angle, origin) {
+    for(var i=0, len=this.components.length; i<len; ++i) {
+      this.components[i].rotate(angle, origin);
+    }
+  },
+  /**
+   * Method: resize
+   * Resize a geometry relative to some origin.  Use this method to apply
+   *     a uniform scaling to a geometry.
+   *
+   * Parameters:
+   * scale - {Float} Factor by which to scale the geometry.  A scale of 2
+   *                 doubles the size of the geometry in each dimension
+   *                 (lines, for example, will be twice as long, and polygons
+   *                 will have four times the area).
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
+  resize: function(scale, origin, ratio) {
+    for(var i=0; i<this.components.length; ++i) {
+      this.components[i].resize(scale, origin, ratio);
+    }
+    return this;
+  },
+  distanceTo: function(geometry, options) {
+    var edge = !(options && options.edge === false);
+    var details = edge && options && options.details;
+    var result, best;
+    var min = Number.POSITIVE_INFINITY;
+    for(var i=0, len=this.components.length; i<len; ++i) {
+      result = this.components[i].distanceTo(geometry, options);
+      distance = details ? result.distance : result;
+      if(distance < min) {
+        min = distance;
+        best = result;
+        if(min == 0)
+          break;
+      }
+    }
+    return best;
+  },
+  /** 
+   * Method: equals
+   * Determine whether another geometry is equivalent to this one.  Geometries
+   *     are considered equivalent if all components have the same coordinates.
+   * 
+   * Parameters:
+   * geom - {<ZOO.Geometry>} The geometry to test. 
+   *
+   * Returns:
+   * {Boolean} The supplied geometry is equivalent to this geometry.
+   */
+  equals: function(geometry) {
+    var equivalent = true;
+    if(!geometry || !geometry.CLASS_NAME ||
+       (this.CLASS_NAME != geometry.CLASS_NAME))
+      equivalent = false;
+    else if(!(geometry.components instanceof Array) ||
+             (geometry.components.length != this.components.length))
+      equivalent = false;
+    else
+      for(var i=0, len=this.components.length; i<len; ++i) {
+        if(!this.components[i].equals(geometry.components[i])) {
+          equivalent = false;
+          break;
+        }
+      }
+    return equivalent;
+  },
+  /**
+   * Method: transform
+   * Reproject the components geometry from source to dest.
+   * 
+   * Parameters:
+   * source - {<ZOO.Projection>} 
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
+  transform: function(source, dest) {
+    if (source && dest) {
+      for (var i=0, len=this.components.length; i<len; i++) {  
+        var component = this.components[i];
+        component.transform(source, dest);
+      }
+      this.bounds = null;
+    }
+    return this;
+  },
+  /**
+   * Method: intersects
+   * Determine if the input geometry intersects this one.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} Any type of geometry.
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this one.
+   */
+  intersects: function(geometry) {
+    var intersect = false;
+    for(var i=0, len=this.components.length; i<len; ++ i) {
+      intersect = geometry.intersects(this.components[i]);
+      if(intersect)
+        break;
+    }
+    return intersect;
+  },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
+  getVertices: function(nodes) {
+    var vertices = [];
+    for(var i=0, len=this.components.length; i<len; ++i) {
+      Array.prototype.push.apply(
+          vertices, this.components[i].getVertices(nodes)
+          );
+    }
+    return vertices;
+  },
+  CLASS_NAME: 'ZOO.Geometry.Collection'
+});
+/**
+ * Class: ZOO.Geometry.Point
+ * Point geometry class. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry> 
+ */
+ZOO.Geometry.Point = ZOO.Class(ZOO.Geometry, {
+  /** 
+   * Property: x 
+   * {float} 
+   */
+  x: null,
+  /** 
+   * Property: y 
+   * {float} 
+   */
+  y: null,
+  /**
+   * Constructor: ZOO.Geometry.Point
+   * Construct a point geometry.
+   *
+   * Parameters:
+   * x - {float} 
+   * y - {float}
+   * 
+   */
+  initialize: function(x, y) {
+    ZOO.Geometry.prototype.initialize.apply(this, arguments);
+    this.x = parseFloat(x);
+    this.y = parseFloat(y);
+  },
+  /**
+   * Method: clone
+   * 
+   * Returns:
+   * {<ZOO.Geometry.Point>} An exact clone of this ZOO.Geometry.Point
+   */
+  clone: function(obj) {
+    if (obj == null)
+      obj = new ZOO.Geometry.Point(this.x, this.y);
+    // catch any randomly tagged-on properties
+    // ZOO.Util.applyDefaults(obj, this);
+    return obj;
+  },
+  /** 
+   * Method: calculateBounds
+   * Create a new Bounds based on the x/y
+   */
+  calculateBounds: function () {
+    this.bounds = new ZOO.Bounds(this.x, this.y,
+                                        this.x, this.y);
+  },
+  distanceTo: function(geometry, options) {
+    var edge = !(options && options.edge === false);
+    var details = edge && options && options.details;
+    var distance, x0, y0, x1, y1, result;
+    if(geometry instanceof ZOO.Geometry.Point) {
+      x0 = this.x;
+      y0 = this.y;
+      x1 = geometry.x;
+      y1 = geometry.y;
+      distance = Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));
+      result = !details ?
+        distance : {x0: x0, y0: y0, x1: x1, y1: y1, distance: distance};
+    } else {
+      result = geometry.distanceTo(this, options);
+      if(details) {
+        // switch coord order since this geom is target
+        result = {
+          x0: result.x1, y0: result.y1,
+          x1: result.x0, y1: result.y0,
+          distance: result.distance
+        };
+      }
+    }
+    return result;
+  },
+  /** 
+   * Method: equals
+   * Determine whether another geometry is equivalent to this one.  Geometries
+   *     are considered equivalent if all components have the same coordinates.
+   * 
+   * Parameters:
+   * geom - {<ZOO.Geometry.Point>} The geometry to test. 
+   *
+   * Returns:
+   * {Boolean} The supplied geometry is equivalent to this geometry.
+   */
+  equals: function(geom) {
+    var equals = false;
+    if (geom != null)
+      equals = ((this.x == geom.x && this.y == geom.y) ||
+                (isNaN(this.x) && isNaN(this.y) && isNaN(geom.x) && isNaN(geom.y)));
+    return equals;
+  },
+  /**
+   * Method: toShortString
+   *
+   * Returns:
+   * {String} Shortened String representation of Point object. 
+   *         (ex. <i>"5, 42"</i>)
+   */
+  toShortString: function() {
+    return (this.x + ", " + this.y);
+  },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
+  move: function(x, y) {
+    this.x = this.x + x;
+    this.y = this.y + y;
+    this.clearBounds();
+  },
+  /**
+   * Method: rotate
+   * Rotate a point around another.
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
+  rotate: function(angle, origin) {
+        angle *= Math.PI / 180;
+        var radius = this.distanceTo(origin);
+        var theta = angle + Math.atan2(this.y - origin.y, this.x - origin.x);
+        this.x = origin.x + (radius * Math.cos(theta));
+        this.y = origin.y + (radius * Math.sin(theta));
+        this.clearBounds();
+  },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the collection
+   */
+  getCentroid: function() {
+    return new ZOO.Geometry.Point(this.x, this.y);
+  },
+  /**
+   * Method: resize
+   * Resize a point relative to some origin.  For points, this has the effect
+   *     of scaling a vector (from the origin to the point).  This method is
+   *     more useful on geometry collection subclasses.
+   *
+   * Parameters:
+   * scale - {Float} Ratio of the new distance from the origin to the old
+   *                 distance from the origin.  A scale of 2 doubles the
+   *                 distance between the point and origin.
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
+  resize: function(scale, origin, ratio) {
+    ratio = (ratio == undefined) ? 1 : ratio;
+    this.x = origin.x + (scale * ratio * (this.x - origin.x));
+    this.y = origin.y + (scale * (this.y - origin.y));
+    this.clearBounds();
+    return this;
+  },
+  /**
+   * Method: intersects
+   * Determine if the input geometry intersects this one.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} Any type of geometry.
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this one.
+   */
+  intersects: function(geometry) {
+    var intersect = false;
+    if(geometry.CLASS_NAME == "ZOO.Geometry.Point") {
+      intersect = this.equals(geometry);
+    } else {
+      intersect = geometry.intersects(this);
+    }
+    return intersect;
+  },
+  /**
+   * Method: transform
+   * Translate the x,y properties of the point from source to dest.
+   * 
+   * Parameters:
+   * source - {<ZOO.Projection>} 
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
+  transform: function(source, dest) {
+    if ((source && dest)) {
+      ZOO.Projection.transform(
+          this, source, dest); 
+      this.bounds = null;
+    }       
+    return this;
+  },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
+  getVertices: function(nodes) {
+    return [this];
+  },
+  CLASS_NAME: 'ZOO.Geometry.Point'
+});
+/**
+ * Class: ZOO.Geometry.Surface
+ * Surface geometry class. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry> 
+ */
+ZOO.Geometry.Surface = ZOO.Class(ZOO.Geometry, {
+  initialize: function() {
+    ZOO.Geometry.prototype.initialize.apply(this, arguments);
+  },
+  CLASS_NAME: "ZOO.Geometry.Surface"
+});
+/**
+ * Class: ZOO.Geometry.MultiPoint
+ * MultiPoint is a collection of Points. Create a new instance with the
+ * <ZOO.Geometry.MultiPoint> constructor.
+ *
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
+ZOO.Geometry.MultiPoint = ZOO.Class(
+  ZOO.Geometry.Collection, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of
+   * components that the collection can include.  A null value means the
+   * component types are not restricted.
+   */
+  componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: ZOO.Geometry.MultiPoint
+   * Create a new MultiPoint Geometry
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.Point>)} 
+   *
+   * Returns:
+   * {<ZOO.Geometry.MultiPoint>}
+   */
+  initialize: function(components) {
+    ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
+  },
+  /**
+   * Method: addPoint
+   * Wrapper for <ZOO.Geometry.Collection.addComponent>
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>} Point to be added
+   * index - {Integer} Optional index
+   */
+  addPoint: function(point, index) {
+    this.addComponent(point, index);
+  },
+  /**
+   * Method: removePoint
+   * Wrapper for <ZOO.Geometry.Collection.removeComponent>
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>} Point to be removed
+   */
+  removePoint: function(point){
+    this.removeComponent(point);
+  },
+  CLASS_NAME: "ZOO.Geometry.MultiPoint"
+});
+/**
+ * Class: ZOO.Geometry.Curve
+ * A Curve is a MultiPoint, whose points are assumed to be connected. To 
+ * this end, we provide a "getLength()" function, which iterates through 
+ * the points, summing the distances between them. 
+ * 
+ * Inherits: 
+ *  - <ZOO.Geometry.MultiPoint>
+ */
+ZOO.Geometry.Curve = ZOO.Class(ZOO.Geometry.MultiPoint, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of 
+   *                 components that the collection can include.  A null 
+   *                 value means the component types are not restricted.
+   */
+  componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: ZOO.Geometry.Curve
+   * 
+   * Parameters:
+   * point - {Array(<ZOO.Geometry.Point>)}
+   */
+  initialize: function(points) {
+    ZOO.Geometry.MultiPoint.prototype.initialize.apply(this,arguments);
+  },
+  /**
+   * Method: getLength
+   * 
+   * Returns:
+   * {Float} The length of the curve
+   */
+  getLength: function() {
+    var length = 0.0;
+    if ( this.components && (this.components.length > 1)) {
+      for(var i=1, len=this.components.length; i<len; i++) {
+        length += this.components[i-1].distanceTo(this.components[i]);
+      }
+    }
+    return length;
+  },
+  /**
+     * APIMethod: getGeodesicLength
+     * Calculate the approximate length of the geometry were it projected onto
+     *     the earth.
+     *
+     * projection - {<ZOO.Projection>} The spatial reference system
+     *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+     *     assumed.
+     * 
+     * Returns:
+     * {Float} The appoximate geodesic length of the geometry in meters.
+     */
+    getGeodesicLength: function(projection) {
+      var geom = this;  // so we can work with a clone if needed
+      if(projection) {
+        var gg = new ZOO.Projection("EPSG:4326");
+        if(!gg.equals(projection)) {
+          geom = this.clone().transform(projection, gg);
+       }
+     }
+     var length = 0.0;
+     if(geom.components && (geom.components.length > 1)) {
+       var p1, p2;
+       for(var i=1, len=geom.components.length; i<len; i++) {
+         p1 = geom.components[i-1];
+         p2 = geom.components[i];
+        // this returns km and requires x/y properties
+        length += ZOO.distVincenty(p1,p2);
+      }
+    }
+    // convert to m
+    return length * 1000;
+  },
+  CLASS_NAME: "ZOO.Geometry.Curve"
+});
+/**
+ * Class: ZOO.Geometry.LineString
+ * A LineString is a Curve which, once two points have been added to it, can 
+ * never be less than two points long.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Curve>
+ */
+ZOO.Geometry.LineString = ZOO.Class(ZOO.Geometry.Curve, {
+  /**
+   * Constructor: ZOO.Geometry.LineString
+   * Create a new LineString geometry
+   *
+   * Parameters:
+   * points - {Array(<ZOO.Geometry.Point>)} An array of points used to
+   *          generate the linestring
+   *
+   */
+  initialize: function(points) {
+    ZOO.Geometry.Curve.prototype.initialize.apply(this, arguments);        
+  },
+  /**
+   * Method: removeComponent
+   * Only allows removal of a point if there are three or more points in 
+   * the linestring. (otherwise the result would be just a single point)
+   *
+   * Parameters: 
+   * point - {<ZOO.Geometry.Point>} The point to be removed
+   */
+  removeComponent: function(point) {
+    if ( this.components && (this.components.length > 2))
+      ZOO.Geometry.Collection.prototype.removeComponent.apply(this,arguments);
+  },
+  /**
+   * Method: intersects
+   * Test for instersection between two geometries.  This is a cheapo
+   *     implementation of the Bently-Ottmann algorigithm.  It doesn't
+   *     really keep track of a sweep line data structure.  It is closer
+   *     to the brute force method, except that segments are sorted and
+   *     potential intersections are only calculated when bounding boxes
+   *     intersect.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this geometry.
+   */
+  intersects: function(geometry) {
+    var intersect = false;
+    var type = geometry.CLASS_NAME;
+    if(type == "ZOO.Geometry.LineString" ||
+       type == "ZOO.Geometry.LinearRing" ||
+       type == "ZOO.Geometry.Point") {
+      var segs1 = this.getSortedSegments();
+      var segs2;
+      if(type == "ZOO.Geometry.Point")
+        segs2 = [{
+          x1: geometry.x, y1: geometry.y,
+          x2: geometry.x, y2: geometry.y
+        }];
+      else
+        segs2 = geometry.getSortedSegments();
+      var seg1, seg1x1, seg1x2, seg1y1, seg1y2,
+          seg2, seg2y1, seg2y2;
+      // sweep right
+      outer: for(var i=0, len=segs1.length; i<len; ++i) {
+         seg1 = segs1[i];
+         seg1x1 = seg1.x1;
+         seg1x2 = seg1.x2;
+         seg1y1 = seg1.y1;
+         seg1y2 = seg1.y2;
+         inner: for(var j=0, jlen=segs2.length; j<jlen; ++j) {
+           seg2 = segs2[j];
+           if(seg2.x1 > seg1x2)
+             break;
+           if(seg2.x2 < seg1x1)
+             continue;
+           seg2y1 = seg2.y1;
+           seg2y2 = seg2.y2;
+           if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2))
+             continue;
+           if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2))
+             continue;
+           if(ZOO.Geometry.segmentsIntersect(seg1, seg2)) {
+             intersect = true;
+             break outer;
+           }
+         }
+      }
+    } else {
+      intersect = geometry.intersects(this);
+    }
+    return intersect;
+  },
+  /**
+   * Method: getSortedSegments
+   *
+   * Returns:
+   * {Array} An array of segment objects.  Segment objects have properties
+   *     x1, y1, x2, and y2.  The start point is represented by x1 and y1.
+   *     The end point is represented by x2 and y2.  Start and end are
+   *     ordered so that x1 < x2.
+   */
+  getSortedSegments: function() {
+    var numSeg = this.components.length - 1;
+    var segments = new Array(numSeg);
+    for(var i=0; i<numSeg; ++i) {
+      point1 = this.components[i];
+      point2 = this.components[i + 1];
+      if(point1.x < point2.x)
+        segments[i] = {
+          x1: point1.x,
+          y1: point1.y,
+          x2: point2.x,
+          y2: point2.y
+        };
+      else
+        segments[i] = {
+          x1: point2.x,
+          y1: point2.y,
+          x2: point1.x,
+          y2: point1.y
+        };
+    }
+    // more efficient to define this somewhere static
+    function byX1(seg1, seg2) {
+      return seg1.x1 - seg2.x1;
+    }
+    return segments.sort(byX1);
+  },
+  /**
+   * Method: splitWithSegment
+   * Split this geometry with the given segment.
+   *
+   * Parameters:
+   * seg - {Object} An object with x1, y1, x2, and y2 properties referencing
+   *     segment endpoint coordinates.
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source segment must be within the
+   *     tolerance distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of one of the source segment's
+   *     endpoints will be assumed to occur at the endpoint.
+   *
+   * Returns:
+   * {Object} An object with *lines* and *points* properties.  If the given
+   *     segment intersects this linestring, the lines array will reference
+   *     geometries that result from the split.  The points array will contain
+   *     all intersection points.  Intersection points are sorted along the
+   *     segment (in order from x1,y1 to x2,y2).
+   */
+  splitWithSegment: function(seg, options) {
+    var edge = !(options && options.edge === false);
+    var tolerance = options && options.tolerance;
+    var lines = [];
+    var verts = this.getVertices();
+    var points = [];
+    var intersections = [];
+    var split = false;
+    var vert1, vert2, point;
+    var node, vertex, target;
+    var interOptions = {point: true, tolerance: tolerance};
+    var result = null;
+    for(var i=0, stop=verts.length-2; i<=stop; ++i) {
+      vert1 = verts[i];
+      points.push(vert1.clone());
+      vert2 = verts[i+1];
+      target = {x1: vert1.x, y1: vert1.y, x2: vert2.x, y2: vert2.y};
+      point = ZOO.Geometry.segmentsIntersect(seg, target, interOptions);
+      if(point instanceof ZOO.Geometry.Point) {
+        if((point.x === seg.x1 && point.y === seg.y1) ||
+           (point.x === seg.x2 && point.y === seg.y2) ||
+            point.equals(vert1) || point.equals(vert2))
+          vertex = true;
+        else
+          vertex = false;
+        if(vertex || edge) {
+          // push intersections different than the previous
+          if(!point.equals(intersections[intersections.length-1]))
+            intersections.push(point.clone());
+          if(i === 0) {
+            if(point.equals(vert1))
+              continue;
+          }
+          if(point.equals(vert2))
+            continue;
+          split = true;
+          if(!point.equals(vert1))
+            points.push(point);
+          lines.push(new ZOO.Geometry.LineString(points));
+          points = [point.clone()];
+        }
+      }
+    }
+    if(split) {
+      points.push(vert2.clone());
+      lines.push(new ZOO.Geometry.LineString(points));
+    }
+    if(intersections.length > 0) {
+      // sort intersections along segment
+      var xDir = seg.x1 < seg.x2 ? 1 : -1;
+      var yDir = seg.y1 < seg.y2 ? 1 : -1;
+      result = {
+        lines: lines,
+        points: intersections.sort(function(p1, p2) {
+           return (xDir * p1.x - xDir * p2.x) || (yDir * p1.y - yDir * p2.y);
+        })
+      };
+    }
+    return result;
+  },
+  /**
+   * Method: split
+   * Use this geometry (the source) to attempt to split a target geometry.
+   * 
+   * Parameters:
+   * target - {<ZOO.Geometry>} The target geometry.
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * mutual - {Boolean} Split the source geometry in addition to the target
+   *     geometry.  Default is false.
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source must be within the tolerance
+   *     distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of an existing vertex on the source
+   *     will be assumed to occur at the vertex.
+   * 
+   * Returns:
+   * {Array} A list of geometries (of this same type as the target) that
+   *     result from splitting the target with the source geometry.  The
+   *     source and target geometry will remain unmodified.  If no split
+   *     results, null will be returned.  If mutual is true and a split
+   *     results, return will be an array of two arrays - the first will be
+   *     all geometries that result from splitting the source geometry and
+   *     the second will be all geometries that result from splitting the
+   *     target geometry.
+   */
+  split: function(target, options) {
+    var results = null;
+    var mutual = options && options.mutual;
+    var sourceSplit, targetSplit, sourceParts, targetParts;
+    if(target instanceof ZOO.Geometry.LineString) {
+      var verts = this.getVertices();
+      var vert1, vert2, seg, splits, lines, point;
+      var points = [];
+      sourceParts = [];
+      for(var i=0, stop=verts.length-2; i<=stop; ++i) {
+        vert1 = verts[i];
+        vert2 = verts[i+1];
+        seg = {
+          x1: vert1.x, y1: vert1.y,
+          x2: vert2.x, y2: vert2.y
+        };
+        targetParts = targetParts || [target];
+        if(mutual)
+          points.push(vert1.clone());
+        for(var j=0; j<targetParts.length; ++j) {
+          splits = targetParts[j].splitWithSegment(seg, options);
+          if(splits) {
+            // splice in new features
+            lines = splits.lines;
+            if(lines.length > 0) {
+              lines.unshift(j, 1);
+              Array.prototype.splice.apply(targetParts, lines);
+              j += lines.length - 2;
+            }
+            if(mutual) {
+              for(var k=0, len=splits.points.length; k<len; ++k) {
+                point = splits.points[k];
+                if(!point.equals(vert1)) {
+                  points.push(point);
+                  sourceParts.push(new ZOO.Geometry.LineString(points));
+                  if(point.equals(vert2))
+                    points = [];
+                  else
+                    points = [point.clone()];
+                }
+              }
+            }
+          }
+        }
+      }
+      if(mutual && sourceParts.length > 0 && points.length > 0) {
+        points.push(vert2.clone());
+        sourceParts.push(new ZOO.Geometry.LineString(points));
+      }
+    } else {
+      results = target.splitWith(this, options);
+    }
+    if(targetParts && targetParts.length > 1)
+      targetSplit = true;
+    else
+      targetParts = [];
+    if(sourceParts && sourceParts.length > 1)
+      sourceSplit = true;
+    else
+      sourceParts = [];
+    if(targetSplit || sourceSplit) {
+      if(mutual)
+        results = [sourceParts, targetParts];
+      else
+        results = targetParts;
+    }
+    return results;
+  },
+  /**
+   * Method: splitWith
+   * Split this geometry (the target) with the given geometry (the source).
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} A geometry used to split this
+   *     geometry (the source).
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * mutual - {Boolean} Split the source geometry in addition to the target
+   *     geometry.  Default is false.
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source must be within the tolerance
+   *     distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of an existing vertex on the source
+   *     will be assumed to occur at the vertex.
+   * 
+   * Returns:
+   * {Array} A list of geometries (of this same type as the target) that
+   *     result from splitting the target with the source geometry.  The
+   *     source and target geometry will remain unmodified.  If no split
+   *     results, null will be returned.  If mutual is true and a split
+   *     results, return will be an array of two arrays - the first will be
+   *     all geometries that result from splitting the source geometry and
+   *     the second will be all geometries that result from splitting the
+   *     target geometry.
+   */
+  splitWith: function(geometry, options) {
+    return geometry.split(this, options);
+  },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
+  getVertices: function(nodes) {
+    var vertices;
+    if(nodes === true)
+      vertices = [
+        this.components[0],
+        this.components[this.components.length-1]
+      ];
+    else if (nodes === false)
+      vertices = this.components.slice(1, this.components.length-1);
+    else
+      vertices = this.components.slice();
+    return vertices;
+  },
+  distanceTo: function(geometry, options) {
+    var edge = !(options && options.edge === false);
+    var details = edge && options && options.details;
+    var result, best = {};
+    var min = Number.POSITIVE_INFINITY;
+    if(geometry instanceof ZOO.Geometry.Point) {
+      var segs = this.getSortedSegments();
+      var x = geometry.x;
+      var y = geometry.y;
+      var seg;
+      for(var i=0, len=segs.length; i<len; ++i) {
+        seg = segs[i];
+        result = ZOO.Geometry.distanceToSegment(geometry, seg);
+        if(result.distance < min) {
+          min = result.distance;
+          best = result;
+          if(min === 0)
+            break;
+        } else {
+          // if distance increases and we cross y0 to the right of x0, no need to keep looking.
+          if(seg.x2 > x && ((y > seg.y1 && y < seg.y2) || (y < seg.y1 && y > seg.y2)))
+            break;
+        }
+      }
+      if(details)
+        best = {
+          distance: best.distance,
+          x0: best.x, y0: best.y,
+          x1: x, y1: y
+        };
+      else
+        best = best.distance;
+    } else if(geometry instanceof ZOO.Geometry.LineString) { 
+      var segs0 = this.getSortedSegments();
+      var segs1 = geometry.getSortedSegments();
+      var seg0, seg1, intersection, x0, y0;
+      var len1 = segs1.length;
+      var interOptions = {point: true};
+      outer: for(var i=0, len=segs0.length; i<len; ++i) {
+        seg0 = segs0[i];
+        x0 = seg0.x1;
+        y0 = seg0.y1;
+        for(var j=0; j<len1; ++j) {
+          seg1 = segs1[j];
+          intersection = ZOO.Geometry.segmentsIntersect(seg0, seg1, interOptions);
+          if(intersection) {
+            min = 0;
+            best = {
+              distance: 0,
+              x0: intersection.x, y0: intersection.y,
+              x1: intersection.x, y1: intersection.y
+            };
+            break outer;
+          } else {
+            result = ZOO.Geometry.distanceToSegment({x: x0, y: y0}, seg1);
+            if(result.distance < min) {
+              min = result.distance;
+              best = {
+                distance: min,
+                x0: x0, y0: y0,
+                x1: result.x, y1: result.y
+              };
+            }
+          }
+        }
+      }
+      if(!details)
+        best = best.distance;
+      if(min !== 0) {
+        // check the final vertex in this line's sorted segments
+        if(seg0) {
+          result = geometry.distanceTo(
+              new ZOO.Geometry.Point(seg0.x2, seg0.y2),
+              options
+              );
+          var dist = details ? result.distance : result;
+          if(dist < min) {
+            if(details)
+              best = {
+                distance: min,
+                x0: result.x1, y0: result.y1,
+                x1: result.x0, y1: result.y0
+              };
+            else
+              best = dist;
+          }
+        }
+      }
+    } else {
+      best = geometry.distanceTo(this, options);
+      // swap since target comes from this line
+      if(details)
+        best = {
+          distance: best.distance,
+          x0: best.x1, y0: best.y1,
+          x1: best.x0, y1: best.y0
+        };
+    }
+    return best;
+  },
+  CLASS_NAME: "ZOO.Geometry.LineString"
+});
+/**
+ * Class: ZOO.Geometry.LinearRing
+ * 
+ * A Linear Ring is a special LineString which is closed. It closes itself 
+ * automatically on every addPoint/removePoint by adding a copy of the first
+ * point as the last point. 
+ * 
+ * Also, as it is the first in the line family to close itself, a getArea()
+ * function is defined to calculate the enclosed area of the linearRing
+ * 
+ * Inherits:
+ *  - <ZOO.Geometry.LineString>
+ */
+ZOO.Geometry.LinearRing = ZOO.Class(
+  ZOO.Geometry.LineString, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of 
+   *                 components that the collection can include.  A null 
+   *                 value means the component types are not restricted.
+   */
+  componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: ZOO.Geometry.LinearRing
+   * Linear rings are constructed with an array of points.  This array
+   *     can represent a closed or open ring.  If the ring is open (the last
+   *     point does not equal the first point), the constructor will close
+   *     the ring.  If the ring is already closed (the last point does equal
+   *     the first point), it will be left closed.
+   * 
+   * Parameters:
+   * points - {Array(<ZOO.Geometry.Point>)} points
+   */
+  initialize: function(points) {
+    ZOO.Geometry.LineString.prototype.initialize.apply(this,arguments);
+  },
+  /**
+   * Method: addComponent
+   * Adds a point to geometry components.  If the point is to be added to
+   *     the end of the components array and it is the same as the last point
+   *     already in that array, the duplicate point is not added.  This has 
+   *     the effect of closing the ring if it is not already closed, and 
+   *     doing the right thing if it is already closed.  This behavior can 
+   *     be overridden by calling the method with a non-null index as the 
+   *     second argument.
+   *
+   * Parameter:
+   * point - {<ZOO.Geometry.Point>}
+   * index - {Integer} Index into the array to insert the component
+   * 
+   * Returns:
+   * {Boolean} Was the Point successfully added?
+   */
+  addComponent: function(point, index) {
+    var added = false;
+    //remove last point
+    var lastPoint = this.components.pop();
+    // given an index, add the point
+    // without an index only add non-duplicate points
+    if(index != null || !point.equals(lastPoint))
+      added = ZOO.Geometry.Collection.prototype.addComponent.apply(this,arguments);
+    //append copy of first point
+    var firstPoint = this.components[0];
+    ZOO.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);
+    return added;
+  },
+  /**
+   * APIMethod: removeComponent
+   * Removes a point from geometry components.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   */
+  removeComponent: function(point) {
+    if (this.components.length > 4) {
+      //remove last point
+      this.components.pop();
+      //remove our point
+      ZOO.Geometry.Collection.prototype.removeComponent.apply(this,arguments);
+      //append copy of first point
+      var firstPoint = this.components[0];
+      ZOO.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);
+    }
+  },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
+  move: function(x, y) {
+    for(var i = 0, len=this.components.length; i<len - 1; i++) {
+      this.components[i].move(x, y);
+    }
+  },
+  /**
+   * Method: rotate
+   * Rotate a geometry around some origin
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
+  rotate: function(angle, origin) {
+    for(var i=0, len=this.components.length; i<len - 1; ++i) {
+      this.components[i].rotate(angle, origin);
+    }
+  },
+  /**
+   * Method: resize
+   * Resize a geometry relative to some origin.  Use this method to apply
+   *     a uniform scaling to a geometry.
+   *
+   * Parameters:
+   * scale - {Float} Factor by which to scale the geometry.  A scale of 2
+   *                 doubles the size of the geometry in each dimension
+   *                 (lines, for example, will be twice as long, and polygons
+   *                 will have four times the area).
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
+  resize: function(scale, origin, ratio) {
+    for(var i=0, len=this.components.length; i<len - 1; ++i) {
+      this.components[i].resize(scale, origin, ratio);
+    }
+    return this;
+  },
+  /**
+   * Method: transform
+   * Reproject the components geometry from source to dest.
+   *
+   * Parameters:
+   * source - {<ZOO.Projection>}
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
+  transform: function(source, dest) {
+    if (source && dest) {
+      for (var i=0, len=this.components.length; i<len - 1; i++) {
+        var component = this.components[i];
+        component.transform(source, dest);
+      }
+      this.bounds = null;
+    }
+    return this;
+  },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the ring
+   */
+  getCentroid: function() {
+    if ( this.components && (this.components.length > 2)) {
+      var sumX = 0.0;
+      var sumY = 0.0;
+      for (var i = 0; i < this.components.length - 1; i++) {
+        var b = this.components[i];
+        var c = this.components[i+1];
+        sumX += (b.x + c.x) * (b.x * c.y - c.x * b.y);
+        sumY += (b.y + c.y) * (b.x * c.y - c.x * b.y);
+      }
+      var area = -1 * this.getArea();
+      var x = sumX / (6 * area);
+      var y = sumY / (6 * area);
+    }
+    return new ZOO.Geometry.Point(x, y);
+  },
+  /**
+   * Method: getArea
+   * Note - The area is positive if the ring is oriented CW, otherwise
+   *         it will be negative.
+   * 
+   * Returns:
+   * {Float} The signed area for a ring.
+   */
+  getArea: function() {
+    var area = 0.0;
+    if ( this.components && (this.components.length > 2)) {
+      var sum = 0.0;
+      for (var i=0, len=this.components.length; i<len - 1; i++) {
+        var b = this.components[i];
+        var c = this.components[i+1];
+        sum += (b.x + c.x) * (c.y - b.y);
+      }
+      area = - sum / 2.0;
+    }
+    return area;
+  },
+  /**
+   * Method: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.  Note that this area will be positive if ring is oriented
+   *     clockwise, otherwise it will be negative.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate signed geodesic area of the polygon in square
+   *     meters.
+   */
+  getGeodesicArea: function(projection) {
+    var ring = this;  // so we can work with a clone if needed
+    if(projection) {
+      var gg = new ZOO.Projection("EPSG:4326");
+      if(!gg.equals(projection)) {
+        ring = this.clone().transform(projection, gg);
+      }
+    }
+    var area = 0.0;
+    var len = ring.components && ring.components.length;
+    if(len > 2) {
+      var p1, p2;
+      for(var i=0; i<len-1; i++) {
+        p1 = ring.components[i];
+        p2 = ring.components[i+1];
+        area += ZOO.rad(p2.x - p1.x) *
+                (2 + Math.sin(ZOO.rad(p1.y)) +
+                Math.sin(ZOO.rad(p2.y)));
+      }
+      area = area * 6378137.0 * 6378137.0 / 2.0;
+    }
+    return area;
+  },
+  /**
+   * Method: containsPoint
+   * Test if a point is inside a linear ring.  For the case where a point
+   *     is coincident with a linear ring edge, returns 1.  Otherwise,
+   *     returns boolean.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   *
+   * Returns:
+   * {Boolean | Number} The point is inside the linear ring.  Returns 1 if
+   *     the point is coincident with an edge.  Returns boolean otherwise.
+   */
+  containsPoint: function(point) {
+    var approx = OpenLayers.Number.limitSigDigs;
+    var digs = 14;
+    var px = approx(point.x, digs);
+    var py = approx(point.y, digs);
+    function getX(y, x1, y1, x2, y2) {
+      return (((x1 - x2) * y) + ((x2 * y1) - (x1 * y2))) / (y1 - y2);
+    }
+    var numSeg = this.components.length - 1;
+    var start, end, x1, y1, x2, y2, cx, cy;
+    var crosses = 0;
+    for(var i=0; i<numSeg; ++i) {
+      start = this.components[i];
+      x1 = approx(start.x, digs);
+      y1 = approx(start.y, digs);
+      end = this.components[i + 1];
+      x2 = approx(end.x, digs);
+      y2 = approx(end.y, digs);
+
+      /**
+       * The following conditions enforce five edge-crossing rules:
+       *    1. points coincident with edges are considered contained;
+       *    2. an upward edge includes its starting endpoint, and
+       *    excludes its final endpoint;
+       *    3. a downward edge excludes its starting endpoint, and
+       *    includes its final endpoint;
+       *    4. horizontal edges are excluded; and
+       *    5. the edge-ray intersection point must be strictly right
+       *    of the point P.
+       */
+      if(y1 == y2) {
+        // horizontal edge
+        if(py == y1) {
+          // point on horizontal line
+          if(x1 <= x2 && (px >= x1 && px <= x2) || // right or vert
+              x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert
+            // point on edge
+            crosses = -1;
+            break;
+          }
+        }
+        // ignore other horizontal edges
+        continue;
+      }
+      cx = approx(getX(py, x1, y1, x2, y2), digs);
+      if(cx == px) {
+        // point on line
+        if(y1 < y2 && (py >= y1 && py <= y2) || // upward
+            y1 > y2 && (py <= y1 && py >= y2)) { // downward
+          // point on edge
+          crosses = -1;
+          break;
+        }
+      }
+      if(cx <= px) {
+        // no crossing to the right
+        continue;
+      }
+      if(x1 != x2 && (cx < Math.min(x1, x2) || cx > Math.max(x1, x2))) {
+        // no crossing
+        continue;
+      }
+      if(y1 < y2 && (py >= y1 && py < y2) || // upward
+          y1 > y2 && (py < y1 && py >= y2)) { // downward
+        ++crosses;
+      }
+    }
+    var contained = (crosses == -1) ?
+      // on edge
+      1 :
+      // even (out) or odd (in)
+      !!(crosses & 1);
+
+    return contained;
+  },
+  intersects: function(geometry) {
+    var intersect = false;
+    if(geometry.CLASS_NAME == "ZOO.Geometry.Point")
+      intersect = this.containsPoint(geometry);
+    else if(geometry.CLASS_NAME == "ZOO.Geometry.LineString")
+      intersect = geometry.intersects(this);
+    else if(geometry.CLASS_NAME == "ZOO.Geometry.LinearRing")
+      intersect = ZOO.Geometry.LineString.prototype.intersects.apply(
+          this, [geometry]
+          );
+    else
+      for(var i=0, len=geometry.components.length; i<len; ++ i) {
+        intersect = geometry.components[i].intersects(this);
+        if(intersect)
+          break;
+      }
+    return intersect;
+  },
+  getVertices: function(nodes) {
+    return (nodes === true) ? [] : this.components.slice(0, this.components.length-1);
+  },
+  CLASS_NAME: "ZOO.Geometry.LinearRing"
+});
+/**
+ * Class: ZOO.Geometry.MultiLineString
+ * A MultiLineString is a geometry with multiple <ZOO.Geometry.LineString>
+ * components.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
+ZOO.Geometry.MultiLineString = ZOO.Class(
+  ZOO.Geometry.Collection, {
+  componentTypes: ["ZOO.Geometry.LineString"],
+  /**
+   * Constructor: ZOO.Geometry.MultiLineString
+   * Constructor for a MultiLineString Geometry.
+   *
+   * Parameters: 
+   * components - {Array(<ZOO.Geometry.LineString>)} 
+   *
+   */
+  initialize: function(components) {
+    ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);        
+  },
+  split: function(geometry, options) {
+    var results = null;
+    var mutual = options && options.mutual;
+    var splits, sourceLine, sourceLines, sourceSplit, targetSplit;
+    var sourceParts = [];
+    var targetParts = [geometry];
+    for(var i=0, len=this.components.length; i<len; ++i) {
+      sourceLine = this.components[i];
+      sourceSplit = false;
+      for(var j=0; j < targetParts.length; ++j) { 
+        splits = sourceLine.split(targetParts[j], options);
+        if(splits) {
+          if(mutual) {
+            sourceLines = splits[0];
+            for(var k=0, klen=sourceLines.length; k<klen; ++k) {
+              if(k===0 && sourceParts.length)
+                sourceParts[sourceParts.length-1].addComponent(
+                  sourceLines[k]
+                );
+              else
+                sourceParts.push(
+                  new ZOO.Geometry.MultiLineString([
+                    sourceLines[k]
+                    ])
+                );
+            }
+            sourceSplit = true;
+            splits = splits[1];
+          }
+          if(splits.length) {
+            // splice in new target parts
+            splits.unshift(j, 1);
+            Array.prototype.splice.apply(targetParts, splits);
+            break;
+          }
+        }
+      }
+      if(!sourceSplit) {
+        // source line was not hit
+        if(sourceParts.length) {
+          // add line to existing multi
+          sourceParts[sourceParts.length-1].addComponent(
+              sourceLine.clone()
+              );
+        } else {
+          // create a fresh multi
+          sourceParts = [
+            new ZOO.Geometry.MultiLineString(
+                sourceLine.clone()
+                )
+            ];
+        }
+      }
+    }
+    if(sourceParts && sourceParts.length > 1)
+      sourceSplit = true;
+    else
+      sourceParts = [];
+    if(targetParts && targetParts.length > 1)
+      targetSplit = true;
+    else
+      targetParts = [];
+    if(sourceSplit || targetSplit) {
+      if(mutual)
+        results = [sourceParts, targetParts];
+      else
+        results = targetParts;
+    }
+    return results;
+  },
+  splitWith: function(geometry, options) {
+    var results = null;
+    var mutual = options && options.mutual;
+    var splits, targetLine, sourceLines, sourceSplit, targetSplit, sourceParts, targetParts;
+    if(geometry instanceof ZOO.Geometry.LineString) {
+      targetParts = [];
+      sourceParts = [geometry];
+      for(var i=0, len=this.components.length; i<len; ++i) {
+        targetSplit = false;
+        targetLine = this.components[i];
+        for(var j=0; j<sourceParts.length; ++j) {
+          splits = sourceParts[j].split(targetLine, options);
+          if(splits) {
+            if(mutual) {
+              sourceLines = splits[0];
+              if(sourceLines.length) {
+                // splice in new source parts
+                sourceLines.unshift(j, 1);
+                Array.prototype.splice.apply(sourceParts, sourceLines);
+                j += sourceLines.length - 2;
+              }
+              splits = splits[1];
+              if(splits.length === 0) {
+                splits = [targetLine.clone()];
+              }
+            }
+            for(var k=0, klen=splits.length; k<klen; ++k) {
+              if(k===0 && targetParts.length) {
+                targetParts[targetParts.length-1].addComponent(
+                    splits[k]
+                    );
+              } else {
+                targetParts.push(
+                    new ZOO.Geometry.MultiLineString([
+                      splits[k]
+                      ])
+                    );
+              }
+            }
+            targetSplit = true;                    
+          }
+        }
+        if(!targetSplit) {
+          // target component was not hit
+          if(targetParts.length) {
+            // add it to any existing multi-line
+            targetParts[targetParts.length-1].addComponent(
+                targetLine.clone()
+                );
+          } else {
+            // or start with a fresh multi-line
+            targetParts = [
+              new ZOO.Geometry.MultiLineString([
+                  targetLine.clone()
+                  ])
+              ];
+          }
+
+        }
+      }
+    } else {
+      results = geometry.split(this);
+    }
+    if(sourceParts && sourceParts.length > 1)
+      sourceSplit = true;
+    else
+      sourceParts = [];
+    if(targetParts && targetParts.length > 1)
+      targetSplit = true;
+    else
+      targetParts = [];
+    if(sourceSplit || targetSplit) {
+      if(mutual)
+        results = [sourceParts, targetParts];
+      else
+        results = targetParts;
+    }
+    return results;
+  },
+  CLASS_NAME: "ZOO.Geometry.MultiLineString"
+});
+/**
+ * Class: ZOO.Geometry.Polygon 
+ * Polygon is a collection of <ZOO.Geometry.LinearRing>. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection> 
+ */
+ZOO.Geometry.Polygon = ZOO.Class(
+  ZOO.Geometry.Collection, {
+  componentTypes: ["ZOO.Geometry.LinearRing"],
+  /**
+   * Constructor: ZOO.Geometry.Polygon
+   * Constructor for a Polygon geometry. 
+   * The first ring (this.component[0])is the outer bounds of the polygon and 
+   * all subsequent rings (this.component[1-n]) are internal holes.
+   *
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.LinearRing>)} 
+   */
+  initialize: function(components) {
+    ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
+  },
+  /** 
+   * Method: getArea
+   * Calculated by subtracting the areas of the internal holes from the 
+   *   area of the outer hole.
+   * 
+   * Returns:
+   * {float} The area of the geometry
+   */
+  getArea: function() {
+    var area = 0.0;
+    if ( this.components && (this.components.length > 0)) {
+      area += Math.abs(this.components[0].getArea());
+      for (var i=1, len=this.components.length; i<len; i++) {
+        area -= Math.abs(this.components[i].getArea());
+      }
+    }
+    return area;
+  },
+  /** 
+   * APIMethod: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate geodesic area of the polygon in square meters.
+   */
+  getGeodesicArea: function(projection) {
+    var area = 0.0;
+    if(this.components && (this.components.length > 0)) {
+      area += Math.abs(this.components[0].getGeodesicArea(projection));
+      for(var i=1, len=this.components.length; i<len; i++) {
+          area -= Math.abs(this.components[i].getGeodesicArea(projection));
+      }
+    }
+    return area;
+  },
+  /**
+   * Method: containsPoint
+   * Test if a point is inside a polygon.  Points on a polygon edge are
+   *     considered inside.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   *
+   * Returns:
+   * {Boolean | Number} The point is inside the polygon.  Returns 1 if the
+   *     point is on an edge.  Returns boolean otherwise.
+   */
+  containsPoint: function(point) {
+    var numRings = this.components.length;
+    var contained = false;
+    if(numRings > 0) {
+    // check exterior ring - 1 means on edge, boolean otherwise
+      contained = this.components[0].containsPoint(point);
+      if(contained !== 1) {
+        if(contained && numRings > 1) {
+          // check interior rings
+          var hole;
+          for(var i=1; i<numRings; ++i) {
+            hole = this.components[i].containsPoint(point);
+            if(hole) {
+              if(hole === 1)
+                contained = 1;
+              else
+                contained = false;
+              break;
+            }
+          }
+        }
+      }
+    }
+    return contained;
+  },
+  intersects: function(geometry) {
+    var intersect = false;
+    var i, len;
+    if(geometry.CLASS_NAME == "ZOO.Geometry.Point") {
+      intersect = this.containsPoint(geometry);
+    } else if(geometry.CLASS_NAME == "ZOO.Geometry.LineString" ||
+              geometry.CLASS_NAME == "ZOO.Geometry.LinearRing") {
+      // check if rings/linestrings intersect
+      for(i=0, len=this.components.length; i<len; ++i) {
+        intersect = geometry.intersects(this.components[i]);
+        if(intersect) {
+          break;
+        }
+      }
+      if(!intersect) {
+        // check if this poly contains points of the ring/linestring
+        for(i=0, len=geometry.components.length; i<len; ++i) {
+          intersect = this.containsPoint(geometry.components[i]);
+          if(intersect) {
+            break;
+          }
+        }
+      }
+    } else {
+      for(i=0, len=geometry.components.length; i<len; ++ i) {
+        intersect = this.intersects(geometry.components[i]);
+        if(intersect)
+          break;
+      }
+    }
+    // check case where this poly is wholly contained by another
+    if(!intersect && geometry.CLASS_NAME == "ZOO.Geometry.Polygon") {
+      // exterior ring points will be contained in the other geometry
+      var ring = this.components[0];
+      for(i=0, len=ring.components.length; i<len; ++i) {
+        intersect = geometry.containsPoint(ring.components[i]);
+        if(intersect)
+          break;
+      }
+    }
+    return intersect;
+  },
+  distanceTo: function(geometry, options) {
+    var edge = !(options && options.edge === false);
+    var result;
+    // this is the case where we might not be looking for distance to edge
+    if(!edge && this.intersects(geometry))
+      result = 0;
+    else
+      result = ZOO.Geometry.Collection.prototype.distanceTo.apply(
+          this, [geometry, options]
+          );
+    return result;
+  },
+  CLASS_NAME: "ZOO.Geometry.Polygon"
+});
+/**
+ * Method: createRegularPolygon
+ * Create a regular polygon around a radius. Useful for creating circles 
+ * and the like.
+ *
+ * Parameters:
+ * origin - {<ZOO.Geometry.Point>} center of polygon.
+ * radius - {Float} distance to vertex, in map units.
+ * sides - {Integer} Number of sides. 20 approximates a circle.
+ * rotation - {Float} original angle of rotation, in degrees.
+ */
+ZOO.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {  
+    var angle = Math.PI * ((1/sides) - (1/2));
+    if(rotation) {
+        angle += (rotation / 180) * Math.PI;
+    }
+    var rotatedAngle, x, y;
+    var points = [];
+    for(var i=0; i<sides; ++i) {
+        rotatedAngle = angle + (i * 2 * Math.PI / sides);
+        x = origin.x + (radius * Math.cos(rotatedAngle));
+        y = origin.y + (radius * Math.sin(rotatedAngle));
+        points.push(new ZOO.Geometry.Point(x, y));
+    }
+    var ring = new ZOO.Geometry.LinearRing(points);
+    return new ZOO.Geometry.Polygon([ring]);
+};
+/**
+ * Class: ZOO.Geometry.MultiPolygon
+ * MultiPolygon is a geometry with multiple <ZOO.Geometry.Polygon>
+ * components.  Create a new instance with the <ZOO.Geometry.MultiPolygon>
+ * constructor.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
+ZOO.Geometry.MultiPolygon = ZOO.Class(
+  ZOO.Geometry.Collection, {
+  componentTypes: ["ZOO.Geometry.Polygon"],
+  /**
+   * Constructor: ZOO.Geometry.MultiPolygon
+   * Create a new MultiPolygon geometry
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.Polygon>)} An array of polygons
+   *              used to generate the MultiPolygon
+   *
+   */
+  initialize: function(components) {
+    ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
+  },
+  CLASS_NAME: "ZOO.Geometry.MultiPolygon"
+});
+/**
+ * Class: ZOO.Process
+ * Used to query OGC WPS process defined by its URL and its identifier. 
+ * Usefull for chaining localhost process.
+ */
+ZOO.Process = ZOO.Class({
+  /**
+   * Property: schemaLocation
+   * {String} Schema location for a particular minor version.
+   */
+  schemaLocation: "http://www.opengis.net/wps/1.0.0/../wpsExecute_request.xsd",
+  /**
+   * Property: namespaces
+   * {Object} Mapping of namespace aliases to namespace URIs.
+   */
+  namespaces: {
+    ows: "http://www.opengis.net/ows/1.1",
+    wps: "http://www.opengis.net/wps/1.0.0",
+    xlink: "http://www.w3.org/1999/xlink",
+    xsi: "http://www.w3.org/2001/XMLSchema-instance",
+  },
+  /**
+   * Property: url
+   * {String} The OGC's Web PRocessing Service URL, 
+   *          default is http://localhost/zoo.
+   */
+  url: 'http://localhost/zoo',
+  /**
+   * Property: identifier
+   * {String} Process identifier in the OGC's Web Processing Service.
+   */
+  identifier: null,
+  /**
+   * Constructor: ZOO.Process
+   * Create a new Process
+   *
+   * Parameters:
+   * url - {String} The OGC's Web Processing Service URL.
+   * identifier - {String} The process identifier in the OGC's Web Processing Service.
+   *
+   */
+  initialize: function(url,identifier) {
+    this.url = url;
+    this.identifier = identifier;
+  },
+  /**
+   * Method: Execute
+   * Query the OGC's Web PRocessing Servcie to Execute the process.
+   *
+   * Parameters:
+   * inputs - {Object}
+   *
+   * Returns:
+   * {String} The OGC's Web processing Service XML response. The result 
+   *          needs to be interpreted.
+   */
+  Execute: function(inputs,outputs) {
+    if (this.identifier == null)
+      return null;
+    var body = new XML('<wps:Execute service="WPS" version="1.0.0" xmlns:wps="'+this.namespaces['wps']+'" xmlns:ows="'+this.namespaces['ows']+'" xmlns:xlink="'+this.namespaces['xlink']+'" xmlns:xsi="'+this.namespaces['xsi']+'" xsi:schemaLocation="'+this.schemaLocation+'"><ows:Identifier>'+this.identifier+'</ows:Identifier>'+this.buildDataInputsNode(inputs)+this.buildDataOutputsNode(outputs)+'</wps:Execute>');
+    body = body.toXMLString();
+    var headers=['Content-Type: text/xml; charset=UTF-8'];
+      if(arguments.length>2){
+	headers[headers.length]=arguments[2];
+      }
+    var response = ZOO.Request.Post(this.url,body,headers);
+    return response;
+  },
+  buildOutput:{
+    /**
+     * Method: buildOutput.ResponseDocument
+     * Given an E4XElement representing the WPS ResponseDocument output.
+     *
+     * Parameters:
+     * identifier - {String} the input indetifier
+     * data - {Object} A WPS complex data input.
+     *
+     * Returns:
+     * {E4XElement} A WPS Input node.
+     */
+    'ResponseDocument': function(identifier,obj) {
+      var output = new XML('<wps:ResponseForm xmlns:wps="'+this.namespaces['wps']+'"><wps:ResponseDocument><wps:Output'+(obj["mimeType"]?' mimeType="'+obj["mimeType"]+'" ':'')+(obj["encoding"]?' encoding="'+obj["encoding"]+'" ':'')+(obj["asReference"]?' asReference="'+obj["asReference"]+'" ':'')+'><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier></wps:Output></wps:ResponseDocument></wps:ResponseForm>');
+      if (obj.encoding)
+        output.*::Data.*::ComplexData.@encoding = obj.encoding;
+      if (obj.schema)
+        output.*::Data.*::ComplexData.@schema = obj.schema;
+      output = output.toXMLString();
+      return output;
+    },
+    'RawDataOutput': function(identifier,obj) {
+      var output = new XML('<wps:ResponseForm xmlns:wps="'+this.namespaces['wps']+'"><wps:RawDataOutput '+(obj["mimeType"]?' mimeType="'+obj["mimeType"]+'" ':'')+(obj["encoding"]?' encoding="'+obj["encoding"]+'" ':'')+'><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier></wps:RawDataOutput></wps:ResponseForm>');
+      if (obj.encoding)
+        output.*::Data.*::ComplexData.@encoding = obj.encoding;
+      if (obj.schema)
+        output.*::Data.*::ComplexData.@schema = obj.schema;
+      output = output.toXMLString();
+      return output;
+    }
+
+  },
+  /**
+   * Property: buildInput
+   * Object containing methods to build WPS inputs.
+   */
+  buildInput: {
+    /**
+     * Method: buildInput.complex
+     * Given an E4XElement representing the WPS complex data input.
+     *
+     * Parameters:
+     * identifier - {String} the input indetifier
+     * data - {Object} A WPS complex data input.
+     *
+     * Returns:
+     * {E4XElement} A WPS Input node.
+     */
+    'complex': function(identifier,data) {
+      var input = new XML('<wps:Input xmlns:wps="'+this.namespaces['wps']+'"><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier>'+(data.value?'<wps:Data><wps:ComplexData><![CDATA['+data.value+']]></wps:ComplexData></wps:Data>':(data.xlink?'<wps:Reference xmlns:xlink="'+this.namespaces['xlink']+'" xlink:href="'+data.xlink+'" mimeType="'+data.mimeType+'" />':''))+'</wps:Input>');
+      if(data.xlink)
+	input.*::Reference.@mimeType = data.mimetype ? data.mimetype : 'application/json';
+      else
+	input.*::Data.*::ComplexData.@mimeType = data.mimetype ? data.mimetype : 'application/json';
+      if (data.encoding)
+        input.*::Data.*::ComplexData.@encoding = data.encoding;
+      if (data.schema)
+        input.*::Data.*::ComplexData.@schema = data.schema;
+      input = input.toXMLString();
+      return input;
+    },
+    /**
+     * Method: buildInput.reference
+     * Given an E4XElement representing the WPS reference input.
+     *
+     * Parameters:
+     * identifier - {String} the input indetifier
+     * data - {Object} A WPS reference input.
+     *
+     * Returns:
+     * {E4XElement} A WPS Input node.
+     */
+    'reference': function(identifier,data) {
+      return '<wps:Input xmlns:wps="'+this.namespaces['wps']+'"><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier><wps:Reference xmlns:xlink="'+this.namespaces['xlink']+'" xlink:href="'+data.value.replace('&','&amp;','gi')+'"/></wps:Input>';
+    },
+    /**
+     * Method: buildInput.literal
+     * Given an E4XElement representing the WPS literal data input.
+     *
+     * Parameters:
+     * identifier - {String} the input indetifier
+     * data - {Object} A WPS literal data input.
+     *
+     * Returns:
+     * {E4XElement} The WPS Input node.
+     */
+    'literal': function(identifier,data) {
+	if(data && !eval(data["isArray"])){
+	    var input = new XML('<wps:Input xmlns:wps="'+this.namespaces['wps']+'"><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier><wps:Data><wps:LiteralData>'+data.value+'</wps:LiteralData></wps:Data></wps:Input>');
+      if (data.type)
+        input.*::Data.*::LiteralData.@dataType = data.type;
+      if (data.uom)
+        input.*::Data.*::LiteralData.@uom = data.uom;
+      input = input.toXMLString();
+      return input;
+	}else if(data){
+	    var inputf="";
+	    for(i=0;i<parseInt(data["length"]);i++){
+		var input = new XML('<wps:Input xmlns:wps="'+this.namespaces['wps']+'"><ows:Identifier xmlns:ows="'+this.namespaces['ows']+'">'+identifier+'</ows:Identifier><wps:Data><wps:LiteralData>'+data.value[i]+'</wps:LiteralData></wps:Data></wps:Input>');
+		if (data.type)
+		    input.*::Data.*::LiteralData.@dataType = data.type;
+		if (data.uom)
+		    input.*::Data.*::LiteralData.@uom = data.uom;
+		inputf += input.toXMLString();
+	    }
+	    return inputf;
+	}
+	
+    }
+  },
+  /**
+   * Method: buildDataInputsNode
+   * Method to build the WPS DataInputs element.
+   *
+   * Parameters:
+   * inputs - {Object}
+   *
+   * Returns:
+   * {E4XElement} The WPS DataInputs node for Execute query.
+   */
+  buildDataInputsNode:function(inputs){
+    var data, builder, inputsArray=[];
+    for (var attr in inputs) {
+      data = inputs[attr];
+	if (data && (data.mimetype || data.type == 'complex'))
+        builder = this.buildInput['complex'];
+	else if (data && (data.type == 'reference' || data.type == 'url'))
+        builder = this.buildInput['reference'];
+      else
+        builder = this.buildInput['literal'];
+      inputsArray.push(builder.apply(this,[attr,data]));
+    }
+    return '<wps:DataInputs xmlns:wps="'+this.namespaces['wps']+'">'+inputsArray.join('\n')+'</wps:DataInputs>';
+  },
+
+  buildDataOutputsNode:function(outputs){
+    var data, builder, outputsArray=[];
+    for (var attr in outputs) {
+      data = outputs[attr];
+      builder = this.buildOutput[data.type];
+      outputsArray.push(builder.apply(this,[attr,data]));
+    }
+    return outputsArray.join('\n');
+  },
+
+  CLASS_NAME: "ZOO.Process"
+});
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-proj4js.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-proj4js.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-api/js/ZOO-proj4js.js	(revision 672)
@@ -0,0 +1,258 @@
+/*
+  proj4js.js -- Javascript reprojection library. 
+  
+  Authors:      Mike Adair madairATdmsolutions.ca
+                Richard Greenwood richATgreenwoodmap.com
+                Didier Richard didier.richardATign.fr
+                Stephen Irons
+  License:      MIT as per: http://trac.osgeo.org/proj4js/browser/trunk/LICENSE
+                Note: This program is an almost direct port of the C library
+                Proj4.
+*/
+
+/**
+ * Author : René-Luc D'Hont
+ *
+ * Copyright 2010 3liz SARL. All rights reserved.
+ */
+
+Proj4js={defaultDatum:'WGS84',transform:function(source,dest,point){if(!source.readyToUse||!dest.readyToUse){this.reportError("Proj4js initialization for "+source.srsCode+" not yet complete");return point;}
+if((source.srsProjNumber=="900913"&&dest.datumCode!="WGS84")||(dest.srsProjNumber=="900913"&&source.datumCode!="WGS84")){var wgs84=Proj4js.WGS84;this.transform(source,wgs84,point);source=wgs84;}
+if(source.projName=="longlat"){point.x*=Proj4js.common.D2R;point.y*=Proj4js.common.D2R;}else{if(source.to_meter){point.x*=source.to_meter;point.y*=source.to_meter;}
+source.inverse(point);}
+if(source.from_greenwich){point.x+=source.from_greenwich;}
+point=this.datum_transform(source.datum,dest.datum,point);if(dest.from_greenwich){point.x-=dest.from_greenwich;}
+if(dest.projName=="longlat"){point.x*=Proj4js.common.R2D;point.y*=Proj4js.common.R2D;}else{dest.forward(point);if(dest.to_meter){point.x/=dest.to_meter;point.y/=dest.to_meter;}}
+return point;},datum_transform:function(source,dest,point){if(source.compare_datums(dest)){return point;}
+if(source.datum_type==Proj4js.common.PJD_NODATUM||dest.datum_type==Proj4js.common.PJD_NODATUM){return point;}
+if(source.datum_type==Proj4js.common.PJD_GRIDSHIFT)
+{alert("ERROR: Grid shift transformations are not implemented yet.");}
+if(dest.datum_type==Proj4js.common.PJD_GRIDSHIFT)
+{alert("ERROR: Grid shift transformations are not implemented yet.");}
+if(source.es!=dest.es||source.a!=dest.a||source.datum_type==Proj4js.common.PJD_3PARAM||source.datum_type==Proj4js.common.PJD_7PARAM||dest.datum_type==Proj4js.common.PJD_3PARAM||dest.datum_type==Proj4js.common.PJD_7PARAM)
+{source.geodetic_to_geocentric(point);if(source.datum_type==Proj4js.common.PJD_3PARAM||source.datum_type==Proj4js.common.PJD_7PARAM){source.geocentric_to_wgs84(point);}
+if(dest.datum_type==Proj4js.common.PJD_3PARAM||dest.datum_type==Proj4js.common.PJD_7PARAM){dest.geocentric_from_wgs84(point);}
+dest.geocentric_to_geodetic(point);}
+if(dest.datum_type==Proj4js.common.PJD_GRIDSHIFT)
+{alert("ERROR: Grid shift transformations are not implemented yet.");}
+return point;},reportError:function(msg){},extend:function(destination,source){destination=destination||{};if(source){for(var property in source){var value=source[property];if(value!==undefined){destination[property]=value;}}}
+return destination;},Class:function(){var Class=function(){this.initialize.apply(this,arguments);};var extended={};var parent;for(var i=0;i<arguments.length;++i){if(typeof arguments[i]=="function"){parent=arguments[i].prototype;}else{parent=arguments[i];}
+Proj4js.extend(extended,parent);}
+Class.prototype=extended;return Class;},bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},scriptName:"proj4js-compressed.js",defsLookupService:'http://spatialreference.org/ref',libPath:null,getScriptLocation:function(){if(this.libPath)return this.libPath;var scriptName=this.scriptName;var scriptNameLen=scriptName.length;var scripts=document.getElementsByTagName('script');for(var i=0;i<scripts.length;i++){var src=scripts[i].getAttribute('src');if(src){var index=src.lastIndexOf(scriptName);if((index>-1)&&(index+scriptNameLen==src.length)){this.libPath=src.slice(0,-scriptNameLen);break;}}}
+return this.libPath||"";},
+  loadScript:function(url,onload,onfail,loadCheck){
+    var script = [];
+  var script = ZOORequest('GET',url);
+  try {
+    eval(script);
+    onload();
+  } catch (e) {
+    onfail();
+  }
+    /*
+    var script=document.createElement('script');
+    script.defer=false;
+    script.type="text/javascript";
+    script.id=url;
+    script.src=url;
+    script.onload=onload;
+    script.onerror=onfail;
+    script.loadCheck=loadCheck;
+    if(/MSIE/.test(navigator.userAgent)){script.onreadystatechange=this.checkReadyState;}
+    document.getElementsByTagName('head')[0].appendChild(script);
+    */
+  },
+  checkReadyState:function(){if(this.readyState=='loaded'){if(!this.loadCheck()){this.onerror();}else{this.onload();}}}};Proj4js.Proj=Proj4js.Class({readyToUse:false,title:null,projName:null,units:null,datum:null,x0:0,y0:0,initialize:function(srsCode){this.srsCodeInput=srsCode;if(srsCode.indexOf('urn:')==0){var urn=srsCode.split(':');if((urn[1]=='ogc'||urn[1]=='x-ogc')&&(urn[2]=='def')&&(urn[3]=='crs')){srsCode=urn[4]+':'+urn[urn.length-1];}}else if(srsCode.indexOf('http://')==0){var url=srsCode.split('#');if(url[0].match(/epsg.org/)){srsCode='EPSG:'+url[1];}else if(url[0].match(/RIG.xml/)){srsCode='IGNF:'+url[1];}}
+this.srsCode=srsCode.toUpperCase();if(this.srsCode.indexOf("EPSG")==0){this.srsCode=this.srsCode;this.srsAuth='epsg';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("IGNF")==0){this.srsCode=this.srsCode;this.srsAuth='IGNF';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("CRS")==0){this.srsCode=this.srsCode;this.srsAuth='CRS';this.srsProjNumber=this.srsCode.substring(4);}else{this.srsAuth='';this.srsProjNumber=this.srsCode;}
+this.loadProjDefinition();},
+  loadProjDefinition:function(){
+    if(Proj4js.defs[this.srsCode]){this.defsLoaded();return;}
+    this.loadFromService();
+  /*
+    var url=Proj4js.getScriptLocation()+'defs/'+this.srsAuth.toUpperCase()+this.srsProjNumber+'.js';
+    Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.loadFromService,this),Proj4js.bind(this.checkDefsLoaded,this));
+    */
+  },
+  loadFromService:function(){var url=Proj4js.defsLookupService+'/'+this.srsAuth+'/'+this.srsProjNumber+'/proj4js/';Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.defsFailed,this),Proj4js.bind(this.checkDefsLoaded,this));},defsLoaded:function(){this.parseDefs();this.loadProjCode(this.projName);},checkDefsLoaded:function(){if(Proj4js.defs[this.srsCode]){return true;}else{return false;}},defsFailed:function(){Proj4js.reportError('failed to load projection definition for: '+this.srsCode);Proj4js.defs[this.srsCode]=Proj4js.defs['WGS84'];this.defsLoaded();},
+  loadProjCode:function(projName){
+    if(Proj4js.Proj[projName]){this.initTransforms();return;}
+    var url=Proj4js.getScriptLocation()+'projCode/'+projName+'.js';
+    Proj4js.loadScript(url,Proj4js.bind(this.loadProjCodeSuccess,this,projName),Proj4js.bind(this.loadProjCodeFailure,this,projName),Proj4js.bind(this.checkCodeLoaded,this,projName));
+  },
+  loadProjCodeSuccess:function(projName){if(Proj4js.Proj[projName].dependsOn){this.loadProjCode(Proj4js.Proj[projName].dependsOn);}else{this.initTransforms();}},loadProjCodeFailure:function(projName){Proj4js.reportError("failed to find projection file for: "+projName);},checkCodeLoaded:function(projName){if(Proj4js.Proj[projName]){return true;}else{return false;}},initTransforms:function(){Proj4js.extend(this,Proj4js.Proj[this.projName]);this.init();this.readyToUse=true;},parseDefs:function(){this.defData=Proj4js.defs[this.srsCode];var paramName,paramVal;if(!this.defData){return;}
+var paramArray=this.defData.split("+");for(var prop=0;prop<paramArray.length;prop++){var property=paramArray[prop].split("=");paramName=property[0].toLowerCase();paramVal=property[1];switch(paramName.replace(/\s/gi,"")){case"":break;case"title":this.title=paramVal;break;case"proj":this.projName=paramVal.replace(/\s/gi,"");break;case"units":this.units=paramVal.replace(/\s/gi,"");break;case"datum":this.datumCode=paramVal.replace(/\s/gi,"");break;case"nadgrids":this.nagrids=paramVal.replace(/\s/gi,"");break;case"ellps":this.ellps=paramVal.replace(/\s/gi,"");break;case"a":this.a=parseFloat(paramVal);break;case"b":this.b=parseFloat(paramVal);break;case"rf":this.rf=parseFloat(paramVal);break;case"lat_0":this.lat0=paramVal*Proj4js.common.D2R;break;case"lat_1":this.lat1=paramVal*Proj4js.common.D2R;break;case"lat_2":this.lat2=paramVal*Proj4js.common.D2R;break;case"lat_ts":this.lat_ts=paramVal*Proj4js.common.D2R;break;case"lon_0":this.long0=paramVal*Proj4js.common.D2R;break;case"alpha":this.alpha=parseFloat(paramVal)*Proj4js.common.D2R;break;case"lonc":this.longc=paramVal*Proj4js.common.D2R;break;case"x_0":this.x0=parseFloat(paramVal);break;case"y_0":this.y0=parseFloat(paramVal);break;case"k_0":this.k0=parseFloat(paramVal);break;case"k":this.k0=parseFloat(paramVal);break;case"r_a":this.R_A=true;break;case"zone":this.zone=parseInt(paramVal);break;case"south":this.utmSouth=true;break;case"towgs84":this.datum_params=paramVal.split(",");break;case"to_meter":this.to_meter=parseFloat(paramVal);break;case"from_greenwich":this.from_greenwich=paramVal*Proj4js.common.D2R;break;case"pm":paramVal=paramVal.replace(/\s/gi,"");this.from_greenwich=Proj4js.PrimeMeridian[paramVal]?Proj4js.PrimeMeridian[paramVal]:parseFloat(paramVal);this.from_greenwich*=Proj4js.common.D2R;break;case"no_defs":break;default:}}
+this.deriveConstants();},deriveConstants:function(){if(this.nagrids=='@null')this.datumCode='none';if(this.datumCode&&this.datumCode!='none'){var datumDef=Proj4js.Datum[this.datumCode];if(datumDef){this.datum_params=datumDef.towgs84?datumDef.towgs84.split(','):null;this.ellps=datumDef.ellipse;this.datumName=datumDef.datumName?datumDef.datumName:this.datumCode;}}
+if(!this.a){var ellipse=Proj4js.Ellipsoid[this.ellps]?Proj4js.Ellipsoid[this.ellps]:Proj4js.Ellipsoid['WGS84'];Proj4js.extend(this,ellipse);}
+if(this.rf&&!this.b)this.b=(1.0-1.0/this.rf)*this.a;if(Math.abs(this.a-this.b)<Proj4js.common.EPSLN){this.sphere=true;this.b=this.a;}
+this.a2=this.a*this.a;this.b2=this.b*this.b;this.es=(this.a2-this.b2)/this.a2;this.e=Math.sqrt(this.es);if(this.R_A){this.a*=1.-this.es*(Proj4js.common.SIXTH+this.es*(Proj4js.common.RA4+this.es*Proj4js.common.RA6));this.a2=this.a*this.a;this.b2=this.b*this.b;this.es=0.;}
+this.ep2=(this.a2-this.b2)/this.b2;if(!this.k0)this.k0=1.0;this.datum=new Proj4js.datum(this);}});Proj4js.Proj.longlat={init:function(){},forward:function(pt){return pt;},inverse:function(pt){return pt;}};Proj4js.defs={'WGS84':"+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4326':"+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4269':"+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees",'EPSG:3785':"+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"};Proj4js.defs['GOOGLE']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:900913']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:102113']=Proj4js.defs['EPSG:3785'];Proj4js.common={PI:3.141592653589793238,HALF_PI:1.570796326794896619,TWO_PI:6.283185307179586477,FORTPI:0.78539816339744833,R2D:57.29577951308232088,D2R:0.01745329251994329577,SEC_TO_RAD:4.84813681109535993589914102357e-6,EPSLN:1.0e-10,MAX_ITER:20,COS_67P5:0.38268343236508977,AD_C:1.0026000,PJD_UNKNOWN:0,PJD_3PARAM:1,PJD_7PARAM:2,PJD_GRIDSHIFT:3,PJD_WGS84:4,PJD_NODATUM:5,SRS_WGS84_SEMIMAJOR:6378137.0,SIXTH:.1666666666666666667,RA4:.04722222222222222222,RA6:.02215608465608465608,RV4:.06944444444444444444,RV6:.04243827160493827160,msfnz:function(eccent,sinphi,cosphi){var con=eccent*sinphi;return cosphi/(Math.sqrt(1.0-con*con));},tsfnz:function(eccent,phi,sinphi){var con=eccent*sinphi;var com=.5*eccent;con=Math.pow(((1.0-con)/(1.0+con)),com);return(Math.tan(.5*(this.HALF_PI-phi))/con);},phi2z:function(eccent,ts){var eccnth=.5*eccent;var con,dphi;var phi=this.HALF_PI-2*Math.atan(ts);for(i=0;i<=15;i++){con=eccent*Math.sin(phi);dphi=this.HALF_PI-2*Math.atan(ts*(Math.pow(((1.0-con)/(1.0+con)),eccnth)))-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001)return phi;}
+alert("phi2z has NoConvergence");return(-9999);},qsfnz:function(eccent,sinphi){var con;if(eccent>1.0e-7){con=eccent*sinphi;return((1.0-eccent*eccent)*(sinphi/(1.0-con*con)-(.5/eccent)*Math.log((1.0-con)/(1.0+con))));}else{return(2.0*sinphi);}},asinz:function(x){if(Math.abs(x)>1.0){x=(x>1.0)?1.0:-1.0;}
+return Math.asin(x);},e0fn:function(x){return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));},e1fn:function(x){return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));},e2fn:function(x){return(0.05859375*x*x*(1.0+0.75*x));},e3fn:function(x){return(x*x*x*(35.0/3072.0));},mlfn:function(e0,e1,e2,e3,phi){return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));},srat:function(esinp,exp){return(Math.pow((1.0-esinp)/(1.0+esinp),exp));},sign:function(x){if(x<0.0)return(-1);else return(1);},adjust_lon:function(x){x=(Math.abs(x)<this.PI)?x:(x-(this.sign(x)*this.TWO_PI));return x;},adjust_lat:function(x){x=(Math.abs(x)<this.HALF_PI)?x:(x-(this.sign(x)*this.PI));return x;},latiso:function(eccent,phi,sinphi){if(Math.abs(phi)>this.HALF_PI)return+Number.NaN;if(phi==this.HALF_PI)return Number.POSITIVE_INFINITY;if(phi==-1.0*this.HALF_PI)return-1.0*Number.POSITIVE_INFINITY;var con=eccent*sinphi;return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;},fL:function(x,L){return 2.0*Math.atan(x*Math.exp(L))-this.HALF_PI;},invlatiso:function(eccent,ts){var phi=this.fL(1.0,ts);var Iphi=0.0;var con=0.0;do{Iphi=phi;con=eccent*Math.sin(Iphi);phi=this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)}while(Math.abs(phi-Iphi)>1.0e-12);return phi;},sinh:function(x)
+{var r=Math.exp(x);r=(r-1.0/r)/2.0;return r;},cosh:function(x)
+{var r=Math.exp(x);r=(r+1.0/r)/2.0;return r;},tanh:function(x)
+{var r=Math.exp(x);r=(r-1.0/r)/(r+1.0/r);return r;},asinh:function(x)
+{var s=(x>=0?1.0:-1.0);return s*(Math.log(Math.abs(x)+Math.sqrt(x*x+1.0)));},acosh:function(x)
+{return 2.0*Math.log(Math.sqrt((x+1.0)/2.0)+Math.sqrt((x-1.0)/2.0));},atanh:function(x)
+{return Math.log((x-1.0)/(x+1.0))/2.0;},gN:function(a,e,sinphi)
+{var temp=e*sinphi;return a/Math.sqrt(1.0-temp*temp);}};Proj4js.datum=Proj4js.Class({initialize:function(proj){this.datum_type=Proj4js.common.PJD_WGS84;if(proj.datumCode&&proj.datumCode=='none'){this.datum_type=Proj4js.common.PJD_NODATUM;}
+if(proj&&proj.datum_params){for(var i=0;i<proj.datum_params.length;i++){proj.datum_params[i]=parseFloat(proj.datum_params[i]);}
+if(proj.datum_params[0]!=0||proj.datum_params[1]!=0||proj.datum_params[2]!=0){this.datum_type=Proj4js.common.PJD_3PARAM;}
+if(proj.datum_params.length>3){if(proj.datum_params[3]!=0||proj.datum_params[4]!=0||proj.datum_params[5]!=0||proj.datum_params[6]!=0){this.datum_type=Proj4js.common.PJD_7PARAM;proj.datum_params[3]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[4]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[5]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[6]=(proj.datum_params[6]/1000000.0)+1.0;}}}
+if(proj){this.a=proj.a;this.b=proj.b;this.es=proj.es;this.ep2=proj.ep2;this.datum_params=proj.datum_params;}},compare_datums:function(dest){if(this.datum_type!=dest.datum_type){return false;}else if(this.a!=dest.a||Math.abs(this.es-dest.es)>0.000000000050){return false;}else if(this.datum_type==Proj4js.common.PJD_3PARAM){return(this.datum_params[0]==dest.datum_params[0]&&this.datum_params[1]==dest.datum_params[1]&&this.datum_params[2]==dest.datum_params[2]);}else if(this.datum_type==Proj4js.common.PJD_7PARAM){return(this.datum_params[0]==dest.datum_params[0]&&this.datum_params[1]==dest.datum_params[1]&&this.datum_params[2]==dest.datum_params[2]&&this.datum_params[3]==dest.datum_params[3]&&this.datum_params[4]==dest.datum_params[4]&&this.datum_params[5]==dest.datum_params[5]&&this.datum_params[6]==dest.datum_params[6]);}else if(this.datum_type==Proj4js.common.PJD_GRIDSHIFT){return strcmp(pj_param(this.params,"snadgrids").s,pj_param(dest.params,"snadgrids").s)==0;}else{return true;}},geodetic_to_geocentric:function(p){var Longitude=p.x;var Latitude=p.y;var Height=p.z?p.z:0;var X;var Y;var Z;var Error_Code=0;var Rn;var Sin_Lat;var Sin2_Lat;var Cos_Lat;if(Latitude<-Proj4js.common.HALF_PI&&Latitude>-1.001*Proj4js.common.HALF_PI){Latitude=-Proj4js.common.HALF_PI;}else if(Latitude>Proj4js.common.HALF_PI&&Latitude<1.001*Proj4js.common.HALF_PI){Latitude=Proj4js.common.HALF_PI;}else if((Latitude<-Proj4js.common.HALF_PI)||(Latitude>Proj4js.common.HALF_PI)){Proj4js.reportError('geocent:lat out of range:'+Latitude);return null;}
+if(Longitude>Proj4js.common.PI)Longitude-=(2*Proj4js.common.PI);Sin_Lat=Math.sin(Latitude);Cos_Lat=Math.cos(Latitude);Sin2_Lat=Sin_Lat*Sin_Lat;Rn=this.a/(Math.sqrt(1.0e0-this.es*Sin2_Lat));X=(Rn+Height)*Cos_Lat*Math.cos(Longitude);Y=(Rn+Height)*Cos_Lat*Math.sin(Longitude);Z=((Rn*(1-this.es))+Height)*Sin_Lat;p.x=X;p.y=Y;p.z=Z;return Error_Code;},geocentric_to_geodetic:function(p){var genau=1.E-12;var genau2=(genau*genau);var maxiter=30;var P;var RR;var CT;var ST;var RX;var RK;var RN;var CPHI0;var SPHI0;var CPHI;var SPHI;var SDPHI;var At_Pole;var iter;var X=p.x;var Y=p.y;var Z=p.z?p.z:0.0;var Longitude;var Latitude;var Height;At_Pole=false;P=Math.sqrt(X*X+Y*Y);RR=Math.sqrt(X*X+Y*Y+Z*Z);if(P/this.a<genau){At_Pole=true;Longitude=0.0;if(RR/this.a<genau){Latitude=Proj4js.common.HALF_PI;Height=-this.b;return;}}else{Longitude=Math.atan2(Y,X);}
+CT=Z/RR;ST=P/RR;RX=1.0/Math.sqrt(1.0-this.es*(2.0-this.es)*ST*ST);CPHI0=ST*(1.0-this.es)*RX;SPHI0=CT*RX;iter=0;do
+{iter++;RN=this.a/Math.sqrt(1.0-this.es*SPHI0*SPHI0);Height=P*CPHI0+Z*SPHI0-RN*(1.0-this.es*SPHI0*SPHI0);RK=this.es*RN/(RN+Height);RX=1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST);CPHI=ST*(1.0-RK)*RX;SPHI=CT*RX;SDPHI=SPHI*CPHI0-CPHI*SPHI0;CPHI0=CPHI;SPHI0=SPHI;}
+while(SDPHI*SDPHI>genau2&&iter<maxiter);Latitude=Math.atan(SPHI/Math.abs(CPHI));p.x=Longitude;p.y=Latitude;p.z=Height;return p;},geocentric_to_geodetic_noniter:function(p){var X=p.x;var Y=p.y;var Z=p.z?p.z:0;var Longitude;var Latitude;var Height;var W;var W2;var T0;var T1;var S0;var S1;var Sin_B0;var Sin3_B0;var Cos_B0;var Sin_p1;var Cos_p1;var Rn;var Sum;var At_Pole;X=parseFloat(X);Y=parseFloat(Y);Z=parseFloat(Z);At_Pole=false;if(X!=0.0)
+{Longitude=Math.atan2(Y,X);}
+else
+{if(Y>0)
+{Longitude=Proj4js.common.HALF_PI;}
+else if(Y<0)
+{Longitude=-Proj4js.common.HALF_PI;}
+else
+{At_Pole=true;Longitude=0.0;if(Z>0.0)
+{Latitude=Proj4js.common.HALF_PI;}
+else if(Z<0.0)
+{Latitude=-Proj4js.common.HALF_PI;}
+else
+{Latitude=Proj4js.common.HALF_PI;Height=-this.b;return;}}}
+W2=X*X+Y*Y;W=Math.sqrt(W2);T0=Z*Proj4js.common.AD_C;S0=Math.sqrt(T0*T0+W2);Sin_B0=T0/S0;Cos_B0=W/S0;Sin3_B0=Sin_B0*Sin_B0*Sin_B0;T1=Z+this.b*this.ep2*Sin3_B0;Sum=W-this.a*this.es*Cos_B0*Cos_B0*Cos_B0;S1=Math.sqrt(T1*T1+Sum*Sum);Sin_p1=T1/S1;Cos_p1=Sum/S1;Rn=this.a/Math.sqrt(1.0-this.es*Sin_p1*Sin_p1);if(Cos_p1>=Proj4js.common.COS_67P5)
+{Height=W/Cos_p1-Rn;}
+else if(Cos_p1<=-Proj4js.common.COS_67P5)
+{Height=W/-Cos_p1-Rn;}
+else
+{Height=Z/Sin_p1+Rn*(this.es-1.0);}
+if(At_Pole==false)
+{Latitude=Math.atan(Sin_p1/Cos_p1);}
+p.x=Longitude;p.y=Latitude;p.z=Height;return p;},geocentric_to_wgs84:function(p){if(this.datum_type==Proj4js.common.PJD_3PARAM)
+{p.x+=this.datum_params[0];p.y+=this.datum_params[1];p.z+=this.datum_params[2];}
+else if(this.datum_type==Proj4js.common.PJD_7PARAM)
+{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_out=M_BF*(p.x-Rz_BF*p.y+Ry_BF*p.z)+Dx_BF;var y_out=M_BF*(Rz_BF*p.x+p.y-Rx_BF*p.z)+Dy_BF;var z_out=M_BF*(-Ry_BF*p.x+Rx_BF*p.y+p.z)+Dz_BF;p.x=x_out;p.y=y_out;p.z=z_out;}},geocentric_from_wgs84:function(p){if(this.datum_type==Proj4js.common.PJD_3PARAM)
+{p.x-=this.datum_params[0];p.y-=this.datum_params[1];p.z-=this.datum_params[2];}
+else if(this.datum_type==Proj4js.common.PJD_7PARAM)
+{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_tmp=(p.x-Dx_BF)/M_BF;var y_tmp=(p.y-Dy_BF)/M_BF;var z_tmp=(p.z-Dz_BF)/M_BF;p.x=x_tmp+Rz_BF*y_tmp-Ry_BF*z_tmp;p.y=-Rz_BF*x_tmp+y_tmp+Rx_BF*z_tmp;p.z=Ry_BF*x_tmp-Rx_BF*y_tmp+z_tmp;}}});Proj4js.Point=Proj4js.Class({initialize:function(x,y,z){if(typeof x=='object'){this.x=x[0];this.y=x[1];this.z=x[2]||0.0;}else if(typeof x=='string'){var coords=x.split(',');this.x=parseFloat(coords[0]);this.y=parseFloat(coords[1]);this.z=parseFloat(coords[2])||0.0;}else{this.x=x;this.y=y;this.z=z||0.0;}},clone:function(){return new Proj4js.Point(this.x,this.y,this.z);},toString:function(){return("x="+this.x+",y="+this.y);},toShortString:function(){return(this.x+", "+this.y);}});Proj4js.PrimeMeridian={"greenwich":0.0,"lisbon":-9.131906111111,"paris":2.337229166667,"bogota":-74.080916666667,"madrid":-3.687938888889,"rome":12.452333333333,"bern":7.439583333333,"jakarta":106.807719444444,"ferro":-17.666666666667,"brussels":4.367975,"stockholm":18.058277777778,"athens":23.7163375,"oslo":10.722916666667};Proj4js.Ellipsoid={"MERIT":{a:6378137.0,rf:298.257,ellipseName:"MERIT 1983"},"SGS85":{a:6378136.0,rf:298.257,ellipseName:"Soviet Geodetic System 85"},"GRS80":{a:6378137.0,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},"IAU76":{a:6378140.0,rf:298.257,ellipseName:"IAU 1976"},"airy":{a:6377563.396,b:6356256.910,ellipseName:"Airy 1830"},"APL4.":{a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},"NWL9D":{a:6378145.0,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},"mod_airy":{a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},"andrae":{a:6377104.43,rf:300.0,ellipseName:"Andrae 1876 (Den., Iclnd.)"},"aust_SA":{a:6378160.0,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},"GRS67":{a:6378160.0,rf:298.2471674270,ellipseName:"GRS 67(IUGG 1967)"},"bessel":{a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},"bess_nam":{a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},"clrk66":{a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},"clrk80":{a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},"CPM":{a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},"delmbr":{a:6376428.0,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},"engelis":{a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},"evrst30":{a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},"evrst48":{a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},"evrst56":{a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},"evrst69":{a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},"evrstSS":{a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},"fschr60":{a:6378166.0,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},"fschr60m":{a:6378155.0,rf:298.3,ellipseName:"Fischer 1960"},"fschr68":{a:6378150.0,rf:298.3,ellipseName:"Fischer 1968"},"helmert":{a:6378200.0,rf:298.3,ellipseName:"Helmert 1906"},"hough":{a:6378270.0,rf:297.0,ellipseName:"Hough"},"intl":{a:6378388.0,rf:297.0,ellipseName:"International 1909 (Hayford)"},"kaula":{a:6378163.0,rf:298.24,ellipseName:"Kaula 1961"},"lerch":{a:6378139.0,rf:298.257,ellipseName:"Lerch 1979"},"mprts":{a:6397300.0,rf:191.0,ellipseName:"Maupertius 1738"},"new_intl":{a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},"plessis":{a:6376523.0,rf:6355863.0,ellipseName:"Plessis 1817 (France)"},"krass":{a:6378245.0,rf:298.3,ellipseName:"Krassovsky, 1942"},"SEasia":{a:6378155.0,b:6356773.3205,ellipseName:"Southeast Asia"},"walbeck":{a:6376896.0,b:6355834.8467,ellipseName:"Walbeck"},"WGS60":{a:6378165.0,rf:298.3,ellipseName:"WGS 60"},"WGS66":{a:6378145.0,rf:298.25,ellipseName:"WGS 66"},"WGS72":{a:6378135.0,rf:298.26,ellipseName:"WGS 72"},"WGS84":{a:6378137.0,rf:298.257223563,ellipseName:"WGS 84"},"sphere":{a:6370997.0,b:6370997.0,ellipseName:"Normal Sphere (r=6370997)"}};Proj4js.Datum={"WGS84":{towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},"GGRS87":{towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},"NAD83":{towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},"NAD27":{nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},"potsdam":{towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},"carthage":{towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},"hermannskogel":{towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},"ire65":{towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},"nzgd49":{towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},"OSGB36":{towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"}};Proj4js.WGS84=new Proj4js.Proj('WGS84');Proj4js.Datum['OSB36']=Proj4js.Datum['OSGB36'];Proj4js.Proj.aea={init:function(){if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("aeaInitEqualLatitudes");return;}
+this.temp=this.b/this.a;this.es=1.0-Math.pow(this.temp,2);this.e3=Math.sqrt(this.es);this.sin_po=Math.sin(this.lat1);this.cos_po=Math.cos(this.lat1);this.t1=this.sin_po;this.con=this.sin_po;this.ms1=Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);this.qs1=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);this.sin_po=Math.sin(this.lat2);this.cos_po=Math.cos(this.lat2);this.t2=this.sin_po;this.ms2=Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);this.qs2=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);this.sin_po=Math.sin(this.lat0);this.cos_po=Math.cos(this.lat0);this.t3=this.sin_po;this.qs0=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);if(Math.abs(this.lat1-this.lat2)>Proj4js.common.EPSLN){this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1);}else{this.ns0=this.con;}
+this.c=this.ms1*this.ms1+this.ns0*this.qs1;this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0;},forward:function(p){var lon=p.x;var lat=p.y;this.sin_phi=Math.sin(lat);this.cos_phi=Math.cos(lat);var qs=Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi);var rh1=this.a*Math.sqrt(this.c-this.ns0*qs)/this.ns0;var theta=this.ns0*Proj4js.common.adjust_lon(lon-this.long0);var x=rh1*Math.sin(theta)+this.x0;var y=this.rh-rh1*Math.cos(theta)+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var rh1,qs,con,theta,lon,lat;p.x-=this.x0;p.y=this.rh-p.y+this.y0;if(this.ns0>=0){rh1=Math.sqrt(p.x*p.x+p.y*p.y);con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;}
+theta=0.0;if(rh1!=0.0){theta=Math.atan2(con*p.x,con*p.y);}
+con=rh1*this.ns0/this.a;qs=(this.c-con*con)/this.ns0;if(this.e3>=1e-10){con=1-.5*(1.0-this.es)*Math.log((1.0-this.e3)/(1.0+this.e3))/this.e3;if(Math.abs(Math.abs(con)-Math.abs(qs))>.0000000001){lat=this.phi1z(this.e3,qs);}else{if(qs>=0){lat=.5*PI;}else{lat=-.5*PI;}}}else{lat=this.phi1z(e3,qs);}
+lon=Proj4js.common.adjust_lon(theta/this.ns0+this.long0);p.x=lon;p.y=lat;return p;},phi1z:function(eccent,qs){var con,com,dphi;var phi=Proj4js.common.asinz(.5*qs);if(eccent<Proj4js.common.EPSLN)return phi;var eccnts=eccent*eccent;for(var i=1;i<=25;i++){sinphi=Math.sin(phi);cosphi=Math.cos(phi);con=eccent*sinphi;com=1.0-con*con;dphi=.5*com*com/cosphi*(qs/(1.0-eccnts)-sinphi/com+.5/eccent*Math.log((1.0-con)/(1.0+con)));phi=phi+dphi;if(Math.abs(dphi)<=1e-7)return phi;}
+Proj4js.reportError("aea:phi1z:Convergence error");return null;}};Proj4js.Proj.sterea={dependsOn:'gauss',init:function(){Proj4js.Proj['gauss'].init.apply(this);if(!this.rc){Proj4js.reportError("sterea:init:E_ERROR_0");return;}
+this.sinc0=Math.sin(this.phic0);this.cosc0=Math.cos(this.phic0);this.R2=2.0*this.rc;if(!this.title)this.title="Oblique Stereographic Alternative";},forward:function(p){p.x=Proj4js.common.adjust_lon(p.x-this.long0);Proj4js.Proj['gauss'].forward.apply(this,[p]);sinc=Math.sin(p.y);cosc=Math.cos(p.y);cosl=Math.cos(p.x);k=this.k0*this.R2/(1.0+this.sinc0*sinc+this.cosc0*cosc*cosl);p.x=k*cosc*Math.sin(p.x);p.y=k*(this.cosc0*sinc-this.sinc0*cosc*cosl);p.x=this.a*p.x+this.x0;p.y=this.a*p.y+this.y0;return p;},inverse:function(p){var lon,lat;p.x=(p.x-this.x0)/this.a;p.y=(p.y-this.y0)/this.a;p.x/=this.k0;p.y/=this.k0;if((rho=Math.sqrt(p.x*p.x+p.y*p.y))){c=2.0*Math.atan2(rho,this.R2);sinc=Math.sin(c);cosc=Math.cos(c);lat=Math.asin(cosc*this.sinc0+p.y*sinc*this.cosc0/rho);lon=Math.atan2(p.x*sinc,rho*this.cosc0*cosc-p.y*this.sinc0*sinc);}else{lat=this.phic0;lon=0.;}
+p.x=lon;p.y=lat;Proj4js.Proj['gauss'].inverse.apply(this,[p]);p.x=Proj4js.common.adjust_lon(p.x+this.long0);return p;}};function phi4z(eccent,e0,e1,e2,e3,a,b,c,phi){var sinphi,sin2ph,tanph,ml,mlp,con1,con2,con3,dphi,i;phi=a;for(i=1;i<=15;i++){sinphi=Math.sin(phi);tanphi=Math.tan(phi);c=tanphi*Math.sqrt(1.0-eccent*sinphi*sinphi);sin2ph=Math.sin(2.0*phi);ml=e0*phi-e1*sin2ph+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi);mlp=e0-2.0*e1*Math.cos(2.0*phi)+4.0*e2*Math.cos(4.0*phi)-6.0*e3*Math.cos(6.0*phi);con1=2.0*ml+c*(ml*ml+b)-2.0*a*(c*ml+1.0);con2=eccent*sin2ph*(ml*ml+b-2.0*a*ml)/(2.0*c);con3=2.0*(a-ml)*(c*mlp-2.0/sin2ph)-2.0*mlp;dphi=con1/(con2+con3);phi+=dphi;if(Math.abs(dphi)<=.0000000001)return(phi);}
+Proj4js.reportError("phi4z: No convergence");return null;}
+function e4fn(x){var con,com;con=1.0+x;com=1.0-x;return(Math.sqrt((Math.pow(con,con))*(Math.pow(com,com))));}
+Proj4js.Proj.poly={init:function(){var temp;if(this.lat0=0)this.lat0=90;this.temp=this.b/this.a;this.es=1.0-Math.pow(this.temp,2);this.e=Math.sqrt(this.es);this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.ml0=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);},forward:function(p){var sinphi,cosphi;var al;var c;var con,ml;var ms;var x,y;var lon=p.x;var lat=p.y;con=Proj4js.common.adjust_lon(lon-this.long0);if(Math.abs(lat)<=.0000001){x=this.x0+this.a*con;y=this.y0-this.a*this.ml0;}else{sinphi=Math.sin(lat);cosphi=Math.cos(lat);ml=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);ms=Proj4js.common.msfnz(this.e,sinphi,cosphi);con=sinphi;x=this.x0+this.a*ms*Math.sin(con)/sinphi;y=this.y0+this.a*(ml-this.ml0+ms*(1.0-Math.cos(con))/sinphi);}
+p.x=x;p.y=y;return p;},inverse:function(p){var sin_phi,cos_phi;var al;var b;var c;var con,ml;var iflg;var lon,lat;p.x-=this.x0;p.y-=this.y0;al=this.ml0+p.y/this.a;iflg=0;if(Math.abs(al)<=.0000001){lon=p.x/this.a+this.long0;lat=0.0;}else{b=al*al+(p.x/this.a)*(p.x/this.a);iflg=phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,b,c,lat);if(iflg!=1)return(iflg);lon=Proj4js.common.adjust_lon((Proj4js.common.asinz(p.x*c/this.a)/Math.sin(lat))+this.long0);}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.equi={init:function(){if(!this.x0)this.x0=0;if(!this.y0)this.y0=0;if(!this.lat0)this.lat0=0;if(!this.long0)this.long0=0;},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon*Math.cos(this.lat0);var y=this.y0+this.a*lat;this.t1=x;this.t2=Math.cos(this.lat0);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lat=p.y/this.a;if(Math.abs(lat)>Proj4js.common.HALF_PI){Proj4js.reportError("equi:Inv:DataError");}
+var lon=Proj4js.common.adjust_lon(this.long0+p.x/(this.a*Math.cos(this.lat0)));p.x=lon;p.y=lat;}};Proj4js.Proj.merc={init:function(){if(this.lat_ts){if(this.sphere){this.k0=Math.cos(this.lat_ts);}else{this.k0=Proj4js.common.msfnz(this.es,Math.sin(this.lat_ts),Math.cos(this.lat_ts));}}},forward:function(p){var lon=p.x;var lat=p.y;if(lat*Proj4js.common.R2D>90.0&&lat*Proj4js.common.R2D<-90.0&&lon*Proj4js.common.R2D>180.0&&lon*Proj4js.common.R2D<-180.0){Proj4js.reportError("merc:forward: llInputOutOfRange: "+lon+" : "+lat);return null;}
+var x,y;if(Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN){Proj4js.reportError("merc:forward: ll2mAtPoles");return null;}else{if(this.sphere){x=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(lon-this.long0);y=this.y0+this.a*this.k0*Math.log(Math.tan(Proj4js.common.FORTPI+0.5*lat));}else{var sinphi=Math.sin(lat);var ts=Proj4js.common.tsfnz(this.e,lat,sinphi);x=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(lon-this.long0);y=this.y0-this.a*this.k0*Math.log(ts);}
+p.x=x;p.y=y;return p;}},inverse:function(p){var x=p.x-this.x0;var y=p.y-this.y0;var lon,lat;if(this.sphere){lat=Proj4js.common.HALF_PI-2.0*Math.atan(Math.exp(-y/this.a*this.k0));}else{var ts=Math.exp(-y/(this.a*this.k0));lat=Proj4js.common.phi2z(this.e,ts);if(lat==-9999){Proj4js.reportError("merc:inverse: lat = -9999");return null;}}
+lon=Proj4js.common.adjust_lon(this.long0+x/(this.a*this.k0));p.x=lon;p.y=lat;return p;}};Proj4js.Proj.utm={dependsOn:'tmerc',init:function(){if(!this.zone){Proj4js.reportError("utm:init: zone must be specified for UTM");return;}
+this.lat0=0.0;this.long0=((6*Math.abs(this.zone))-183)*Proj4js.common.D2R;this.x0=500000.0;this.y0=this.utmSouth?10000000.0:0.0;this.k0=0.9996;Proj4js.Proj['tmerc'].init.apply(this);this.forward=Proj4js.Proj['tmerc'].forward;this.inverse=Proj4js.Proj['tmerc'].inverse;}};Proj4js.Proj.eqdc={init:function(){if(!this.mode)this.mode=0;this.temp=this.b/this.a;this.es=1.0-Math.pow(this.temp,2);this.e=Math.sqrt(this.es);this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.sinphi=Math.sin(this.lat1);this.cosphi=Math.cos(this.lat1);this.ms1=Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);this.ml1=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat1);if(this.mode!=0){if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("eqdc:Init:EqualLatitudes");}
+this.sinphi=Math.sin(this.lat2);this.cosphi=Math.cos(this.lat2);this.ms2=Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);this.ml2=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat2);if(Math.abs(this.lat1-this.lat2)>=Proj4js.common.EPSLN){this.ns=(this.ms1-this.ms2)/(this.ml2-this.ml1);}else{this.ns=this.sinphi;}}else{this.ns=this.sinphi;}
+this.g=this.ml1+this.ms1/this.ns;this.ml0=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);this.rh=this.a*(this.g-this.ml0);},forward:function(p){var lon=p.x;var lat=p.y;var ml=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);var rh1=this.a*(this.g-ml);var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+rh1*Math.sin(theta);var y=this.y0+this.rh-rh1*Math.cos(theta);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y=this.rh-p.y+this.y0;var con,rh1;if(this.ns>=0){var rh1=Math.sqrt(p.x*p.x+p.y*p.y);var con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;}
+var theta=0.0;if(rh1!=0.0)theta=Math.atan2(con*p.x,con*p.y);var ml=this.g-rh1/this.a;var lat=this.phi3z(this.ml,this.e0,this.e1,this.e2,this.e3);var lon=Proj4js.common.adjust_lon(this.long0+theta/this.ns);p.x=lon;p.y=lat;return p;},phi3z:function(ml,e0,e1,e2,e3){var phi;var dphi;phi=ml;for(var i=0;i<15;i++){dphi=(ml+e1*Math.sin(2.0*phi)-e2*Math.sin(4.0*phi)+e3*Math.sin(6.0*phi))/e0-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001){return phi;}}
+Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");return null;}};Proj4js.Proj.tmerc={init:function(){this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.ml0=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);},forward:function(p){var lon=p.x;var lat=p.y;var delta_lon=Proj4js.common.adjust_lon(lon-this.long0);var con;var x,y;var sin_phi=Math.sin(lat);var cos_phi=Math.cos(lat);if(this.sphere){var b=cos_phi*Math.sin(delta_lon);if((Math.abs(Math.abs(b)-1.0))<.0000000001){Proj4js.reportError("tmerc:forward: Point projects into infinity");return(93);}else{x=.5*this.a*this.k0*Math.log((1.0+b)/(1.0-b));con=Math.acos(cos_phi*Math.cos(delta_lon)/Math.sqrt(1.0-b*b));if(lat<0)con=-con;y=this.a*this.k0*(con-this.lat0);}}else{var al=cos_phi*delta_lon;var als=Math.pow(al,2);var c=this.ep2*Math.pow(cos_phi,2);var tq=Math.tan(lat);var t=Math.pow(tq,2);con=1.0-this.es*Math.pow(sin_phi,2);var n=this.a/Math.sqrt(con);var ml=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);x=this.k0*n*al*(1.0+als/6.0*(1.0-t+c+als/20.0*(5.0-18.0*t+Math.pow(t,2)+72.0*c-58.0*this.ep2)))+this.x0;y=this.k0*(ml-this.ml0+n*tq*(als*(0.5+als/24.0*(5.0-t+9.0*c+4.0*Math.pow(c,2)+als/30.0*(61.0-58.0*t+Math.pow(t,2)+600.0*c-330.0*this.ep2)))))+this.y0;}
+p.x=x;p.y=y;return p;},inverse:function(p){var con,phi;var delta_phi;var i;var max_iter=6;var lat,lon;if(this.sphere){var f=Math.exp(p.x/(this.a*this.k0));var g=.5*(f-1/f);var temp=this.lat0+p.y/(this.a*this.k0);var h=Math.cos(temp);con=Math.sqrt((1.0-h*h)/(1.0+g*g));lat=Proj4js.common.asinz(con);if(temp<0)
+lat=-lat;if((g==0)&&(h==0)){lon=this.long0;}else{lon=Proj4js.common.adjust_lon(Math.atan2(g,h)+this.long0);}}else{var x=p.x-this.x0;var y=p.y-this.y0;con=(this.ml0+y/this.k0)/this.a;phi=con;for(i=0;true;i++){delta_phi=((con+this.e1*Math.sin(2.0*phi)-this.e2*Math.sin(4.0*phi)+this.e3*Math.sin(6.0*phi))/this.e0)-phi;phi+=delta_phi;if(Math.abs(delta_phi)<=Proj4js.common.EPSLN)break;if(i>=max_iter){Proj4js.reportError("tmerc:inverse: Latitude failed to converge");return(95);}}
+if(Math.abs(phi)<Proj4js.common.HALF_PI){var sin_phi=Math.sin(phi);var cos_phi=Math.cos(phi);var tan_phi=Math.tan(phi);var c=this.ep2*Math.pow(cos_phi,2);var cs=Math.pow(c,2);var t=Math.pow(tan_phi,2);var ts=Math.pow(t,2);con=1.0-this.es*Math.pow(sin_phi,2);var n=this.a/Math.sqrt(con);var r=n*(1.0-this.es)/con;var d=x/(n*this.k0);var ds=Math.pow(d,2);lat=phi-(n*tan_phi*ds/r)*(0.5-ds/24.0*(5.0+3.0*t+10.0*c-4.0*cs-9.0*this.ep2-ds/30.0*(61.0+90.0*t+298.0*c+45.0*ts-252.0*this.ep2-3.0*cs)));lon=Proj4js.common.adjust_lon(this.long0+(d*(1.0-ds/6.0*(1.0+2.0*t+c-ds/20.0*(5.0-2.0*c+28.0*t-3.0*cs+8.0*this.ep2+24.0*ts)))/cos_phi));}else{lat=Proj4js.common.HALF_PI*Proj4js.common.sign(y);lon=this.long0;}}
+p.x=lon;p.y=lat;return p;}};Proj4js.defs["GOOGLE"]="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"];Proj4js.Proj.gstmerc={init:function(){var temp=this.b/this.a;this.e=Math.sqrt(1.0-temp*temp);this.lc=this.long0;this.rs=Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e));var sinz=Math.sin(this.lat0);var pc=Math.asin(sinz/this.rs);var sinzpc=Math.sin(pc);this.cp=Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz);this.n2=this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz);this.xs=this.x0;this.ys=this.y0-this.n2*pc;if(!this.title)this.title="Gauss Schreiber transverse mercator";},forward:function(p){var lon=p.x;var lat=p.y;var L=this.rs*(lon-this.lc);var Ls=this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat)));var lat1=Math.asin(Math.sin(L)/Proj4js.common.cosh(Ls));var Ls1=Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));p.x=this.xs+(this.n2*Ls1);p.y=this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L)));return p;},inverse:function(p){var x=p.x;var y=p.y;var L=Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2));var lat1=Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2));var LC=Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));p.x=this.lc+L/this.rs;p.y=Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs);return p;}};Proj4js.Proj.ortho={init:function(def){;this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);},forward:function(p){var sinphi,cosphi;var dlon;var coslon;var ksp;var g;var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslon=Math.cos(dlon);g=this.sin_p14*sinphi+this.cos_p14*cosphi*coslon;ksp=1.0;if((g>0)||(Math.abs(g)<=Proj4js.common.EPSLN)){var x=this.a*ksp*cosphi*Math.sin(dlon);var y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}else{Proj4js.reportError("orthoFwdPointError");}
+p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinz,cosz;var temp;var con;var lon,lat;p.x-=this.x0;p.y-=this.y0;rh=Math.sqrt(p.x*p.x+p.y*p.y);if(rh>this.a+.0000001){Proj4js.reportError("orthoInvDataError");}
+z=Proj4js.common.asinz(rh/this.a);sinz=Math.sin(z);cosz=Math.cos(z);lon=this.long0;if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.lat0;}
+lat=Proj4js.common.asinz(cosz*this.sin_p14+(p.y*sinz*this.cos_p14)/rh);con=Math.abs(lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(this.lat0>=0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}}
+con=cosz-this.sin_p14*Math.sin(lat);if((Math.abs(con)>=Proj4js.common.EPSLN)||(Math.abs(x)>=Proj4js.common.EPSLN)){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2((p.x*sinz*this.cos_p14),(con*rh)));}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.somerc={init:function(){var phy0=this.lat0;this.lambda0=this.long0;var sinPhy0=Math.sin(phy0);var semiMajorAxis=this.a;var invF=this.rf;var flattening=1/invF;var e2=2*flattening-Math.pow(flattening,2);var e=this.e=Math.sqrt(e2);this.R=semiMajorAxis*Math.sqrt(1-e2)/(1-e2*Math.pow(sinPhy0,2.0));this.alpha=Math.sqrt(1+e2/(1-e2)*Math.pow(Math.cos(phy0),4.0));this.b0=Math.asin(sinPhy0/this.alpha);this.K=Math.log(Math.tan(Math.PI/4.0+this.b0/2.0))
+-this.alpha*Math.log(Math.tan(Math.PI/4.0+phy0/2.0))
++this.alpha*e/2*Math.log((1+e*sinPhy0)/(1-e*sinPhy0));},forward:function(p){var Sa1=Math.log(Math.tan(Math.PI/4.0-p.y/2.0));var Sa2=this.e/2.0*Math.log((1+this.e*Math.sin(p.y))/(1-this.e*Math.sin(p.y)));var S=-this.alpha*(Sa1+Sa2)+this.K;var b=2.0*(Math.atan(Math.exp(S))-Math.PI/4.0);var I=this.alpha*(p.x-this.lambda0);var rotI=Math.atan(Math.sin(I)/(Math.sin(this.b0)*Math.tan(b)+
+Math.cos(this.b0)*Math.cos(I)));var rotB=Math.asin(Math.cos(this.b0)*Math.sin(b)-
+Math.sin(this.b0)*Math.cos(b)*Math.cos(I));p.y=this.R/2.0*Math.log((1+Math.sin(rotB))/(1-Math.sin(rotB)))
++this.y0;p.x=this.R*rotI+this.x0;return p;},inverse:function(p){var Y=p.x-this.x0;var X=p.y-this.y0;var rotI=Y/this.R;var rotB=2*(Math.atan(Math.exp(X/this.R))-Math.PI/4.0);var b=Math.asin(Math.cos(this.b0)*Math.sin(rotB)
++Math.sin(this.b0)*Math.cos(rotB)*Math.cos(rotI));var I=Math.atan(Math.sin(rotI)/(Math.cos(this.b0)*Math.cos(rotI)-Math.sin(this.b0)*Math.tan(rotB)));var lambda=this.lambda0+I/this.alpha;var S=0.0;var phy=b;var prevPhy=-1000.0;var iteration=0;while(Math.abs(phy-prevPhy)>0.0000001)
+{if(++iteration>20)
+{Proj4js.reportError("omercFwdInfinity");return;}
+S=1.0/this.alpha*(Math.log(Math.tan(Math.PI/4.0+b/2.0))-this.K)
++this.e*Math.log(Math.tan(Math.PI/4.0
++Math.asin(this.e*Math.sin(phy))/2.0));prevPhy=phy;phy=2.0*Math.atan(Math.exp(S))-Math.PI/2.0;}
+p.x=lambda;p.y=phy;return p;}};Proj4js.Proj.stere={ssfn_:function(phit,sinphi,eccen){sinphi*=eccen;return(Math.tan(.5*(Proj4js.common.HALF_PI+phit))*Math.pow((1.-sinphi)/(1.+sinphi),.5*eccen));},TOL:1.e-8,NITER:8,CONV:1.e-10,S_POLE:0,N_POLE:1,OBLIQ:2,EQUIT:3,init:function(){this.phits=this.lat_ts?this.lat_ts:Proj4js.common.HALF_PI;var t=Math.abs(this.lat0);if((Math.abs(t)-Proj4js.common.HALF_PI)<Proj4js.common.EPSLN){this.mode=this.lat0<0.?this.S_POLE:this.N_POLE;}else{this.mode=t>Proj4js.common.EPSLN?this.OBLIQ:this.EQUIT;}
+this.phits=Math.abs(this.phits);if(this.es){var X;switch(this.mode){case this.N_POLE:case this.S_POLE:if(Math.abs(this.phits-Proj4js.common.HALF_PI)<Proj4js.common.EPSLN){this.akm1=2.*this.k0/Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e));}else{t=Math.sin(this.phits);this.akm1=Math.cos(this.phits)/Proj4js.common.tsfnz(this.e,this.phits,t);t*=this.e;this.akm1/=Math.sqrt(1.-t*t);}
+break;case this.EQUIT:this.akm1=2.*this.k0;break;case this.OBLIQ:t=Math.sin(this.lat0);X=2.*Math.atan(this.ssfn_(this.lat0,t,this.e))-Proj4js.common.HALF_PI;t*=this.e;this.akm1=2.*this.k0*Math.cos(this.lat0)/Math.sqrt(1.-t*t);this.sinX1=Math.sin(X);this.cosX1=Math.cos(X);break;}}else{switch(this.mode){case this.OBLIQ:this.sinph0=Math.sin(this.lat0);this.cosph0=Math.cos(this.lat0);case this.EQUIT:this.akm1=2.*this.k0;break;case this.S_POLE:case this.N_POLE:this.akm1=Math.abs(this.phits-Proj4js.common.HALF_PI)>=Proj4js.common.EPSLN?Math.cos(this.phits)/Math.tan(Proj4js.common.FORTPI-.5*this.phits):2.*this.k0;break;}}},forward:function(p){var lon=p.x;lon=Proj4js.common.adjust_lon(lon-this.long0);var lat=p.y;var x,y;if(this.sphere){var sinphi,cosphi,coslam,sinlam;sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslam=Math.cos(lon);sinlam=Math.sin(lon);switch(this.mode){case this.EQUIT:y=1.+cosphi*coslam;if(y<=Proj4js.common.EPSLN){F_ERROR;}
+y=this.akm1/y;x=y*cosphi*sinlam;y*=sinphi;break;case this.OBLIQ:y=1.+this.sinph0*sinphi+this.cosph0*cosphi*coslam;if(y<=Proj4js.common.EPSLN){F_ERROR;}
+y=this.akm1/y;x=y*cosphi*sinlam;y*=this.cosph0*sinphi-this.sinph0*cosphi*coslam;break;case this.N_POLE:coslam=-coslam;lat=-lat;case this.S_POLE:if(Math.abs(lat-Proj4js.common.HALF_PI)<this.TOL){F_ERROR;}
+y=this.akm1*Math.tan(Proj4js.common.FORTPI+.5*lat);x=sinlam*y;y*=coslam;break;}}else{coslam=Math.cos(lon);sinlam=Math.sin(lon);sinphi=Math.sin(lat);if(this.mode==this.OBLIQ||this.mode==this.EQUIT){X=2.*Math.atan(this.ssfn_(lat,sinphi,this.e));sinX=Math.sin(X-Proj4js.common.HALF_PI);cosX=Math.cos(X);}
+switch(this.mode){case this.OBLIQ:A=this.akm1/(this.cosX1*(1.+this.sinX1*sinX+this.cosX1*cosX*coslam));y=A*(this.cosX1*sinX-this.sinX1*cosX*coslam);x=A*cosX;break;case this.EQUIT:A=2.*this.akm1/(1.+cosX*coslam);y=A*sinX;x=A*cosX;break;case this.S_POLE:lat=-lat;coslam=-coslam;sinphi=-sinphi;case this.N_POLE:x=this.akm1*Proj4js.common.tsfnz(this.e,lat,sinphi);y=-x*coslam;break;}
+x=x*sinlam;}
+p.x=x*this.a+this.x0;p.y=y*this.a+this.y0;return p;},inverse:function(p){var x=(p.x-this.x0)/this.a;var y=(p.y-this.y0)/this.a;var lon,lat;var cosphi,sinphi,tp=0.0,phi_l=0.0,rho,halfe=0.0,pi2=0.0;var i;if(this.sphere){var c,rh,sinc,cosc;rh=Math.sqrt(x*x+y*y);c=2.*Math.atan(rh/this.akm1);sinc=Math.sin(c);cosc=Math.cos(c);lon=0.;switch(this.mode){case this.EQUIT:if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=0.;}else{lat=Math.asin(y*sinc/rh);}
+if(cosc!=0.||x!=0.)lon=Math.atan2(x*sinc,cosc*rh);break;case this.OBLIQ:if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.phi0;}else{lat=Math.asin(cosc*sinph0+y*sinc*cosph0/rh);}
+c=cosc-sinph0*Math.sin(lat);if(c!=0.||x!=0.){lon=Math.atan2(x*sinc*cosph0,c*rh);}
+break;case this.N_POLE:y=-y;case this.S_POLE:if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.phi0;}else{lat=Math.asin(this.mode==this.S_POLE?-cosc:cosc);}
+lon=(x==0.&&y==0.)?0.:Math.atan2(x,y);break;}}else{rho=Math.sqrt(x*x+y*y);switch(this.mode){case this.OBLIQ:case this.EQUIT:tp=2.*Math.atan2(rho*this.cosX1,this.akm1);cosphi=Math.cos(tp);sinphi=Math.sin(tp);if(rho==0.0){phi_l=Math.asin(cosphi*this.sinX1);}else{phi_l=Math.asin(cosphi*this.sinX1+(y*sinphi*this.cosX1/rho));}
+tp=Math.tan(.5*(Proj4js.common.HALF_PI+phi_l));x*=sinphi;y=rho*this.cosX1*cosphi-y*this.sinX1*sinphi;pi2=Proj4js.common.HALF_PI;halfe=.5*this.e;break;case this.N_POLE:y=-y;case this.S_POLE:tp=-rho/this.akm1;phi_l=Proj4js.common.HALF_PI-2.*Math.atan(tp);pi2=-Proj4js.common.HALF_PI;halfe=-.5*this.e;break;}
+for(i=this.NITER;i--;phi_l=lat){sinphi=this.e*Math.sin(phi_l);lat=2.*Math.atan(tp*Math.pow((1.+sinphi)/(1.-sinphi),halfe))-pi2;if(Math.abs(phi_l-lat)<this.CONV){if(this.mode==this.S_POLE)lat=-lat;lon=(x==0.&&y==0.)?0.:Math.atan2(x,y);p.x=Proj4js.common.adjust_lon(lon+this.long0);p.y=lat;return p;}}}}};Proj4js.Proj.nzmg={iterations:1,init:function(){this.A=new Array();this.A[1]=+0.6399175073;this.A[2]=-0.1358797613;this.A[3]=+0.063294409;this.A[4]=-0.02526853;this.A[5]=+0.0117879;this.A[6]=-0.0055161;this.A[7]=+0.0026906;this.A[8]=-0.001333;this.A[9]=+0.00067;this.A[10]=-0.00034;this.B_re=new Array();this.B_im=new Array();this.B_re[1]=+0.7557853228;this.B_im[1]=0.0;this.B_re[2]=+0.249204646;this.B_im[2]=+0.003371507;this.B_re[3]=-0.001541739;this.B_im[3]=+0.041058560;this.B_re[4]=-0.10162907;this.B_im[4]=+0.01727609;this.B_re[5]=-0.26623489;this.B_im[5]=-0.36249218;this.B_re[6]=-0.6870983;this.B_im[6]=-1.1651967;this.C_re=new Array();this.C_im=new Array();this.C_re[1]=+1.3231270439;this.C_im[1]=0.0;this.C_re[2]=-0.577245789;this.C_im[2]=-0.007809598;this.C_re[3]=+0.508307513;this.C_im[3]=-0.112208952;this.C_re[4]=-0.15094762;this.C_im[4]=+0.18200602;this.C_re[5]=+1.01418179;this.C_im[5]=+1.64497696;this.C_re[6]=+1.9660549;this.C_im[6]=+2.5127645;this.D=new Array();this.D[1]=+1.5627014243;this.D[2]=+0.5185406398;this.D[3]=-0.03333098;this.D[4]=-0.1052906;this.D[5]=-0.0368594;this.D[6]=+0.007317;this.D[7]=+0.01220;this.D[8]=+0.00394;this.D[9]=-0.0013;},forward:function(p){var lon=p.x;var lat=p.y;var delta_lat=lat-this.lat0;var delta_lon=lon-this.long0;var d_phi=delta_lat/Proj4js.common.SEC_TO_RAD*1E-5;var d_lambda=delta_lon;var d_phi_n=1;var d_psi=0;for(n=1;n<=10;n++){d_phi_n=d_phi_n*d_phi;d_psi=d_psi+this.A[n]*d_phi_n;}
+var th_re=d_psi;var th_im=d_lambda;var th_n_re=1;var th_n_im=0;var th_n_re1;var th_n_im1;var z_re=0;var z_im=0;for(n=1;n<=6;n++){th_n_re1=th_n_re*th_re-th_n_im*th_im;th_n_im1=th_n_im*th_re+th_n_re*th_im;th_n_re=th_n_re1;th_n_im=th_n_im1;z_re=z_re+this.B_re[n]*th_n_re-this.B_im[n]*th_n_im;z_im=z_im+this.B_im[n]*th_n_re+this.B_re[n]*th_n_im;}
+x=(z_im*this.a)+this.x0;y=(z_re*this.a)+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var x=p.x;var y=p.y;var delta_x=x-this.x0;var delta_y=y-this.y0;var z_re=delta_y/this.a;var z_im=delta_x/this.a;var z_n_re=1;var z_n_im=0;var z_n_re1;var z_n_im1;var th_re=0;var th_im=0;for(n=1;n<=6;n++){z_n_re1=z_n_re*z_re-z_n_im*z_im;z_n_im1=z_n_im*z_re+z_n_re*z_im;z_n_re=z_n_re1;z_n_im=z_n_im1;th_re=th_re+this.C_re[n]*z_n_re-this.C_im[n]*z_n_im;th_im=th_im+this.C_im[n]*z_n_re+this.C_re[n]*z_n_im;}
+for(i=0;i<this.iterations;i++){var th_n_re=th_re;var th_n_im=th_im;var th_n_re1;var th_n_im1;var num_re=z_re;var num_im=z_im;for(n=2;n<=6;n++){th_n_re1=th_n_re*th_re-th_n_im*th_im;th_n_im1=th_n_im*th_re+th_n_re*th_im;th_n_re=th_n_re1;th_n_im=th_n_im1;num_re=num_re+(n-1)*(this.B_re[n]*th_n_re-this.B_im[n]*th_n_im);num_im=num_im+(n-1)*(this.B_im[n]*th_n_re+this.B_re[n]*th_n_im);}
+th_n_re=1;th_n_im=0;var den_re=this.B_re[1];var den_im=this.B_im[1];for(n=2;n<=6;n++){th_n_re1=th_n_re*th_re-th_n_im*th_im;th_n_im1=th_n_im*th_re+th_n_re*th_im;th_n_re=th_n_re1;th_n_im=th_n_im1;den_re=den_re+n*(this.B_re[n]*th_n_re-this.B_im[n]*th_n_im);den_im=den_im+n*(this.B_im[n]*th_n_re+this.B_re[n]*th_n_im);}
+var den2=den_re*den_re+den_im*den_im;th_re=(num_re*den_re+num_im*den_im)/den2;th_im=(num_im*den_re-num_re*den_im)/den2;}
+var d_psi=th_re;var d_lambda=th_im;var d_psi_n=1;var d_phi=0;for(n=1;n<=9;n++){d_psi_n=d_psi_n*d_psi;d_phi=d_phi+this.D[n]*d_psi_n;}
+var lat=this.lat0+(d_phi*Proj4js.common.SEC_TO_RAD*1E5);var lon=this.long0+d_lambda;p.x=lon;p.y=lat;return p;}};Proj4js.Proj.mill={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon;var y=this.y0+this.a*Math.log(Math.tan((Proj4js.common.PI/4.0)+(lat/2.5)))*1.25;p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lon=Proj4js.common.adjust_lon(this.long0+p.x/this.a);var lat=2.5*(Math.atan(Math.exp(0.8*p.y/this.a))-Proj4js.common.PI/4.0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.gnom={init:function(def){this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);this.infinity_dist=1000*this.a;},forward:function(p){var sinphi,cosphi;var dlon;var coslon;var ksp;var g;var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslon=Math.cos(dlon);g=this.sin_p14*sinphi+this.cos_p14*cosphi*coslon;ksp=1.0;if((g>0)||(Math.abs(g)<=Proj4js.common.EPSLN)){x=this.x0+this.a*ksp*cosphi*Math.sin(dlon)/g;y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon)/g;}else{Proj4js.reportError("orthoFwdPointError");x=this.x0+this.infinity_dist*cosphi*Math.sin(dlon);y=this.y0+this.infinity_dist*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}
+p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinc,cosc;var c;var lon,lat;p.x=(p.x-this.x0)/this.a;p.y=(p.y-this.y0)/this.a;p.x/=this.k0;p.y/=this.k0;if((rh=Math.sqrt(p.x*p.x+p.y*p.y))){c=Math.atan2(rh,this.rc);sinc=Math.sin(c);cosc=Math.cos(c);lat=Proj4js.common.asinz(cosc*this.sin_p14+(p.y*sinc*this.cos_p14)/rh);lon=Math.atan2(p.x*sinc,rh*this.cos_p14*cosc-p.y*this.sin_p14*sinc);lon=Proj4js.common.adjust_lon(this.long0+lon);}else{lat=this.phic0;lon=0.0;}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.sinu={init:function(){this.R=6370997.0;},forward:function(p){var x,y,delta_lon;var lon=p.x;var lat=p.y;delta_lon=Proj4js.common.adjust_lon(lon-this.long0);x=this.R*delta_lon*Math.cos(lat)+this.x0;y=this.R*lat+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var lat,temp,lon;p.x-=this.x0;p.y-=this.y0;lat=p.y/this.R;if(Math.abs(lat)>Proj4js.common.HALF_PI){Proj4js.reportError("sinu:Inv:DataError");}
+temp=Math.abs(lat)-Proj4js.common.HALF_PI;if(Math.abs(temp)>Proj4js.common.EPSLN){temp=this.long0+p.x/(this.R*Math.cos(lat));lon=Proj4js.common.adjust_lon(temp);}else{lon=this.long0;}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.vandg={init:function(){this.R=6370997.0;},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var x,y;if(Math.abs(lat)<=Proj4js.common.EPSLN){x=this.x0+this.R*dlon;y=this.y0;}
+var theta=Proj4js.common.asinz(2.0*Math.abs(lat/Proj4js.common.PI));if((Math.abs(dlon)<=Proj4js.common.EPSLN)||(Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN)){x=this.x0;if(lat>=0){y=this.y0+Proj4js.common.PI*this.R*Math.tan(.5*theta);}else{y=this.y0+Proj4js.common.PI*this.R*-Math.tan(.5*theta);}}
+var al=.5*Math.abs((Proj4js.common.PI/dlon)-(dlon/Proj4js.common.PI));var asq=al*al;var sinth=Math.sin(theta);var costh=Math.cos(theta);var g=costh/(sinth+costh-1.0);var gsq=g*g;var m=g*(2.0/sinth-1.0);var msq=m*m;var con=Proj4js.common.PI*this.R*(al*(g-msq)+Math.sqrt(asq*(g-msq)*(g-msq)-(msq+asq)*(gsq-msq)))/(msq+asq);if(dlon<0){con=-con;}
+x=this.x0+con;con=Math.abs(con/(Proj4js.common.PI*this.R));if(lat>=0){y=this.y0+Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);}else{y=this.y0-Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);}
+p.x=x;p.y=y;return p;},inverse:function(p){var dlon;var xx,yy,xys,c1,c2,c3;var al,asq;var a1;var m1;var con;var th1;var d;p.x-=this.x0;p.y-=this.y0;con=Proj4js.common.PI*this.R;xx=p.x/con;yy=p.y/con;xys=xx*xx+yy*yy;c1=-Math.abs(yy)*(1.0+xys);c2=c1-2.0*yy*yy+xx*xx;c3=-2.0*c1+1.0+2.0*yy*yy+xys*xys;d=yy*yy/c3+(2.0*c2*c2*c2/c3/c3/c3-9.0*c1*c2/c3/c3)/27.0;a1=(c1-c2*c2/3.0/c3)/c3;m1=2.0*Math.sqrt(-a1/3.0);con=((3.0*d)/a1)/m1;if(Math.abs(con)>1.0){if(con>=0.0){con=1.0;}else{con=-1.0;}}
+th1=Math.acos(con)/3.0;if(p.y>=0){lat=(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}else{lat=-(-m1*Math.cos(th1+PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}
+if(Math.abs(xx)<Proj4js.common.EPSLN){lon=this.long0;}
+lon=Proj4js.common.adjust_lon(this.long0+Proj4js.common.PI*(xys-1.0+Math.sqrt(1.0+2.0*(xx*xx-yy*yy)+xys*xys))/2.0/xx);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.cea={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon*Math.cos(this.lat_ts);var y=this.y0+this.a*Math.sin(lat)/Math.cos(this.lat_ts);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lon=Proj4js.common.adjust_lon(this.long0+(p.x/this.a)/Math.cos(this.lat_ts));var lat=Math.asin((p.y/this.a)*Math.cos(this.lat_ts));p.x=lon;p.y=lat;return p;}};Proj4js.Proj.eqc={init:function(){if(!this.x0)this.x0=0;if(!this.y0)this.y0=0;if(!this.lat0)this.lat0=0;if(!this.long0)this.long0=0;if(!this.lat_ts)this.lat_ts=0;if(!this.title)this.title="Equidistant Cylindrical (Plate Carre)";this.rc=Math.cos(this.lat_ts);},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var dlat=Proj4js.common.adjust_lat(lat-this.lat0);p.x=this.x0+(this.a*dlon*this.rc);p.y=this.y0+(this.a*dlat);return p;},inverse:function(p){var x=p.x;var y=p.y;p.x=Proj4js.common.adjust_lon(this.long0+((x-this.x0)/(this.a*this.rc)));p.y=Proj4js.common.adjust_lat(this.lat0+((y-this.y0)/(this.a)));return p;}};Proj4js.Proj.cass={init:function(){if(!this.sphere){this.en=this.pj_enfn(this.es)
+this.m0=this.pj_mlfn(this.lat0,Math.sin(this.lat0),Math.cos(this.lat0),this.en);}},C1:.16666666666666666666,C2:.00833333333333333333,C3:.04166666666666666666,C4:.33333333333333333333,C5:.06666666666666666666,forward:function(p){var x,y;var lam=p.x;var phi=p.y;lam=Proj4js.common.adjust_lon(lam-this.long0);if(this.sphere){x=Math.asin(Math.cos(phi)*Math.sin(lam));y=Math.atan2(Math.tan(phi),Math.cos(lam))-this.phi0;}else{this.n=Math.sin(phi);this.c=Math.cos(phi);y=this.pj_mlfn(phi,this.n,this.c,this.en);this.n=1./Math.sqrt(1.-this.es*this.n*this.n);this.tn=Math.tan(phi);this.t=this.tn*this.tn;this.a1=lam*this.c;this.c*=this.es*this.c/(1-this.es);this.a2=this.a1*this.a1;x=this.n*this.a1*(1.-this.a2*this.t*(this.C1-(8.-this.t+8.*this.c)*this.a2*this.C2));y-=this.m0-this.n*this.tn*this.a2*(.5+(5.-this.t+6.*this.c)*this.a2*this.C3);}
+p.x=this.a*x+this.x0;p.y=this.a*y+this.y0;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var x=p.x/this.a;var y=p.y/this.a;if(this.sphere){this.dd=y+this.lat0;phi=Math.asin(Math.sin(this.dd)*Math.cos(x));lam=Math.atan2(Math.tan(x),Math.cos(this.dd));}else{ph1=this.pj_inv_mlfn(this.m0+y,this.es,this.en);this.tn=Math.tan(ph1);this.t=this.tn*this.tn;this.n=Math.sin(ph1);this.r=1./(1.-this.es*this.n*this.n);this.n=Math.sqrt(this.r);this.r*=(1.-this.es)*this.n;this.dd=x/this.n;this.d2=this.dd*this.dd;phi=ph1-(this.n*this.tn/this.r)*this.d2*(.5-(1.+3.*this.t)*this.d2*this.C3);lam=this.dd*(1.+this.t*this.d2*(-this.C4+(1.+3.*this.t)*this.d2*this.C5))/Math.cos(ph1);}
+p.x=Proj4js.common.adjust_lon(this.long0+lam);p.y=phi;return p;},pj_enfn:function(es){en=new Array();en[0]=this.C00-es*(this.C02+es*(this.C04+es*(this.C06+es*this.C08)));en[1]=es*(this.C22-es*(this.C04+es*(this.C06+es*this.C08)));var t=es*es;en[2]=t*(this.C44-es*(this.C46+es*this.C48));t*=es;en[3]=t*(this.C66-es*this.C68);en[4]=t*es*this.C88;return en;},pj_mlfn:function(phi,sphi,cphi,en){cphi*=sphi;sphi*=sphi;return(en[0]*phi-cphi*(en[1]+sphi*(en[2]+sphi*(en[3]+sphi*en[4]))));},pj_inv_mlfn:function(arg,es,en){k=1./(1.-es);phi=arg;for(i=Proj4js.common.MAX_ITER;i;--i){s=Math.sin(phi);t=1.-es*s*s;t=(this.pj_mlfn(phi,s,Math.cos(phi),en)-arg)*(t*Math.sqrt(t))*k;phi-=t;if(Math.abs(t)<Proj4js.common.EPSLN)
+return phi;}
+Proj4js.reportError("cass:pj_inv_mlfn: Convergence error");return phi;},C00:1.0,C02:.25,C04:.046875,C06:.01953125,C08:.01068115234375,C22:.75,C44:.46875,C46:.01302083333333333333,C48:.00712076822916666666,C66:.36458333333333333333,C68:.00569661458333333333,C88:.3076171875}
+Proj4js.Proj.gauss={init:function(){sphi=Math.sin(this.lat0);cphi=Math.cos(this.lat0);cphi*=cphi;this.rc=Math.sqrt(1.0-this.es)/(1.0-this.es*sphi*sphi);this.C=Math.sqrt(1.0+this.es*cphi*cphi/(1.0-this.es));this.phic0=Math.asin(sphi/this.C);this.ratexp=0.5*this.C*this.e;this.K=Math.tan(0.5*this.phic0+Proj4js.common.FORTPI)/(Math.pow(Math.tan(0.5*this.lat0+Proj4js.common.FORTPI),this.C)*Proj4js.common.srat(this.e*sphi,this.ratexp));},forward:function(p){var lon=p.x;var lat=p.y;p.y=2.0*Math.atan(this.K*Math.pow(Math.tan(0.5*lat+Proj4js.common.FORTPI),this.C)*Proj4js.common.srat(this.e*Math.sin(lat),this.ratexp))-Proj4js.common.HALF_PI;p.x=this.C*lon;return p;},inverse:function(p){var DEL_TOL=1e-14;var lon=p.x/this.C;var lat=p.y;num=Math.pow(Math.tan(0.5*lat+Proj4js.common.FORTPI)/this.K,1./this.C);for(var i=Proj4js.common.MAX_ITER;i>0;--i){lat=2.0*Math.atan(num*Proj4js.common.srat(this.e*Math.sin(p.y),-0.5*this.e))-Proj4js.common.HALF_PI;if(Math.abs(lat-p.y)<DEL_TOL)break;p.y=lat;}
+if(!i){Proj4js.reportError("gauss:inverse:convergence failed");return null;}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.omerc={init:function(){if(!this.mode)this.mode=0;if(!this.lon1){this.lon1=0;this.mode=1;}
+if(!this.lon2)this.lon2=0;if(!this.lat2)this.lat2=0;var temp=this.b/this.a;var es=1.0-Math.pow(temp,2);var e=Math.sqrt(es);this.sin_p20=Math.sin(this.lat0);this.cos_p20=Math.cos(this.lat0);this.con=1.0-this.es*this.sin_p20*this.sin_p20;this.com=Math.sqrt(1.0-es);this.bl=Math.sqrt(1.0+this.es*Math.pow(this.cos_p20,4.0)/(1.0-es));this.al=this.a*this.bl*this.k0*this.com/this.con;if(Math.abs(this.lat0)<Proj4js.common.EPSLN){this.ts=1.0;this.d=1.0;this.el=1.0;}else{this.ts=Proj4js.common.tsfnz(this.e,this.lat0,this.sin_p20);this.con=Math.sqrt(this.con);this.d=this.bl*this.com/(this.cos_p20*this.con);if((this.d*this.d-1.0)>0.0){if(this.lat0>=0.0){this.f=this.d+Math.sqrt(this.d*this.d-1.0);}else{this.f=this.d-Math.sqrt(this.d*this.d-1.0);}}else{this.f=this.d;}
+this.el=this.f*Math.pow(this.ts,this.bl);}
+if(this.mode!=0){this.g=.5*(this.f-1.0/this.f);this.gama=Proj4js.common.asinz(Math.sin(this.alpha)/this.d);this.longc=this.longc-Proj4js.common.asinz(this.g*Math.tan(this.gama))/this.bl;this.con=Math.abs(this.lat0);if((this.con>Proj4js.common.EPSLN)&&(Math.abs(this.con-Proj4js.common.HALF_PI)>Proj4js.common.EPSLN)){this.singam=Math.sin(this.gama);this.cosgam=Math.cos(this.gama);this.sinaz=Math.sin(this.alpha);this.cosaz=Math.cos(this.alpha);if(this.lat0>=0){this.u=(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}else{this.u=-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}}else{Proj4js.reportError("omerc:Init:DataError");}}else{this.sinphi=Math.sin(this.at1);this.ts1=Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi);this.sinphi=Math.sin(this.lat2);this.ts2=Proj4js.common.tsfnz(this.e,this.lat2,this.sinphi);this.h=Math.pow(this.ts1,this.bl);this.l=Math.pow(this.ts2,this.bl);this.f=this.el/this.h;this.g=.5*(this.f-1.0/this.f);this.j=(this.el*this.el-this.l*this.h)/(this.el*this.el+this.l*this.h);this.p=(this.l-this.h)/(this.l+this.h);this.dlon=this.lon1-this.lon2;if(this.dlon<-Proj4js.common.PI)this.lon2=this.lon2-2.0*Proj4js.common.PI;if(this.dlon>Proj4js.common.PI)this.lon2=this.lon2+2.0*Proj4js.common.PI;this.dlon=this.lon1-this.lon2;this.longc=.5*(this.lon1+this.lon2)-Math.atan(this.j*Math.tan(.5*this.bl*this.dlon)/this.p)/this.bl;this.dlon=Proj4js.common.adjust_lon(this.lon1-this.longc);this.gama=Math.atan(Math.sin(this.bl*this.dlon)/this.g);this.alpha=Proj4js.common.asinz(this.d*Math.sin(this.gama));if(Math.abs(this.lat1-this.lat2)<=Proj4js.common.EPSLN){Proj4js.reportError("omercInitDataError");}else{this.con=Math.abs(this.lat1);}
+if((this.con<=Proj4js.common.EPSLN)||(Math.abs(this.con-HALF_PI)<=Proj4js.common.EPSLN)){Proj4js.reportError("omercInitDataError");}else{if(Math.abs(Math.abs(this.lat0)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN){Proj4js.reportError("omercInitDataError");}}
+this.singam=Math.sin(this.gam);this.cosgam=Math.cos(this.gam);this.sinaz=Math.sin(this.alpha);this.cosaz=Math.cos(this.alpha);if(this.lat0>=0){this.u=(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}else{this.u=-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}}},forward:function(p){var theta;var sin_phi,cos_phi;var b;var c,t,tq;var con,n,ml;var q,us,vl;var ul,vs;var s;var dlon;var ts1;var lon=p.x;var lat=p.y;sin_phi=Math.sin(lat);dlon=Proj4js.common.adjust_lon(lon-this.longc);vl=Math.sin(this.bl*dlon);if(Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI)>Proj4js.common.EPSLN){ts1=Proj4js.common.tsfnz(this.e,lat,sin_phi);q=this.el/(Math.pow(ts1,this.bl));s=.5*(q-1.0/q);t=.5*(q+1.0/q);ul=(s*this.singam-vl*this.cosgam)/t;con=Math.cos(this.bl*dlon);if(Math.abs(con)<.0000001){us=this.al*this.bl*dlon;}else{us=this.al*Math.atan((s*this.cosgam+vl*this.singam)/con)/this.bl;if(con<0)us=us+Proj4js.common.PI*this.al/this.bl;}}else{if(lat>=0){ul=this.singam;}else{ul=-this.singam;}
+us=this.al*lat/this.bl;}
+if(Math.abs(Math.abs(ul)-1.0)<=Proj4js.common.EPSLN){Proj4js.reportError("omercFwdInfinity");}
+vs=.5*this.al*Math.log((1.0-ul)/(1.0+ul))/this.bl;us=us-this.u;var x=this.x0+vs*this.cosaz+us*this.sinaz;var y=this.y0+us*this.cosaz-vs*this.sinaz;p.x=x;p.y=y;return p;},inverse:function(p){var delta_lon;var theta;var delta_theta;var sin_phi,cos_phi;var b;var c,t,tq;var con,n,ml;var vs,us,q,s,ts1;var vl,ul,bs;var dlon;var flag;p.x-=this.x0;p.y-=this.y0;flag=0;vs=p.x*this.cosaz-p.y*this.sinaz;us=p.y*this.cosaz+p.x*this.sinaz;us=us+this.u;q=Math.exp(-this.bl*vs/this.al);s=.5*(q-1.0/q);t=.5*(q+1.0/q);vl=Math.sin(this.bl*us/this.al);ul=(vl*this.cosgam+s*this.singam)/t;if(Math.abs(Math.abs(ul)-1.0)<=Proj4js.common.EPSLN)
+{lon=this.longc;if(ul>=0.0){lat=Proj4js.common.HALF_PI;}else{lat=-Proj4js.common.HALF_PI;}}else{con=1.0/this.bl;ts1=Math.pow((this.el/Math.sqrt((1.0+ul)/(1.0-ul))),con);lat=Proj4js.common.phi2z(this.e,ts1);theta=this.longc-Math.atan2((s*this.cosgam-vl*this.singam),con)/this.bl;lon=Proj4js.common.adjust_lon(theta);}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.lcc={init:function(){if(!this.lat2){this.lat2=this.lat0;}
+if(!this.k0)this.k0=1.0;if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("lcc:init: Equal Latitudes");return;}
+var temp=this.b/this.a;this.e=Math.sqrt(1.0-temp*temp);var sin1=Math.sin(this.lat1);var cos1=Math.cos(this.lat1);var ms1=Proj4js.common.msfnz(this.e,sin1,cos1);var ts1=Proj4js.common.tsfnz(this.e,this.lat1,sin1);var sin2=Math.sin(this.lat2);var cos2=Math.cos(this.lat2);var ms2=Proj4js.common.msfnz(this.e,sin2,cos2);var ts2=Proj4js.common.tsfnz(this.e,this.lat2,sin2);var ts0=Proj4js.common.tsfnz(this.e,this.lat0,Math.sin(this.lat0));if(Math.abs(this.lat1-this.lat2)>Proj4js.common.EPSLN){this.ns=Math.log(ms1/ms2)/Math.log(ts1/ts2);}else{this.ns=sin1;}
+this.f0=ms1/(this.ns*Math.pow(ts1,this.ns));this.rh=this.a*this.f0*Math.pow(ts0,this.ns);if(!this.title)this.title="Lambert Conformal Conic";},forward:function(p){var lon=p.x;var lat=p.y;if(lat<=90.0&&lat>=-90.0&&lon<=180.0&&lon>=-180.0){}else{Proj4js.reportError("lcc:forward: llInputOutOfRange: "+lon+" : "+lat);return null;}
+var con=Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI);var ts,rh1;if(con>Proj4js.common.EPSLN){ts=Proj4js.common.tsfnz(this.e,lat,Math.sin(lat));rh1=this.a*this.f0*Math.pow(ts,this.ns);}else{con=lat*this.ns;if(con<=0){Proj4js.reportError("lcc:forward: No Projection");return null;}
+rh1=0;}
+var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);p.x=this.k0*(rh1*Math.sin(theta))+this.x0;p.y=this.k0*(this.rh-rh1*Math.cos(theta))+this.y0;return p;},inverse:function(p){var rh1,con,ts;var lat,lon;x=(p.x-this.x0)/this.k0;y=(this.rh-(p.y-this.y0)/this.k0);if(this.ns>0){rh1=Math.sqrt(x*x+y*y);con=1.0;}else{rh1=-Math.sqrt(x*x+y*y);con=-1.0;}
+var theta=0.0;if(rh1!=0){theta=Math.atan2((con*x),(con*y));}
+if((rh1!=0)||(this.ns>0.0)){con=1.0/this.ns;ts=Math.pow((rh1/(this.a*this.f0)),con);lat=Proj4js.common.phi2z(this.e,ts);if(lat==-9999)return null;}else{lat=-Proj4js.common.HALF_PI;}
+lon=Proj4js.common.adjust_lon(theta/this.ns+this.long0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.laea={S_POLE:1,N_POLE:2,EQUIT:3,OBLIQ:4,init:function(){var t=Math.abs(this.lat0);if(Math.abs(t-Proj4js.common.HALF_PI)<Proj4js.common.EPSLN){this.mode=this.lat0<0.?this.S_POLE:this.N_POLE;}else if(Math.abs(t)<Proj4js.common.EPSLN){this.mode=this.EQUIT;}else{this.mode=this.OBLIQ;}
+if(this.es>0){var sinphi;this.qp=Proj4js.common.qsfnz(this.e,1.0);this.mmf=.5/(1.-this.es);this.apa=this.authset(this.es);switch(this.mode){case this.N_POLE:case this.S_POLE:this.dd=1.;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp);this.dd=1./this.rq;this.xmf=1.;this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp);sinphi=Math.sin(this.lat0);this.sinb1=Proj4js.common.qsfnz(this.e,sinphi)/this.qp;this.cosb1=Math.sqrt(1.-this.sinb1*this.sinb1);this.dd=Math.cos(this.lat0)/(Math.sqrt(1.-this.es*sinphi*sinphi)*this.rq*this.cosb1);this.ymf=(this.xmf=this.rq)/this.dd;this.xmf*=this.dd;break;}}else{if(this.mode==this.OBLIQ){this.sinph0=Math.sin(this.lat0);this.cosph0=Math.cos(this.lat0);}}},forward:function(p){var x,y;var lam=p.x;var phi=p.y;lam=Proj4js.common.adjust_lon(lam-this.long0);if(this.sphere){var coslam,cosphi,sinphi;sinphi=Math.sin(phi);cosphi=Math.cos(phi);coslam=Math.cos(lam);switch(this.mode){case this.EQUIT:y=(this.mode==this.EQUIT)?1.+cosphi*coslam:1.+this.sinph0*sinphi+this.cosph0*cosphi*coslam;if(y<=Proj4js.common.EPSLN){Proj4js.reportError("laea:fwd:y less than eps");return null;}
+y=Math.sqrt(2./y);x=y*cosphi*Math.sin(lam);y*=(this.mode==this.EQUIT)?sinphi:this.cosph0*sinphi-this.sinph0*cosphi*coslam;break;case this.N_POLE:coslam=-coslam;case this.S_POLE:if(Math.abs(phi+this.phi0)<Proj4js.common.EPSLN){Proj4js.reportError("laea:fwd:phi < eps");return null;}
+y=Proj4js.common.FORTPI-phi*.5;y=2.*((this.mode==this.S_POLE)?Math.cos(y):Math.sin(y));x=y*Math.sin(lam);y*=coslam;break;}}else{var coslam,sinlam,sinphi,q,sinb=0.0,cosb=0.0,b=0.0;coslam=Math.cos(lam);sinlam=Math.sin(lam);sinphi=Math.sin(phi);q=Proj4js.common.qsfnz(this.e,sinphi);if(this.mode==this.OBLIQ||this.mode==this.EQUIT){sinb=q/this.qp;cosb=Math.sqrt(1.-sinb*sinb);}
+switch(this.mode){case this.OBLIQ:b=1.+this.sinb1*sinb+this.cosb1*cosb*coslam;break;case this.EQUIT:b=1.+cosb*coslam;break;case this.N_POLE:b=Proj4js.common.HALF_PI+phi;q=this.qp-q;break;case this.S_POLE:b=phi-Proj4js.common.HALF_PI;q=this.qp+q;break;}
+if(Math.abs(b)<Proj4js.common.EPSLN){Proj4js.reportError("laea:fwd:b < eps");return null;}
+switch(this.mode){case this.OBLIQ:case this.EQUIT:b=Math.sqrt(2./b);if(this.mode==this.OBLIQ){y=this.ymf*b*(this.cosb1*sinb-this.sinb1*cosb*coslam);}else{y=(b=Math.sqrt(2./(1.+cosb*coslam)))*sinb*this.ymf;}
+x=this.xmf*b*cosb*sinlam;break;case this.N_POLE:case this.S_POLE:if(q>=0.){x=(b=Math.sqrt(q))*sinlam;y=coslam*((this.mode==this.S_POLE)?b:-b);}else{x=y=0.;}
+break;}}
+p.x=this.a*x+this.x0;p.y=this.a*y+this.y0;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var x=p.x/this.a;var y=p.y/this.a;if(this.sphere){var cosz=0.0,rh,sinz=0.0;rh=Math.sqrt(x*x+y*y);var phi=rh*.5;if(phi>1.){Proj4js.reportError("laea:Inv:DataError");return null;}
+phi=2.*Math.asin(phi);if(this.mode==this.OBLIQ||this.mode==this.EQUIT){sinz=Math.sin(phi);cosz=Math.cos(phi);}
+switch(this.mode){case this.EQUIT:phi=(Math.abs(rh)<=Proj4js.common.EPSLN)?0.:Math.asin(y*sinz/rh);x*=sinz;y=cosz*rh;break;case this.OBLIQ:phi=(Math.abs(rh)<=Proj4js.common.EPSLN)?this.phi0:Math.asin(cosz*sinph0+y*sinz*cosph0/rh);x*=sinz*cosph0;y=(cosz-Math.sin(phi)*sinph0)*rh;break;case this.N_POLE:y=-y;phi=Proj4js.common.HALF_PI-phi;break;case this.S_POLE:phi-=Proj4js.common.HALF_PI;break;}
+lam=(y==0.&&(this.mode==this.EQUIT||this.mode==this.OBLIQ))?0.:Math.atan2(x,y);}else{var cCe,sCe,q,rho,ab=0.0;switch(this.mode){case this.EQUIT:case this.OBLIQ:x/=this.dd;y*=this.dd;rho=Math.sqrt(x*x+y*y);if(rho<Proj4js.common.EPSLN){p.x=0.;p.y=this.phi0;return p;}
+sCe=2.*Math.asin(.5*rho/this.rq);cCe=Math.cos(sCe);x*=(sCe=Math.sin(sCe));if(this.mode==this.OBLIQ){ab=cCe*this.sinb1+y*sCe*this.cosb1/rho
+q=this.qp*ab;y=rho*this.cosb1*cCe-y*this.sinb1*sCe;}else{ab=y*sCe/rho;q=this.qp*ab;y=rho*cCe;}
+break;case this.N_POLE:y=-y;case this.S_POLE:q=(x*x+y*y);if(!q){p.x=0.;p.y=this.phi0;return p;}
+ab=1.-q/this.qp;if(this.mode==this.S_POLE){ab=-ab;}
+break;}
+lam=Math.atan2(x,y);phi=this.authlat(Math.asin(ab),this.apa);}
+p.x=Proj4js.common.adjust_lon(this.long0+lam);p.y=phi;return p;},P00:.33333333333333333333,P01:.17222222222222222222,P02:.10257936507936507936,P10:.06388888888888888888,P11:.06640211640211640211,P20:.01641501294219154443,authset:function(es){var t;var APA=new Array();APA[0]=es*this.P00;t=es*es;APA[0]+=t*this.P01;APA[1]=t*this.P10;t*=es;APA[0]+=t*this.P02;APA[1]+=t*this.P11;APA[2]=t*this.P20;return APA;},authlat:function(beta,APA){var t=beta+beta;return(beta+APA[0]*Math.sin(t)+APA[1]*Math.sin(t+t)+APA[2]*Math.sin(t+t+t));}};Proj4js.Proj.aeqd={init:function(){this.sin_p12=Math.sin(this.lat0);this.cos_p12=Math.cos(this.lat0);},forward:function(p){var lon=p.x;var lat=p.y;var ksp;var sinphi=Math.sin(p.y);var cosphi=Math.cos(p.y);var dlon=Proj4js.common.adjust_lon(lon-this.long0);var coslon=Math.cos(dlon);var g=this.sin_p12*sinphi+this.cos_p12*cosphi*coslon;if(Math.abs(Math.abs(g)-1.0)<Proj4js.common.EPSLN){ksp=1.0;if(g<0.0){Proj4js.reportError("aeqd:Fwd:PointError");return;}}else{var z=Math.acos(g);ksp=z/Math.sin(z);}
+p.x=this.x0+this.a*ksp*cosphi*Math.sin(dlon);p.y=this.y0+this.a*ksp*(this.cos_p12*sinphi-this.sin_p12*cosphi*coslon);return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var rh=Math.sqrt(p.x*p.x+p.y*p.y);if(rh>(2.0*Proj4js.common.HALF_PI*this.a)){Proj4js.reportError("aeqdInvDataError");return;}
+var z=rh/this.a;var sinz=Math.sin(z);var cosz=Math.cos(z);var lon=this.long0;var lat;if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.lat0;}else{lat=Proj4js.common.asinz(cosz*this.sin_p12+(p.y*sinz*this.cos_p12)/rh);var con=Math.abs(this.lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(lat0>=0.0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}}else{con=cosz-this.sin_p12*Math.sin(lat);if((Math.abs(con)<Proj4js.common.EPSLN)&&(Math.abs(p.x)<Proj4js.common.EPSLN)){}else{var temp=Math.atan2((p.x*sinz*this.cos_p12),(con*rh));lon=Proj4js.common.adjust_lon(this.long0+Math.atan2((p.x*sinz*this.cos_p12),(con*rh)));}}}
+p.x=lon;p.y=lat;return p;}};Proj4js.Proj.moll={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;var delta_lon=Proj4js.common.adjust_lon(lon-this.long0);var theta=lat;var con=Proj4js.common.PI*Math.sin(lat);for(var i=0;true;i++){var delta_theta=-(theta+Math.sin(theta)-con)/(1.0+Math.cos(theta));theta+=delta_theta;if(Math.abs(delta_theta)<Proj4js.common.EPSLN)break;if(i>=50){Proj4js.reportError("moll:Fwd:IterationError");}}
+theta/=2.0;if(Proj4js.common.PI/2-Math.abs(lat)<Proj4js.common.EPSLN)delta_lon=0;var x=0.900316316158*this.a*delta_lon*Math.cos(theta)+this.x0;var y=1.4142135623731*this.a*Math.sin(theta)+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var theta;var arg;p.x-=this.x0;var arg=p.y/(1.4142135623731*this.a);if(Math.abs(arg)>0.999999999999)arg=0.999999999999;var theta=Math.asin(arg);var lon=Proj4js.common.adjust_lon(this.long0+(p.x/(0.900316316158*this.a*Math.cos(theta))));if(lon<(-Proj4js.common.PI))lon=-Proj4js.common.PI;if(lon>Proj4js.common.PI)lon=Proj4js.common.PI;arg=(2.0*theta+Math.sin(2.0*theta))/Proj4js.common.PI;if(Math.abs(arg)>1.0)arg=1.0;var lat=Math.asin(arg);p.x=lon;p.y=lat;return p;}};
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/utils.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/utils.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/utils.js	(revision 672)
@@ -0,0 +1,74 @@
+define([
+], function() {
+    
+    
+    // parseUri 1.2.2
+    // (c) Steven Levithan <stevenlevithan.com>
+    // MIT License
+
+    function parseUri (str) {
+    	var	o   = parseUri.options,
+    		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+    		uri = {},
+    		i   = 14;
+
+    	while (i--) uri[o.key[i]] = m[i] || "";
+
+    	uri[o.q.name] = {};
+    	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+    		if ($1) uri[o.q.name][$1] = $2;
+    	});
+
+    	return uri;
+    };
+
+    parseUri.options = {
+    	strictMode: false,
+    	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+    	q:   {
+    		name:   "queryKey",
+    		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+    	},
+    	parser: {
+    		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+    		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+    	}
+    };
+    
+    
+    //
+    function xmlToString(data) {
+        //data.xml check for IE
+        var xmlstr = data.xml ? data.xml : (new XMLSerializer()).serializeToString(data);
+        return xmlstr;
+    }
+
+    function equalsString(a, b) {
+    	if (!a) {
+    		return false;
+    	}
+
+    	if (!b) {
+    		return false;
+    	}
+
+    	return jQuery.trim(a).localeCompare(jQuery.trim(b)) == 0;
+    }
+
+    function encodeXML(str) {
+        return str.replace(/&/g, '&amp;')
+                   .replace(/</g, '&lt;')
+                   .replace(/>/g, '&gt;')
+                   .replace(/"/g, '&quot;')
+                   .replace(/'/g, '&apos;');
+    };
+    
+    return {
+        parseUri: parseUri,
+        xmlToString: xmlToString,
+        equalsString: equalsString,
+        encodeXML: encodeXML,
+    };
+    
+    
+});
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/wps-payload.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/wps-payload.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/wps-payload.js	(revision 672)
@@ -0,0 +1,253 @@
+/**
+ * Author : Samuel Souk aloun
+ *
+ * Copyright (c) 2014 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+define([
+    'jquery', 'utils'
+], function($, utils) {
+    
+    /**
+     * The wpsPayload module is using the 
+     * [Hogan.js]{@link http://twitter.github.io/hogan.js/} templating engine to
+     * generate XML requests to be sent to a WPS Server.
+     * In the ZOO-Client API, the Hogan.js templates have to be compiled before
+     * you can use them from you application. Please refer to the ZOO-Client 
+     * installation documentation for more informations.
+     * 
+     * @module wpsPayload 
+     * @requires payloads
+     * @requires jquery
+     * @requires utils
+     */
+    
+    return {
+
+	/** @exports wpsPayload */
+        
+        /**
+	 * The getPayload function uses the mustache 
+	 * templates and the parameters provided to generate a valid WPS XML 
+	 * request.
+	 * 
+	 * @static
+	 * @param {Object} params - The object representing the request.
+	 * @returns {string} - The corresponding XML request
+	 * @example
+	 * // GetCapabilities
+	 * var request_params = {
+         *     request: 'GetCapabilities',
+	 *     language: 'en-US'
+         * };
+	 * console.wpsPayload.getPayload(request_params));
+	 * @example
+	 * // DescribeProcess with Identifier value set to "all".
+	 * var request_params = {
+         *     request: 'DescribeProcess',
+	 *     identifier: ["all"]
+         * };
+	 * console.log(wpsPayload.getPayload(request_params));
+	 * @example
+	 * //
+	 * var request_params = {
+	 *     request: 'Execute',
+	 *     Identifier: "Buffer",
+	 *     DataInputs: [{"identifier":"InputPolygon","href":"http://features.org/toto.xml","mimeType":"text/xml"}],
+	 *     DataOutputs: [{"identifier":"Result","mimeType":"application/json"}], 
+	 *     language: 'en-US'
+	 * };
+	 * console.log(wpsPayload.getPayload(request_params));
+	 */
+        getPayload: function(params) {
+            if (params.request == 'DescribeProcess') {
+                return this.getPayload_DescribeProcess(params);
+            } else if (params.request == 'GetCapabilities') {
+                return this.getPayload_GetCapabilities(params);
+            } else if (params.request == 'Execute') {
+                return this.getPayload_Execute(params);
+            } else {
+                console.log("#### UNKNOWN REQUEST ####");
+            }
+        },
+
+        /**
+	 * The getPayload_GetCapabilities function is used to generate a valid 
+	 * WPS XML GetCapabilities request using the 
+	 * [payload_GetCapabilities.mustache]{@link http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-client/lib/tpl/payload_GetCapabilities.mustache} 
+	 * template.
+	 * 
+	 * @static
+	 * @param {Object} params - The object representing the request.
+	 * @returns {string} - The corresponding XML request
+	 * @example
+	 * // log the XML request in console
+	 * var request_params = {
+	 *     language: 'en-US'
+         * };
+	 * console.log(wpsPayload.getPayload_GetCapabilities(request_params));
+	 */
+        getPayload_GetCapabilities: function(params) {
+            return templates["payload_GetCapabilities"].render(params);
+        },
+        
+        /**
+	 * The getPayload_DescribeProcess function is used to generate a valid 
+	 * WPS XML DescribeProcess  request using the 
+	 * [payload_DescribeProcess.mustache]{@link http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-client/lib/tpl/payload_DescribeProcess.mustache} 
+	 * template.
+	 * 
+	 * @static
+	 * @param {Object} params - The object representing the request.
+	 * @returns {string} - The corresponding XML request
+	 * @example
+	 * // log the XML request in console
+	 * var request_params = {
+	 *     Identifier: ["Buffer","Centroid"],
+	 *     language: 'en-US'
+         * };
+	 * console.log(wpsPayload.getPayload_DescribeProcess(request_params));
+	 */
+        getPayload_DescribeProcess: function(params) {
+            if (params.Identifier) {
+                if ($.isArray(params.Identifier)) {
+                    return templates["payload_DescribeProcess"].render({identifiers: params.Identifier,language: params.language});
+                }
+                else {
+                    return templates["payload_DescribeProcess"].render({identifiers: [params.Identifier],language: params.language});
+                }
+            }
+            // TODO: no Identifier
+        },
+
+        /**
+	 * The getPayload_Execute function is used to generate a valid WPS XML 
+	 * Excute request using the 
+	 * [payload_Execute.mustache]{@link http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-client/lib/tpl/payload_Execute.mustache}
+	 * template.
+	 * 
+	 * @static
+	 * @param {Object} params - The object representing the request.
+	 * @returns {string} - The corresponding XML request
+	 * @example
+	 * // log the XML request in console
+	 * var request_params = {
+	 *     Identifier: "Buffer",
+	 *     DataInputs: [{"identifier":"InputPolygon","href":"http://features.org/toto.xml","mimeType":"text/xml"}],
+	 *     DataOutputs: [{"identifier":"Result","mimeType":"application/json"}], 
+	 *     language: 'en-US'
+	 * };
+	 * console.log(wpsPayload.getPayload_Execute(request_params));
+	 */
+        getPayload_Execute: function(params) {
+            if (params.DataInputs) {
+                for (var i = 0; i < params.DataInputs.length; i++) {
+		    /**
+		     * Define inputs type depending on presence of mimeType, 
+		     * dataType and crs or dimension for ComplexData, 
+		     * LiteralData and BoundingBox data respectively
+		     */
+		    var hasType=false;
+		    var lp={"data":"literal","mime":"complex"};
+		    for(j in lp){
+			if (params.DataInputs[i][j+"Type"]) {
+			    params.DataInputs[i]['is_'+lp[j]] = true;
+			    params.DataInputs[i].type=lp[j];
+			    if(j=="mime"){
+				params.DataInputs[i].is_XML=(params.DataInputs[i][j+"Type"]=="text/xml");
+				if(!params.DataInputs[i].is_XML){
+				    var tmp=params.DataInputs[i][j+"Type"].split(";");
+				    params.DataInputs[i].is_XML=(tmp[0]=="text/xml");
+				}
+			    }
+			    hasType=true;
+			}
+                    }
+		    if(!hasType){
+			if (params.DataInputs[i]["type"]=="bbox" || 
+			    params.DataInputs[i]["dimension"] || 
+			    params.DataInputs[i]["crs"]){
+
+			    params.DataInputs[i]['is_bbox'] = true;
+			    params.DataInputs[i].type='bbox';
+			    hasType=true;
+			    
+			}
+			if(!hasType){
+			    params.DataInputs[i]['is_literal'] = true;
+			    params.DataInputs[i].type = "literal";
+			}
+		    }
+                    /*
+                     * Set some default values and flags.
+                     */
+                    if (params.DataInputs[i].type == 'bbox') {
+                	if (!params.DataInputs[i].crs) {
+                    	    params.DataInputs[i].crs = "EPSG:4326";
+                    	}
+                    	if (!params.DataInputs[i].dimension) {
+                    	    params.DataInputs[i].dimension = 2;
+                    	}
+            	    }
+                    
+                    // Complex data from payload callback.
+		    console.log("CALLBACK");
+		    console.log(params.DataInputs[i]);
+                    if (params.DataInputs[i].complexPayload_callback) {
+                        params.DataInputs[i].value = window[params.DataInputs[i].complexPayload_callback];
+			console.log(params.DataInputs[i].value);
+                    }
+                    
+                    // Complex data from reference.
+                    if (params.DataInputs[i].href) {
+                        params.DataInputs[i].is_reference = true;
+                        //params.DataInputs[i].href = utils.encodeXML(params.DataInputs[i].href);
+                        if (params.DataInputs[i].method == 'POST') {
+                            params.DataInputs[i].is_post = true;
+                        } else {
+                            params.DataInputs[i].is_get = true;
+                        }
+                    }
+                    else {                        
+                        // Complex data, embeded
+                    }
+                } // for i loop
+            }
+
+            //console.log("==== OUTPUTS ====");
+            if (params.DataOutputs || params.storeExecuteResponse || params.status || params.lineage) {
+                
+                for (var i = 0; i < params.DataOutputs.length; i++) {
+                    //console.log(params.DataOutputs[i]);
+                    
+                    if (params.DataOutputs[i].type) {
+                        params.DataOutputs[i]['is_'+params.DataOutputs[i].type] = true;
+                    }
+                }
+            }
+            
+            return templates["payload_Execute"].render(params);
+        },
+        
+
+    };
+
+});
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/zoo.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/zoo.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/js/wps-client/zoo.js	(revision 672)
@@ -0,0 +1,798 @@
+/**
+ * Author : Samuel Souk aloun
+ *
+ * Copyright (c) 2014 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+define([
+    'xml2json', 'queryString', 'wpsPayload', 'utils'
+], function(X2JS, qs, wpsPayload, utils) {
+
+    /** 
+     * The ZooProcess Class
+     * @constructs ZooProcess
+     * @param {Object} params Parameters
+     * @example
+     * var myZooObject = new ZooProcess({
+     *     url: "http://localhost/cgi-bin/zoo_loader.cgi",
+     *     delay: 2500
+     * });
+     */
+    var ZooProcess = function(params) {
+        
+        /**
+	 * Object configuring the xml2json use.
+	 *
+         * @access private
+	 * @memberof ZooProcess#
+	 * @var _x2js {x2js}
+         */         
+        var _x2js = new X2JS({
+            arrayAccessFormPaths: [
+            'ProcessDescriptions.ProcessDescription.DataInputs.Input',
+            'ProcessDescriptions.ProcessDescription.DataInputs.Input.ComplexData.Supported.Format',
+            'ProcessDescriptions.ProcessDescription.ProcessOutputs.Output',
+            'ProcessDescriptions.ProcessDescription.ProcessOutputs.Output.ComplexOutput.Supported.Format',
+            'Capabilities.ServiceIdentification.Keywords'
+            ],   
+        });
+
+       
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var debug {Boolean} true if verbose messages should be displayed on the console
+	 * @default false
+         */         
+        this.debug = false;
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var url {String} The WPS Server URL
+	 */
+        this.url = params.url;
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var language {String} The language to be used to request the WPS Server
+	 * @default "en-US"
+	 */
+        this.language = params.language?params.language:"en-US";
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var statusLocation {Object} An object to store the statusLocation 
+	 * URLs when running request including both the storeExecuteResponse and
+	 * the status parameters set to true.
+	 */
+        this.statusLocation = {};
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var launched {Object} An object to store the running asynchrone services.
+	 */
+        this.launched = {};
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var terminated {Object} An object to store the finished services.
+	 */
+        this.terminated = {};
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var percent {Object} An object to store the percentage of completude of services.
+	 */
+        this.percent = {};
+        /**
+         * @access public
+	 * @memberof ZooProcess#
+	 * @var delay {Integer} The time (in milliseconds) between each polling requests.
+	 * @default 2000
+	 */
+        this.delay = params.delay || 2000;
+        
+	/**
+	 * The getCapabilities method run the GetCapabilities request by calling {@link ZooProcess#request}.
+	 * 
+	 * @method getCapabilities
+	 * @memberof ZooProcess#
+	 * @param {Object} params The parameter for the request and callback functions to call on success or
+	 * on failure.
+	 * @example
+	 * // Log the array of available processes in console
+	 * myZooObject.getCapabilities({
+	 *     type: 'POST',
+	 *     success: function(data){
+	 *         console.log(data["Capabilities"]["ProcessOfferings"]["Process"]);
+	 *     }
+	 * });
+	 */
+        this.getCapabilities = function(params) {
+            var closure = this;
+
+            if (!params.hasOwnProperty('type')) {
+                params.type = 'GET';
+            }
+
+            var zoo_request_params = {
+                request: 'GetCapabilities',
+                service: 'WPS',
+                version: '1.0.0',
+            }
+
+            this.request(zoo_request_params, params.success, params.error, params.type);
+        };
+        
+	/**
+	 * The describeProcess method run the DescribeProcess request by calling {@link ZooProcess#request}.
+	 * 
+	 * @method describeProcess
+	 * @memberof ZooProcess#
+	 * @param {Object} params 
+	 * @example
+	 * // Log x2js representation of all available services in console
+	 * myZooObject.describeProcess({
+	 *     type: 'POST',
+	 *     identifier: "all"
+	 *     success: function(data){
+	 *         console.log(data);
+	 *     }
+	 * });
+	 */
+        this.describeProcess = function(params) {
+            var closure = this;
+
+            if (!params.hasOwnProperty('type')) {
+                params.type = 'GET';
+            }
+
+            var zoo_request_params = {
+                Identifier: params.identifier,
+                request: 'DescribeProcess',
+                service: 'WPS',
+                version: '1.0.0',
+            }
+
+            this.request(zoo_request_params, params.success, params.error, params.type);
+        };
+        
+	/**
+	 * The convertParams method convert parameters for Execute requests
+	 *
+	 * @method convertParams
+	 * @memberof ZooProcess#
+	 * @param {Object} params The original object
+	 * @returns {Object} The converted object
+	 */
+	this.convertParams = function(params){
+	    var closure = this;
+	    if(closure.debug){
+		console.log("======== Execute "+params.identifier);
+		console.log(params);
+	    }
+
+            if (!params.hasOwnProperty('type')) {
+                params.type = 'GET';
+            }
+
+            var zoo_request_params = {
+                request: 'Execute',
+                service: 'WPS',
+                version: '1.0.0',
+                Identifier: params.identifier,
+                DataInputs: params.dataInputs ? params.dataInputs : '',
+                DataOutputs: params.dataOutputs ? params.dataOutputs : '',
+            }
+
+
+            if (params.hasOwnProperty('responseDocument')) {
+                zoo_request_params.ResponseDocument = params.responseDocument;
+            }
+            if (params.hasOwnProperty('storeExecuteResponse') &&  params.storeExecuteResponse) {
+                zoo_request_params.storeExecuteResponse = 'true';
+            }
+            if (params.hasOwnProperty('status') &&  params.status) {
+                zoo_request_params.status = 'true';
+            }
+            if (params.hasOwnProperty('lineage') &&  params.lineage) {
+                zoo_request_params.lineage = 'true';
+            }
+	    return zoo_request_params;
+	};
+
+	/**
+	 * The buildRequest method is building the object expected by
+	 * [jQuery.ajax]{@link http://api.jquery.com/jquery.ajax/}.
+	 * In case of GET request, it will use {@link ZooProcess#getQueryString}.
+	 * In case of POST request, it will use {@link module:wpsPayload} getPayload.
+	 *
+	 * @method buildRequest
+	 * @memberof ZooProcess#
+	 * @param {Object} params the request parameters
+	 * @param {String} type the request method ("GET" or "POST")
+	 * @returns {Object} The expected object to give as input for the 
+	 * [jQuery.ajax]{@link http://api.jquery.com/jquery.ajax/} function.
+	 */
+	this.buildRequest = function(params,type){
+            var closure = this;
+	    if(closure.debug){
+		console.log('======== REQUEST method='+type);
+		console.log(params);
+	    }
+            var url = this.url;
+            var payload;
+            var headers;
+	    if(params.hasOwnProperty('DataOutputs'))
+		for(var i=0;i<params.DataOutputs.length;i++)
+		    if(params.DataOutputs[i].type==="raw"){
+			params["RawDataOutput"]=params.DataOutputs[i];
+			break;
+		    }
+
+	    params["language"]=this.language;
+            if (type == 'GET') {
+                url += '?' + this.getQueryString(params);
+            } else if (type == 'POST') {
+                payload = wpsPayload.getPayload(params);
+		if(closure.debug){
+                    console.log("======== POST PAYLOAD ========");
+                    console.log(payload);
+		}
+
+                headers = {
+                    "Content-Type": "text/xml"        
+                };
+            }
+	    
+            if(closure.debug){
+		console.log("ajax url: "+url);
+	    }
+	    return {"url":url,"headers": headers,"data": payload,"type":type};
+	};
+
+	/**
+	 * The getRequest method call the {@link ZooProcess#buildRequest} method
+	 * by giving the {@link ZooProcess#convertParams} result as first 
+	 * argument and the detected type (default is 'GET') defined in params.
+	 * 
+	 * @method getRequest
+	 * @memberof ZooProcess#
+	 * @params {Object} params The request parameters
+	 */
+	this.getRequest = function(params){
+	    var closure = this;
+	    var type = 'GET';
+	    if(params.hasOwnProperty("type"))
+		type=params["type"];
+	    return closure.buildRequest(closure.convertParams(params),type);
+	};
+
+	/**
+	 * The execute method run the Execute request by calling {@link ZooProcess#request}
+	 * with the params converted by {@link ZooProcess#convertParams}.
+	 *
+	 * @method execute
+	 * @memberof ZooProcess#
+	 * @param {Object} param Parameters
+	 * @example
+	 * myZooObject.execute({
+	 *     identifier: "Buffer",
+	 *     dataInputs: [{"identifier":"InputPolygon","href":"http://features.org/toto.xml","mimeType":"text/xml"}],
+	 *     dataOutputs: [{"identifier":"Result","mimeType":"application/json","type":"raw"}],
+	 *     type: 'POST',
+	 *     success: function(data) {
+	 *         console.log(data);
+	 *     }
+	 * });
+	 */
+        this.execute = function(params) {
+            var closure = this;
+            this.request(closure.convertParams(params), params.success, params.error, params.type);
+        };
+
+        
+	/**
+	 * The request method call {@link ZooProcess#buildRequest} method to
+	 * to build parameters to give to 
+	 * [jQuery.ajax]{@link http://api.jquery.com/jquery.ajax/}.
+	 * If the request succeed and if the content-type of the response is 
+	 * "text/xml" then xml2json is called on the resulting data and passed 
+	 * to the onSuccess callback function given in parameter. In case the
+	 * request failed, the WPS Exception Repport will be parsed with 
+	 * xml2json and given as parameter to the onError callback function.
+	 *
+	 * @method request
+	 * @memberof ZooProcess#
+	 * @param {Object} params The object used as parameter for
+	 * [jQuery.ajax]{@link http://api.jquery.com/jquery.ajax/}
+	 * @param {Function} onSuccess The callback function called if the request succeed
+	 * @param {Function} onError The callback function called if the request failed 
+	 * @param {String} type The request method ('GET' or 'POST')
+	 */
+        this.request = function(params, onSuccess, onError, type) {
+            var closure = this;
+
+	    var obj;
+	    obj=closure.buildRequest(params,type);
+            $.ajax(obj)
+		.always(
+                    function() {
+			//console.log("ALWAYS");
+                    }
+		)
+		.fail(
+                    function(jqXHR, textStatus, errorThrown) {
+			if(closure.debug){
+			    console.log("======== ERROR ========");
+			}
+			var robj=_x2js.xml2json( jqXHR.responseXML );
+			if(closure.debug){
+			    console.log(robj);
+			}
+			if(onError)
+			    onError(robj);
+                    }
+		)
+		.done(
+                    function(data, textStatus, jqXHR) {
+			if(closure.debug){
+			    console.log("======== SUCCESS ========2");
+			    console.log(data);
+			}
+			var ctype=jqXHR.getResponseHeader("Content-Type").split(";")[0];
+			if( ctype=="text/xml" )
+			{
+			    var tmpD=data;
+			    data = _x2js.xml2json( data );
+			    data._origin=tmpD;
+			}
+			var launched;
+			
+			if (params.storeExecuteResponse == 'true' && params.status == 'true') {
+			    launched = closure.parseStatusLocation(data);            
+			    closure.statusLocation[launched.sid] = launched.statusLocation;
+			    
+			    if ( launched.hasOwnProperty('sid') && 
+				 !closure.launched.hasOwnProperty(launched.sid)) {
+				closure.launched[launched.sid] = launched.statusLocation;
+			    }
+			}
+
+			if(onSuccess)
+			    onSuccess(data, launched);
+		    });
+        };
+        
+	/**
+	 * The watch method should be used from the success callback function
+	 * passed to {@link ZooProcess#execute} when both status and 
+	 * storeExecuteResponse parameters are set to 'true', so when the 
+	 * service should be called asynchronously. This function is
+	 * responsible for polling the WPS server until the service end (success
+	 * or failure). It call the {@link ZooProcess#getStatus} method every
+	 * {@link ZooProcess#delay} milliseconds.
+	 *
+	 * @method watch
+	 * @memberof ZooProcess#
+	 * @param {Integer} sid The identifier of the running service
+	 * @param {Object} handlers The callback function definitions 
+	 * (onPercentCompleted, onProcessSucceeded, onError)
+	 * @example
+	 * zoo.execute({
+	 *     identifier: 'MyIdentifier',
+	 *     type: 'POST',
+	 *     dataInputs: myInputs,
+	 *     dataOutputs: myOupts,
+	 *     storeExecuteResponse: true,
+	 *     status: true,
+	 *     success: function(data, launched) {
+	 *         zoo.watch(launched.sid, {
+         *             onPercentCompleted: function(data) {
+	 *                 console.log("**** PercentCompleted ****");
+	 *                 console.log(data);
+         *                 progress.text(data.text+' : '+(data.percentCompleted)+'%');
+         *             },
+	 *             onProcessSucceeded: function(data) {
+         *                 progress.css('width', (100)+'%');
+	 *                 progress.text(data.text+' : '+(100)+'%');
+	 *                     if (data.result.ExecuteResponse.ProcessOutputs) {
+	 *                         console.log("**** onSuccess ****");
+	 *                         console.log(data.result);
+	 *                     }
+	 *             },
+	 *             onError: function(data) {
+	 *                 console.log("**** onError ****");
+	 *                 console.log(data);
+	 *             },
+         *         });
+	 *     },
+	 *     error: function(data) {
+	 *         console.log("**** ERROR ****");
+	 *         console.log(data);
+	 *         notify("Execute asynchrone failed", 'danger');
+	 *     }
+	 * });
+	 */
+        this.watch = function(sid, handlers) {
+            //onPercentCompleted, onProcessSucceeded, onError
+            var closure = this;
+	    if(closure.debug){
+		console.log("WATCH: "+sid);
+	    }
+
+            function onSuccess(data) {
+		if(closure.debug){
+                    console.log("++++ getStatus SUCCESS "+sid);
+                    console.log(data);
+		}
+
+		if (data.ExecuteResponse.Status.ProcessAccepted) {
+                    var ret = {
+                        sid: sid,
+                        percentCompleted: 0,
+                        text: data.ExecuteResponse.Status.ProcessAccepted.__text,
+                        creationTime: data.ExecuteResponse.Status._creationTime,
+                    };
+
+                    closure.percent[sid] = ret.percentCompleted;
+                    //closure.emit('percent', ret);
+
+                    if (handlers.onPercentCompleted instanceof Function) {
+                        handlers.onPercentCompleted(ret);
+                    }
+
+		}
+                else if (data.ExecuteResponse.Status.ProcessStarted) {
+		    if(closure.debug){
+			console.log("#### ProcessStarted");
+		    }
+
+                    var ret = {
+                        sid: sid,
+                        percentCompleted: data.ExecuteResponse.Status.ProcessStarted._percentCompleted,
+                        text: data.ExecuteResponse.Status.ProcessStarted.__text,
+                        creationTime: data.ExecuteResponse.Status._creationTime,
+                    };
+
+                    closure.percent[sid] = ret.percentCompleted;
+                    //closure.emit('percent', ret);
+
+                    if (handlers.onPercentCompleted instanceof Function) {
+                        handlers.onPercentCompleted(ret);
+                    }
+                }
+                else if (data.ExecuteResponse.Status.ProcessSucceeded) {
+		    if(closure.debug){
+			console.log("#### ProcessSucceeded");
+		    }
+
+                    var text = data.ExecuteResponse.Status.ProcessSucceeded.__text;
+                    closure.terminated[sid] = true;
+
+                    ret = {
+                        sid: sid,
+                        text: text,
+                        result: data
+                    };
+
+                    //closure.emit('success', ret);
+                    if (handlers.onProcessSucceeded instanceof Function) {
+                        handlers.onProcessSucceeded(ret);
+                    }
+                }
+                else {
+		    if(closure.debug){
+			console.log("#### UNHANDLED EXCEPTION");
+		    }
+                    closure.terminated[sid] = true;
+                    ret = {
+                        sid: sid,
+                        code: 'BAD',
+                        text: 'UNHANDLED EXCEPTION'
+                    };
+
+                    //closure.emit('exception', ret);
+                    if (handlers.onError instanceof Function) {
+                        handlers.onError(ret);
+                    }
+                }    
+            }
+
+            function onError(data) {
+		if(closure.debug){
+                    console.log("++++ getStatus ERROR "+sid);
+                    console.log(data);
+		}
+            }
+
+            function ping(sid) {
+		if(closure.debug){
+                    console.log("PING: "+sid);
+		}
+                closure.getStatus(sid, onSuccess, onError);
+                if (closure.terminated[sid]) {
+		    if(closure.debug){
+			console.log("++++ getStatus TERMINATED "+sid);
+		    }
+                }
+                else if (!closure.percent.hasOwnProperty(sid) || closure.percent[sid]<100) {
+                    setTimeout( function() {
+                        ping(sid);
+                     }, closure.delay);
+                } else {
+		    if(closure.debug){
+			console.log(closure.percent);
+		    }
+                }
+            }
+
+            ping(sid);
+        };
+        
+	/**
+	 * The getStatus method call 
+	 * [jQuery.ajax]{@link http://api.jquery.com/jquery.ajax/} to fecth the
+	 * ExecuteResponse document which contains a Status node and
+	 * potentially the result (when the asynch service end). This method is
+	 * used by {@link ZooProcess#watch} to get the ongoing status of 
+	 * services called asynchronously.
+	 * 
+	 * @method getStatus
+	 * @memberof ZooProcess#
+	 * @param {Integer} sid Service Identifier
+	 * @param {Function} onSuccess callback 
+	 * @param {Function} onError callback 
+	 */
+        this.getStatus = function(sid, onSuccess, onError) {
+            var closure = this;
+	    if(closure.debug){
+		console.log("GET STATUS: "+sid);
+	    }
+            if (closure.terminated[sid]) {
+		if(closure.debug){
+                    console.log("DEBUG TERMINATED");
+		}
+                return;
+            }
+            if (!closure.launched[sid]) {
+		if(closure.debug){
+                    console.log("DEBUG LAUNCHED");
+		}
+                return;
+            }
+
+            $.ajax({
+		url: closure.statusLocation[sid]
+	    })
+		.fail(
+                    function(jqXHR, textStatus, errorThrown) {
+			if(closure.debug){
+			    console.log("======== ERROR ========");
+			}
+			var robj=_x2js.xml2json( jqXHR.responseXML );
+			if(closure.debug){
+			    console.log(robj);
+			}
+			if(onError)
+			    onError(robj);
+                    }
+		)
+		.done(
+                    function(data, textStatus, jqXHR) {
+			if(closure.debug){
+			    console.log("======== SUCCESS ========2");
+			    console.log(data);
+			}
+			var ctype=jqXHR.getResponseHeader("Content-Type").split(";")[0];
+			if( ctype=="text/xml" ){
+			    var tmpD=data;
+			    data = _x2js.xml2json( data );
+			    data._origin=tmpD;
+			}
+			if(onSuccess)
+			    onSuccess(data);
+		    });
+        };
+        
+	/**
+	 * The getQueryString method generate a KVP GET request which can be 
+	 * used to request a WPS server.
+	 *
+	 * @method getQueryString
+	 * @memberof ZooProcess#
+	 * @param {Object} params The WPS requests parameters
+	 * @returns {String} The GET WPS request
+	 * @example
+	 * // Log GetCapabilities GET request in console
+	 * var request_params = {
+	 *     request: 'GetCapabilities',
+         *     service: 'WPS',
+         *     version: '1.0.0',
+	 *     language; 'en-US'
+         * }
+	 * console.log(myZooObject.getQueryString(request_params));
+	 */
+        this.getQueryString = function(params) {
+	    var closure = this;
+            var ret = '';
+
+            serializeInputs = function(obj) {
+		if(closure.debug){
+		    console.log("SERIALIZE dataInputs");
+		    console.log(obj);
+		}
+		var lt=$.type(obj);
+		if(lt === "string") {
+                    return obj;
+		}
+		var str = [];
+		for(var p in obj){
+		    if(lt === "array"){
+			if(obj[p].hasOwnProperty("href"))
+			    str.push(obj[p]["identifier"] + "=Reference");
+			else
+			    str.push(obj[p]["identifier"] + "=" + obj[p]["value"]);
+			for(var q in obj[p]){
+			    if(q!="identifier" && q!="value" && q!="href")
+				str.push("@" + q + "=" + obj[p][q]);
+			    else
+				if(q=="href")
+				    str.push("@xlink:" + q + "=" + encodeURIComponent(obj[p][q]));
+			}
+			str.push(";");
+		    }
+		    else
+			if (obj.hasOwnProperty(p)) {
+			    if(p=="href")
+				str.push(p + "=" + encodeURIComponent(obj[p]));
+			    else
+				str.push(p + "=" + obj[p]);
+			}
+		}
+		return str.join("");
+            }
+
+            serializeOutputs = function(obj) {
+		if(closure.debug){
+		    console.log("SERIALIZE dataOutputs");
+		    console.log(obj);
+		}
+		var lt=$.type(obj);
+		if(lt === "string") {
+                    return obj;
+		}
+		var str = [];
+		for(var p in obj){
+		    str.push(obj[p]["identifier"]);
+		    for(var q in obj[p]){
+			if(q!="identifier" && q!="type")
+			    str.push("@" + q + "=" + obj[p][q]);
+		    }
+		    str.push(";");
+		}
+		return str.join("");
+            }
+	    
+            var responseDocument = params.ResponseDocument;
+            var tmp_params = {};
+
+            var objectKeys = Object.keys || function (obj) {
+                var keys = [];
+                for (var key in obj) keys.push(key);
+                return keys;
+            };
+
+            var skip = {
+                'DataInputs': true,
+                'DataOutputs': true,
+                'ResponseDocument': true,
+                'RawDataOutput': true,
+            }
+            var keys = objectKeys(params);
+            for (var i = 0; i < keys.length; i++) {
+                var key = keys[i];
+                if (skip.hasOwnProperty(key) && skip[key]) {
+                    continue;
+                }
+                if (params.hasOwnProperty(key)) {
+                    tmp_params[key] = params[key];
+                }
+            }
+            ret = qs.stringify(tmp_params);
+
+            //req_options.path = req_options.path.replace("&DataInputs=sid%3D", "&DataInputs=sid=")
+            if (params.hasOwnProperty('DataInputs')) {
+              //var dataInputs = params.DataInputs;
+		var dataInputs = serializeInputs(params.DataInputs);
+		if(closure.debug){
+		    console.log("dataInputs: "+dataInputs);
+		}
+		ret += '&DataInputs=' + dataInputs;
+            }
+            
+            if (params.hasOwnProperty('DataOutputs')) {
+		var dataOutputs = serializeOutputs(params.DataOutputs);
+		if(closure.debug){
+		    console.log("dataOutputs: "+dataOutputs);
+		}
+		if(dataOutputs!=""){
+		    var displayInputs=true;
+		    for(var i=0;i<params.DataOutputs.length;i++)
+			if(params.DataOutputs[i].type==="raw"){
+			    ret += '&RawDataOutput=' + dataOutputs;
+			    displayInputs=false;
+			    break;
+			}
+		    if(displayInputs)
+			ret += '&ResponseDocument=' + dataOutputs;
+		}
+            }else{
+		if (params.hasOwnProperty('RawDataOutput')) {
+		    ret+="&RawDataOutput="+params['RawDataOutput']+";";
+		}else{
+		    if (params.hasOwnProperty('ResponseDocument')) {
+			var lt=$.type(params['ResponseDocument']);
+			if(lt === "string") {
+			    ret+="&ResponseDocument="+params['ResponseDocument']+";";
+			}else{
+			    var tmp_ret=serializeOutputs(params['ResponseDocument']);
+			    ret+="&ResponseDocument="+tmp;
+			}
+		    }
+		}
+	    }
+            
+            return ret;
+        };
+        
+	/**
+	 * The parseStatusLocation method parse the statusLocation and return an
+	 * object with sid and statusLocation attributes which contains
+	 * respectively: a unique identifier named sid and the statusLocation
+	 * value returned by the WPS server.
+	 * 
+	 * @method parseStatusLocation
+	 * @memberof ZooProcess#
+	 * @param {Object} data The XML response parsed by x2js.xml2json
+	 * @returns {Object} The result is an object with sid and statusLocation
+	 */
+        this.parseStatusLocation = function(data) {
+            var closure = this;
+
+            if (statusLocation = data.ExecuteResponse._statusLocation) {
+		if(closure.debug){
+                    console.log("statusLocation: "+statusLocation);
+		}
+
+		var lsid=0;
+		for(i in closure.statusLocation)
+		    lsid++;
+		
+                return {sid: lsid, statusLocation: statusLocation};
+            }
+        };        
+    };
+    
+
+    return ZooProcess;
+
+});
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_DescribeProcess.mustache
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_DescribeProcess.mustache	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_DescribeProcess.mustache	(revision 672)
@@ -0,0 +1,5 @@
+<DescribeProcess xmlns="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsDescribeProcess_request.xsd" service="WPS" version="1.0.0" language="{{language}}">
+{{#identifiers}}
+  <ows:Identifier>{{.}}</ows:Identifier>
+{{/identifiers}}
+</DescribeProcess>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_Execute.mustache
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_Execute.mustache	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_Execute.mustache	(revision 672)
@@ -0,0 +1,84 @@
+<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0
+../wpsExecute_request.xsd" language="{{language}}">
+  <!-- template-version: 0.21 -->
+	<ows:Identifier>{{Identifier}}</ows:Identifier>
+	<wps:DataInputs>
+{{#DataInputs}}
+{{#is_literal}}
+		<wps:Input>
+			<ows:Identifier>{{identifier}}</ows:Identifier>
+			<wps:Data>
+				<wps:LiteralData{{#dataType}} dataType="{{dataType}}"{{/dataType}}>{{value}}</wps:LiteralData>
+			</wps:Data>
+		</wps:Input>
+{{/is_literal}}
+{{#is_bbox}}
+		<wps:Input>
+			<ows:Identifier>{{identifier}}</ows:Identifier>
+			<wps:Data>
+				<wps:BoundingBoxData ows:crs="{{crs}}" ows:dimensions="{{dimension}}">
+            <ows:LowerCorner>{{lowerCorner}}</ows:LowerCorner>
+            <ows:UpperCorner>{{upperCorner}}</ows:UpperCorner>
+         </wps:BoundingBoxData>
+			</wps:Data>
+		</wps:Input>
+{{/is_bbox}}
+{{#is_complex}}
+{{#is_reference}}
+{{#is_get}}
+		<wps:Input>
+			<ows:Identifier>{{identifier}}</ows:Identifier>
+			<wps:Reference xlink:href="{{href}}"{{#schema}} schema="{{shema}}"{{/schema}}{{#mimeType}} mimeType="{{mimeType}}"{{/mimeType}}{{#encoding}} encoding="{{encoding}}"{{/encoding}}/>
+		</wps:Input>
+{{/is_get}}
+{{#is_post}}
+		<wps:Input>
+			<ows:Identifier>{{identifier}}</ows:Identifier>
+			<wps:Reference xlink:href="{{href}}" method="{{method}}">
+{{#headers}}
+			  <wps:Header key="{{key}}" value="{{value}}" />
+{{/headers}}
+			  <wps:Body>{{{value}}}</wps:Body>
+			</wps:Reference>
+		</wps:Input>
+{{/is_post}}
+{{/is_reference}}
+{{^is_reference}}
+		<wps:Input>
+      <ows:Identifier>{{identifier}}</ows:Identifier>
+      <wps:Data>
+        <wps:ComplexData{{#schema}} schema="{{shema}}"{{/schema}}{{#mimeType}} mimeType="{{mimeType}}"{{/mimeType}}{{#encoding}} encoding="{{encoding}}"{{/encoding}}>{{#is_XML}}
+	 {{{value}}}{{/is_XML}}{{^is_XML}}<![CDATA[{{{value}}}]]>{{/is_XML}}
+        </wps:ComplexData>
+      </wps:Data>
+    </wps:Input>
+{{/is_reference}}
+{{/is_complex}}
+{{/DataInputs}}
+	</wps:DataInputs>	
+	<wps:ResponseForm>
+{{#RawDataOutput}}
+{{#DataOutputs}}
+    <wps:RawDataOutput mimeType="{{mimeType}}">
+      <ows:Identifier>{{identifier}}</ows:Identifier>
+    </wps:RawDataOutput>
+{{/DataOutputs}}
+{{/RawDataOutput}}
+{{^RawDataOutput}}
+    <wps:ResponseDocument{{#storeExecuteResponse}} storeExecuteResponse="{{storeExecuteResponse}}"{{/storeExecuteResponse}}{{#lineage}} lineage="{{lineage}}"{{/lineage}}{{#status}} status="{{status}}"{{/status}}>
+{{#DataOutputs}}
+{{#is_literal}}
+      <wps:Output{{#dataType}} dataType="{{dataType}}"{{/dataType}}{{#uom}} uom="{{uom}}"{{/uom}}>
+        <ows:Identifier>{{identifier}}</ows:Identifier>
+      </wps:Output>
+{{/is_literal}}
+{{^is_literal}}
+      <wps:Output{{#asReference}} asReference="{{asReference}}"{{/asReference}}{{#schema}} schema="{{schema}}"{{/schema}}{{#mimeType}} mimeType="{{mimeType}}"{{/mimeType}}{{#encoding}} encoding="{{encoding}}"{{/encoding}}>
+        <ows:Identifier>{{identifier}}</ows:Identifier>
+      </wps:Output>
+{{/is_literal}}
+{{/DataOutputs}}
+    </wps:ResponseDocument>
+{{/RawDataOutput}}
+  </wps:ResponseForm>	
+</wps:Execute>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_GetCapabilities.mustache
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_GetCapabilities.mustache	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-client/lib/tpl/payload_GetCapabilities.mustache	(revision 672)
@@ -0,0 +1,5 @@
+<wps:GetCapabilities xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 ../wpsGetCapabilities_request.xsd" language="{{language}}" service="WPS">
+    <wps:AcceptVersions>
+        <ows:Version>1.0.0</ows:Version>
+    </wps:AcceptVersions>
+</wps:GetCapabilities>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Doxyfile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Doxyfile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Doxyfile	(revision 672)
@@ -0,0 +1,2303 @@
+# Doxyfile 1.8.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "ZOO-Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = y=C 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = YES
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.dox *.y *.c *.cxx *.h 
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/LICENSE
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/LICENSE	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/LICENSE	(revision 672)
@@ -0,0 +1,21 @@
+ZOO-Kernel License
+
+Copyright (c) 2009-2013 GeoLabs SARL
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the “Software”), to deal
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies of this Software or works derived from this Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Makefile.in
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Makefile.in	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/Makefile.in	(revision 672)
@@ -0,0 +1,117 @@
+include ZOOMakefile.opts
+
+all: version.h zoo_loader.cgi ${YAML_FILE1}
+
+version.h:
+	echo "#define ZOO_VERSION \"`svnversion`\"" > version.h
+
+service.o: service.c service.h
+	gcc ${YAML_CFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service.c
+
+main_conf_read.tab.c: main_conf_read.y service.h
+	bison -p cr -d main_conf_read.y
+
+main_conf_read.tab.o: main_conf_read.tab.c service.h
+	g++ ${CFLAGS} -c main_conf_read.tab.c
+
+lex.cr.c: main_conf_read.y main_conf_read.l main_conf_read.tab.c service.h
+	flex -P cr --header-file main_conf_read.l
+
+lex.cr.o: lex.cr.c service.h
+	g++ ${CFLAGS} -c lex.cr.c
+
+service_conf.tab.c: service_conf.y service.h
+	bison -p sr -d service_conf.y
+
+service_conf.tab.o: service_conf.tab.c service.h
+	g++ ${CFLAGS} -c service_conf.tab.c
+
+lex.sr.c: service_conf.y service_conf.l service_conf.tab.c service.h
+	flex -P sr --header-file service_conf.l
+
+lex.sr.o: lex.sr.c service.h
+	g++ ${CFLAGS} -c lex.sr.c
+
+ulinet.o: ulinet.c
+	gcc -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c ulinet.c
+
+request_parser.o: request_parser.c request_parser.h
+	g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c request_parser.c
+
+sqlapi.o: sqlapi.c sqlapi.h
+	g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c sqlapi.c
+
+caching.o: caching.c
+	g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c caching.c
+
+response_print.o: response_print.c response_print.h
+	g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c response_print.c
+
+server_internal.o: server_internal.c server_internal.h service.h mimetypes.h
+	g++ ${GDAL_CFLAGS} ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c server_internal.c
+
+service_internal.o: service_internal.c service_internal.h service.h
+	gcc ${GDAL_CFLAGS} ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal.c
+
+service_yaml.o: service_yaml.c service.h
+	gcc ${YAML_CFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_yaml.c
+
+service_internal_ms.o: service_internal_ms.c
+	gcc ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal_ms.c
+
+service_internal_python.o: service_internal_python.c service.h
+	g++ ${XML2CFLAGS} ${PYTHONCFLAGS} ${CFLAGS} -c service_internal_python.c
+
+service_internal_otb.o: service_internal_otb.c service_internal_otb.h service.h
+	g++ ${XML2CFLAGS} ${OTBCFLAGS} ${CFLAGS} -c service_internal_otb.c
+
+service_internal_saga.o: service_internal_saga.c service_internal_saga.h service.h
+	g++ ${XML2CFLAGS} ${SAGA_CFLAGS} ${CFLAGS} -c service_internal_saga.c
+
+otbZooWatcher.o: otbZooWatcher.cxx otbZooWatcher.h  service.h
+	g++ ${OTBCFLAGS} ${CFLAGS} -c otbZooWatcher.cxx
+
+service_internal_php.o: service_internal_php.c service.h
+	g++ -c ${XML2CFLAGS} ${PHPCFLAGS} ${CFLAGS}  ${PHP_ENABLED} service_internal_php.c
+
+service_internal_perl.o: service_internal_perl.c service.h
+	gcc -c ${XML2CFLAGS} ${PERLCFLAGS} ${CFLAGS}  ${PERL_ENABLED} service_internal_perl.c
+
+service_internal_java.o: service_internal_java.c service.h
+	gcc -c ${XML2CFLAGS} ${JAVACFLAGS} ${CFLAGS} ${JAVA_ENABLED} service_internal_java.c
+
+service_internal_js.o: service_internal_js.c service_internal_js.h
+	gcc -fPIC ${XML2CFLAGS} ${JSCFLAGS} ${CFLAGS} ${JS_ENABLED} -c service_internal_js.c
+
+service_internal_ruby.o: service_internal_ruby.c service_internal_ruby.h
+	g++ ${XML2CFLAGS} ${RUBYCFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c service_internal_ruby.c
+
+service_loader.o: service_loader.c service.h
+	g++ -c ${XML2CFLAGS} ${PYTHONCFLAGS} ${CFLAGS} service_loader.c
+
+zoo_service_loader.o: zoo_service_loader.c service.h
+	g++ -g -O2 ${XML2CFLAGS} ${CFLAGS} ${SAGA_CFLAGS} ${OTBCFLAGS} ${PYTHONCFLAGS} ${JAVACFLAGS} ${JSCFLAGS} ${PERLCFLAGS} ${PHPCFLAGS} ${SAGA_ENABLED} ${OTB_ENABLED} ${PYTHON_ENABLED} ${JS_ENABLED} ${PHP_ENABLED} ${PERL_ENABLED} ${JAVA_ENABLED} -c zoo_service_loader.c  -fno-common -DPIC -o zoo_service_loader.o
+
+libzoo_service.${EXT}: version.h service_internal.o service.o sqlapi.o
+	gcc -shared  ${GDAL_CFLAGS} ${DEFAULT_OPTS} -fpic -o libzoo_service.${EXT} ${CFLAGS}  service_internal.o service.o sqlapi.o -lfcgi ${GDAL_LIBS}
+
+zoo_loader.cgi: version.h libzoo_service.${EXT} zoo_loader.c zoo_service_loader.o  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o request_parser.o response_print.o server_internal.o caching.o ${MS_FILE} ${PYTHON_FILE} ${PHP_FILE} ${JAVA_FILE} ${JS_FILE} ${PERL_FILE} ${RUBY_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE}
+	g++ -g -O2 ${JSCFLAGS} ${PHPCFLAGS}  ${PERLCFLAGS} ${RUBYCFLAGS}  ${JAVACFLAGS} ${XML2CFLAGS} ${PYTHONCFLAGS} ${CFLAGS} -c zoo_loader.c  -fno-common -DPIC -o zoo_loader.o
+	g++  ${JSCFLAGS} ${SAGA_CFLAGS} ${OTBCFLAGS} ${GDAL_CFLAGS} ${XML2CFLAGS} ${PHPCFLAGS} ${PERLCFLAGS} ${JAVACFLAGS} ${PYTHONCFLAGS} ${CFLAGS} zoo_loader.o zoo_service_loader.o ${MS_FILE} ${PYTHON_FILE}  ${PERL_FILE} ${PHP_FILE}  ${JS_FILE} ${JAVA_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE} response_print.o server_internal.o caching.o request_parser.o ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o -o zoo_loader.cgi -L. ${LDFLAGS}
+
+zcfg2yaml: zcfg2yaml.c service.h lex.sr.o service_conf.tab.o service_conf.y main_conf_read.tab.o lex.cr.o response_print.o server_internal.o service_internal.o ${MS_FILE} ${YAML_FILE}
+	g++ -g -O2 ${JSCFLAGS} ${RUBYCFLAGS} ${XML2CFLAGS} ${CFLAGS} -c zcfg2yaml.c  -fno-common -DPIC -o zcfg2yaml.o
+	g++  ${XML2CFLAGS} ${CFLAGS} zcfg2yaml.o server_internal.o service_internal.o ${MS_FILE} response_print.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o  ${YAML_FILE} -o zcfg2yaml -L. ${LDFLAGS}
+
+install:
+	install -d ${CGI_DIR}
+	install zoo_loader.cgi ${CGI_DIR}/
+	install libzoo_service.${EXT} ${DESTDIR}${INST_LIB}/${LIBZOO_SERVICE}
+	(cd ${DESTDIR}${INST_LIB} ; \
+	 if [ -e "libzoo_service.${EXT}" ]; then rm  libzoo_service.${EXT}; fi ; \
+	 ln -s ${LIBZOO_SERVICE} libzoo_service.${EXT})
+	install -d ${DESTDIR}${INST_INCLUDE}/zoo
+	install service.h service_internal.h ${DESTDIR}${INST_INCLUDE}/zoo
+
+clean:
+	rm -f version.h *.o *.zo *.eo *.tab.c *.tab.h *.sr.c* service_loader lex.* *.lreg *.sibling service_loader.dSYM *${EXT}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/README
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/README	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/README	(revision 672)
@@ -0,0 +1,3 @@
+For information on how to compile and install the ZOO Kernel, please refer to:
+
+http://zoo-project.org/docs/kernel/installation.html
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ZOOMakefile.opts.in
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ZOOMakefile.opts.in	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ZOOMakefile.opts.in	(revision 672)
@@ -0,0 +1,97 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+PREFIX=@prefix@
+INST_LIB=@libdir@
+INST_INCLUDE=@includedir@
+VERSION=1.5
+REVISION=0
+EXT=so
+DEFAULT_OPTS=-Wl,-soname,libzoo_service.so.${VERSION}
+OS:=$(shell uname -s)
+ifeq ($(OS),Darwin)
+	MACOS_LD_FLAGS=-lintl
+	MACOS_LD_NET_FLAGS=-framework SystemConfiguration -framework CoreFoundation
+	MACOS_CFLAGS=-arch $(shell uname -m)
+	EXT=dylib
+	DEFAULT_OPTS=-Wl,-compatibility_version,${VERSION},-current_version,${VERSION},-install_name,${DESTDIR}${INST_LIB}/libzoo_service.${VERSION}.${REVISION}.dylib
+	LIBZOO_SERVICE=libzoo_service.${VERSION}.${REVISION}.${EXT}
+else
+	LIBZOO_SERVICE=libzoo_service.${EXT}.${VERSION}
+endif
+
+CGI_DIR=@CGI_DIR@
+
+YAML_CFLAGS=@YAML_CPPFLAGS@
+YAML_LDFLAGS=@YAML_LDFLAGS@
+YAML_FILE=@YAML_FILE@
+YAML_FILE1=@YAML_FILE1@
+
+GDAL_CFLAGS=@GDAL_CFLAGS@
+GDAL_LIBS=@GDAL_LIBS@
+
+XML2CFLAGS=@XML2_CPPFLAGS@
+XML2LDFLAGS=@XML2_LDFLAGS@
+
+XSLT_CFLAGS=@XSLT_CPPFLAGS@
+XSLT_LDFLAGS=@XSLT_LDFLAGS@
+
+GEOS_CFLAGS=@GEOS_CPPFLAGS@
+GEOS_LDFLAGS=@GEOS_LDFLAGS@
+
+CGAL_CFLAGS=@CGAL_CPPFLAGS@
+CGAL_LDFLAGS=@CGAL_LDFLAGS@
+
+PYTHONCFLAGS=@PYTHON_CPPFLAGS@
+PYTHONLDFLAGS=@PYTHON_LDFLAGS@
+PYTHON_ENABLED=@PYTHON_ENABLED@
+PYTHON_FILE=@PYTHON_FILE@
+
+RUBYCFLAGS=@RUBY_CPPFLAGS@
+RUBYLDFLAGS=@RUBY_LDFLAGS@
+RUBY_ENABLED=@RUBY_ENABLED@
+RUBY_FILE=@RUBY_FILE@
+
+JS_ENABLED=@JS_ENABLED@
+JSCFLAGS=@JS_CPPFLAGS@
+JSLDFLAGS=@JS_LDFLAGS@
+JS_FILE=@JS_FILE@
+ifeq ($(JS_ENABLED),-DUSE_JS)
+     JS_LDFLAGS=${ZRPATH}/zoo-kernel/ulinet.o ${ZRPATH}/zoo-kernel/service_internal_js.o -lcurl 
+endif
+
+MS_CFLAGS=@MS_CFLAGS@
+MS_LDFLAGS=@MS_LIBS@
+MS_FILE=@MS_FILE@
+
+ZOO_CFLAGS=-I${ZRPATH}/../thirds/cgic206/ -I${ZRPATH}/zoo-kernel/
+ZOO_LDFLAGS=-lcrypto -luuid
+
+JAVACFLAGS=@JAVA_CPPFLAGS@
+JAVALDFLAGS=@JAVA_LDFLAGS@
+JAVA_ENABLED=@JAVA_ENABLED@
+JAVA_FILE=@JAVA_FILE@
+
+PHPCFLAGS=@PHP_CPPFLAGS@
+PHPLDFLAGS=@PHP_LDFLAGS@
+PHP_ENABLED=@PHP_ENABLED@
+PHP_FILE=@PHP_FILE@
+
+
+PERLCFLAGS=@PERL_CPPFLAGS@
+PERLLDFLAGS=@PERL_LDFLAGS@
+PERL_ENABLED=@PERL_ENABLED@
+PERL_FILE=@PERL_FILE@
+
+OTBCFLAGS=@OTB_CPPFLAGS@
+OTBLDFLAGS=@OTB_LDFLAGS@
+OTB_ENABLED=@OTB_ENABLED@
+OTB_FILE=@OTB_FILE@
+
+SAGA_CFLAGS=@SAGA_CPPFLAGS@
+SAGA_LDFLAGS=@SAGA_LDFLAGS@
+SAGA_ENABLED=@SAGA_ENABLED@
+SAGA_FILE=@SAGA_FILE@
+
+CFLAGS=@RELY_ON_DB@ @DEB_DEF@ -fpic ${YAML_CFLAGS} ${MACOS_CFLAGS} ${MS_CFLAGS} -I../../thirds/cgic206 -I. -DLINUX_FREE_ISSUE #-DDEBUG #-DDEBUG_SERVICE_CONF
+LDFLAGS=-lzoo_service -lcurl -L../../thirds/cgic206 -lcgic ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lfcgi -lcrypto -luuid ${MS_LDFLAGS} ${MACOS_LD_FLAGS} ${MACOS_LD_NET_FLAGS} ${YAML_LDFLAGS} ${OTBLDFLAGS} ${SAGA_LDFLAGS}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.c	(revision 672)
@@ -0,0 +1,382 @@
+/*
+ * Author : Gérald Fenoy
+ *
+ *  Copyright 2008-2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "caching.h"
+#include "service.h"
+#include "service_internal.h"
+#include "response_print.h"
+#include <openssl/md5.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+/**
+ * Compute md5
+ * 
+ * @param url the char* 
+ * @return a char* representing the md5 of the url
+ * @warning make sure to free ressources returned by this function
+ */
+char* getMd5(char* url){
+  EVP_MD_CTX md5ctx;
+  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
+  unsigned char result[EVP_MAX_MD_SIZE];
+  unsigned int len;
+  EVP_DigestInit(&md5ctx, EVP_md5());
+  EVP_DigestUpdate(&md5ctx, url, strlen(url));
+  EVP_DigestFinal_ex(&md5ctx,result,&len);
+  EVP_MD_CTX_cleanup(&md5ctx);
+  int i;
+  for(i = 0; i < len; i++){
+    if(i>0){
+      char *tmp=strdup(fresult);
+      sprintf(fresult,"%s%02x", tmp,result[i]);
+      free(tmp);
+    }
+    else
+      sprintf(fresult,"%02x",result[i]);
+  }
+  return fresult;
+}
+
+
+/**
+ * Cache a file for a given request.
+ * For each cached file, the are two files stored, a .zca and a .zcm containing
+ * the downloaded content and the mimeType respectively. 
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param request the url used too fetch the content
+ * @param content the downloaded content
+ * @param mimeType the content mimeType 
+ * @param length the content size
+ * @param filepath a buffer for storing the path of the cached file; may be NULL
+ * @param max_path the size of the allocated filepath buffer  
+ */
+void addToCache(maps* conf,char* request,char* content,char* mimeType,int length, 
+                char* filepath, size_t max_path){
+  map* tmp=getMapFromMaps(conf,"main","cacheDir");
+  if(tmp!=NULL){
+    char* md5str=getMd5(request);
+    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
+    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
+#ifdef DEBUG
+    fprintf(stderr,"Cache list : %s\n",fname);
+    fflush(stderr);
+#endif
+    FILE* fo=fopen(fname,"w+");
+    if(fo==NULL){
+#ifdef DEBUG
+      fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno));
+#endif
+      filepath = NULL;	
+      return;
+    }
+    fwrite(content,sizeof(char),length,fo);
+    fclose(fo);
+	
+	if (filepath != NULL) {
+		strncpy(filepath, fname, max_path);
+	}	
+
+    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
+    fo=fopen(fname,"w+");
+#ifdef DEBUG
+    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
+#endif
+    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
+    fclose(fo);
+
+    free(md5str);
+    free(fname);
+  }
+  else {
+	  filepath = NULL;
+  }	  
+}
+
+/**
+ * Verify if a url is available in the cache
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param request the url
+ * @return the full name of the cached file if any, NULL in other case
+ * @warning make sure to free ressources returned by this function (if not NULL)
+ */
+char* isInCache(maps* conf,char* request){
+  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
+  if(tmpM!=NULL){
+    char* md5str=getMd5(request);
+#ifdef DEBUG
+    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
+#endif
+    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
+    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
+    struct stat f_status;
+    int s=stat(fname, &f_status);
+    if(s==0 && f_status.st_size>0){
+      free(md5str);
+      return fname;
+    }
+    free(md5str);
+    free(fname);
+  }
+  return NULL;
+}
+
+/**
+ * Effectively run all the HTTP requests in the queue
+ *
+ * @param m the maps containing the settings of the main.cfg file
+ * @param inputs the maps containing the inputs (defined in the requests+added
+ *  per default based on the zcfg file)
+ * @param hInternet the HINTERNET pointer
+ * @return 0 on success
+ */
+int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet){
+  if(hInternet->nb>0){
+    processDownloads(hInternet);
+    maps* content=*inputs;
+    map* tmp1;
+    int index=0;
+    char sindex[5];
+    while(content!=NULL){
+      
+      map* length=getMap(content->content,"length");
+      int shouldClean=-1;
+      if(length==NULL){
+	length=createMap("length","1");
+	shouldClean=1;
+      }
+      for(int i=0;i<atoi(length->value);i++){
+	char* fcontent;
+	char *mimeType=NULL;
+	int fsize=0;
+	char cname[15];
+	char vname[11];
+	char vname1[11];
+	char sname[9];
+	char mname[15];
+	char icname[14];
+	char xname[16];
+	char oname[12];
+	if(index>0)
+	  sprintf(vname1,"value_%d",index);
+	else
+	  sprintf(vname1,"value");
+
+	if(i>0){
+	  tmp1=getMap(content->content,cname);
+	  sprintf(cname,"cache_file_%d",i);
+	  sprintf(vname,"value_%d",i);
+	  sprintf(sname,"size_%d",i);
+	  sprintf(mname,"mimeType_%d",i);
+	  sprintf(icname,"isCached_%d",i);
+	  sprintf(xname,"Reference_%d",i);
+	  sprintf(oname,"Order_%d",i);
+	}else{
+	  sprintf(cname,"cache_file");
+	  sprintf(vname,"value");
+	  sprintf(sname,"size");
+	  sprintf(mname,"mimeType");
+	  sprintf(icname,"isCached");
+	  sprintf(xname,"Reference");
+	  sprintf(oname,"Order");
+	}
+
+	map* tmap=getMap(content->content,oname);
+	sprintf(sindex,"%d",index+1);
+	if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
+
+	  if(getMap(content->content,icname)==NULL){
+	    
+	    fcontent=(char*)malloc((hInternet->ihandle[index].nDataLen+1)*sizeof(char));
+	    if(fcontent == NULL){
+	      return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
+	    }
+	    size_t dwRead;
+	    InternetReadFile(hInternet->ihandle[index], 
+			     (LPVOID)fcontent, 
+			     hInternet->ihandle[index].nDataLen, 
+			     &dwRead);
+	    fcontent[hInternet->ihandle[index].nDataLen]=0;
+	    fsize=hInternet->ihandle[index].nDataLen;
+	    if(hInternet->ihandle[index].mimeType==NULL)
+	      mimeType=strdup("none");
+	    else
+	      mimeType=strdup(hInternet->ihandle[index].mimeType);	      
+	    
+	    map* tmpMap=getMapOrFill(&content->content,vname,"");
+	    free(tmpMap->value);
+	    tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
+	    if(tmpMap->value==NULL){
+	      return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
+	    }
+	    memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
+	    
+	    char ltmp1[256];
+	    sprintf(ltmp1,"%d",fsize);
+	    map* tmp=getMapFromMaps(*m,"main","cacheDir");
+	    if(tmp!=NULL){
+	      char* md5str=getMd5(tmp1->value);
+	      char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
+	      sprintf(fname,"%s/%s.zca",tmp->value,md5str);
+	      addToMap(content->content,cname,fname);
+	      free(fname);
+	    }
+	    addToMap(content->content,sname,ltmp1);
+	    addToMap(content->content,mname,mimeType);
+	    addToCache(*m,tmp1->value,fcontent,mimeType,fsize, NULL, 0);
+	    free(fcontent);
+	    free(mimeType);
+	    index++;
+
+	  }
+	}
+      }
+      if(shouldClean>0){
+	freeMap(&length);
+	free(length);
+      }
+      
+      content=content->next;
+    }
+    
+  }
+  return 0;
+}
+
+/**
+ * Add a request in the download queue
+ *
+ * @param m the maps containing the settings of the main.cfg file
+ * @param url the url to add to the queue
+ */
+void addRequestToQueue(maps** m,HINTERNET* hInternet,const char* url,bool req){
+  hInternet->waitingRequests[hInternet->nb]=strdup(url);
+  hInternet->ihandle[hInternet->nb].header=NULL;
+  if(req)
+    InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
+  maps *oreq=getMaps(*m,"orequests");
+  if(oreq==NULL){
+    oreq=(maps*)malloc(MAPS_SIZE);
+    oreq->name=zStrdup("orequests");
+    oreq->content=createMap("value",url);
+    oreq->next=NULL;
+    addMapsToMaps(m,oreq);
+    freeMaps(&oreq);
+    free(oreq);
+  }else{
+    setMapArray(oreq->content,"value",hInternet->nb-1,url);
+  }
+}
+
+/**
+ * Try to load file from cache or download a remote file if not in cache
+ *
+ * @param m the maps containing the settings of the main.cfg file
+ * @param content the map to update
+ * @param hInternet the HINTERNET pointer
+ * @param url the url to fetch
+ * @return 0
+ */
+int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
+  char* fcontent;
+  char* cached=isInCache(*m,url);
+  char *mimeType=NULL;
+  int fsize=0;
+
+  map* t=getMap(*content,"xlink:href");
+  if(t==NULL){
+    t=getMap((*content),"href");
+    addToMap(*content,"xlink:href",url);
+  }
+
+  if(cached!=NULL){
+
+    struct stat f_status;
+    int s=stat(cached, &f_status);
+    if(s==0){
+      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+      FILE* f=fopen(cached,"rb");
+      fread(fcontent,f_status.st_size,1,f);
+      fsize=f_status.st_size;
+      fcontent[fsize]=0;
+      fclose(f);
+      addToMap(*content,"cache_file",cached);
+    }
+    cached[strlen(cached)-1]='m';
+    s=stat(cached, &f_status);
+    if(s==0){
+      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+      FILE* f=fopen(cached,"rb");
+      fread(mimeType,f_status.st_size,1,f);
+      mimeType[f_status.st_size]=0;
+      fclose(f);
+    }
+
+  }else{    
+    addRequestToQueue(m,hInternet,url,true);
+    return 0;
+  }
+  if(fsize==0){
+    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
+  }
+  if(mimeType!=NULL){
+    addToMap(*content,"fmimeType",mimeType);
+  }
+
+  map* tmpMap=getMapOrFill(content,"value","");
+    
+  free(tmpMap->value);
+
+  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
+  if(tmpMap->value==NULL)
+    return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
+  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
+
+  char ltmp1[256];
+  sprintf(ltmp1,"%d",fsize);
+  addToMap(*content,"size",ltmp1);
+  if(cached==NULL){
+    addToCache(*m,url,fcontent,mimeType,fsize, NULL, 0);
+  }
+  else{
+    addToMap(*content,"isCached","true");
+    map* tmp=getMapFromMaps(*m,"main","cacheDir");
+    if(tmp!=NULL){
+      map *c=getMap((*content),"xlink:href");
+      char* md5str=getMd5(c->value);
+      char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
+      sprintf(fname,"%s/%s.zca",tmp->value,md5str);
+      addToMap(*content,"cache_file",fname);
+      free(fname);
+    }
+  }
+  free(fcontent);
+  free(mimeType);
+  free(cached);
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/caching.h	(revision 672)
@@ -0,0 +1,40 @@
+/*
+ * Author : Gérald Fenoy
+ *
+ *  Copyright 2008-2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "ulinet.h"
+#include "service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  void addToCache(maps*,char*,char*,char*,int,char*,size_t);
+  char* isInCache(maps*,char*);
+  int runHttpRequests(maps**,maps**,HINTERNET*);
+  void addRequestToQueue(maps**,HINTERNET*,const char*,bool);
+  int loadRemoteFile(maps**,map**,HINTERNET*,char*);
+
+#ifdef __cplusplus
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/configure.ac
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/configure.ac	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/configure.ac	(revision 672)
@@ -0,0 +1,774 @@
+AC_INIT([ZOO Kernel], [1.5.0], [bugs@zoo-project.org])
+
+# Checks for programs.
+AC_PROG_YACC
+AC_PROG_CC
+AC_PROG_LEX
+AC_PROG_CXX
+AC_PROG_SED
+
+# Checks for libraries.
+AC_CHECK_LIB([cgic], [cgiMain])
+AC_CHECK_LIB([curl], [curl_easy_init curl_easy_setopt curl_easy_cleanup curl_easy_perform])
+AC_CHECK_LIB([dl], [dlopen dlsym dlerror dlclose])
+AC_CHECK_LIB([fl], [main])
+AC_CHECK_LIB([pthread], [main])
+AC_CHECK_LIB([ssl], [main])
+
+# Checks for header files.
+AC_FUNC_ALLOCA
+AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h malloc.h stddef.h stdlib.h string.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_TYPE_INT16_T
+AC_TYPE_INT32_T
+AC_TYPE_INT8_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+AC_CHECK_FUNCS([dup2 getcwd memset setenv strdup strstr])
+
+#============================================================================
+# Detect if run on debian / ubuntu
+#============================================================================
+if test -f "/usr/bin/dpkg"
+then
+	DEB_DEF=-DDEB
+fi
+AC_SUBST([DEB_DEF])
+
+AC_ARG_WITH([cgi-dir],
+    [AS_HELP_STRING([--with-cgi-dir=PATH], [Specifies an alternative cgi directory path ( default: /usr/lib/cgi-bin) ])],
+    [CGI_DIR="$withval"], [CGI_DIR="/usr/lib/cgi-bin"])
+AC_SUBST([CGI_DIR])
+
+AC_ARG_WITH([db-backend],
+    [AS_HELP_STRING([--with-db-backend], [Relies on a database for storing status messages and response files ])],
+    [RELY_ON_DB="-DRELY_ON_DB"], [RELY_ON_DB=""])
+AC_SUBST([RELY_ON_DB])
+
+
+# ===========================================================================
+# Detect if libyaml is available
+# ===========================================================================
+
+AC_ARG_WITH([yaml],
+        [AS_HELP_STRING([--with-yaml=PATH], [Specifies an alternative location for the yaml library])],
+        [YAMLPATH="$withval"], [YAMLPATH=""])
+
+if test -z "$YAMLPATH"
+then
+	YAML_LDFLAGS=""
+	YAML_CPPFLAGS=""
+	YAML_FILE=""
+	YAML_FILE1=""
+else
+
+	# Extract the linker and include flags
+	YAML_LDFLAGS="-L$YAMLPATH/lib -lyaml"
+	YAML_CPPFLAGS="-I$YAMLPATH/include -DYAML"
+	YAML_FILE="service_yaml.o"
+	YAML_FILE1="zcfg2yaml"
+	
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$YAML_CPPFLAGS"
+	LIBS_SAVE="$LIBS"
+	LIBS="$YAML_LDFLAGS"
+	AC_CHECK_LIB([yaml], [yaml_parser_initialize,yaml_parser_set_input_file,yaml_parser_scan])
+	AC_CHECK_HEADERS([yaml.h],
+                 [], [AC_MSG_ERROR([could not find headers include related to YAML])])
+	LIBS="$LIBS_SAVE"
+fi
+AC_SUBST([YAML_CPPFLAGS])
+AC_SUBST([YAML_LDFLAGS])
+AC_SUBST([YAML_FILE])
+AC_SUBST([YAML_FILE1])
+
+# ===========================================================================
+# Detect if fastcgi is available
+# ===========================================================================
+
+AC_ARG_WITH([fastcgi],
+        [AS_HELP_STRING([--with-fastcgi=PATH], [Specifies an alternative location for the fastcgi library])],
+        [FCGIPATH="$withval"], [FCGIPATH="/usr"])
+
+# Extract the linker and include flags
+FCGI_LDFLAGS="-L$FCGIPATH/lib"
+FCGI_CPPFLAGS="-I$FCGIPATH/include"
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$FCGI_CPPFLAGS"
+LIBS_SAVE="$LIBS"
+LIBS="$FCGI_LDFLAGS"
+AC_CHECK_LIB([fcgi], [main])
+AC_CHECK_HEADERS([fcgi_stdio.h],
+                 [], [AC_MSG_ERROR([could not find headers include related to fastcgi])])
+LIBS="$LIBS_SAVE"
+AC_SUBST([FCGI_CPPFLAGS])
+AC_SUBST([FCGI_LDFLAGS])
+
+# ===========================================================================
+# Detect if libxml2 is installed
+# ===========================================================================
+
+AC_ARG_WITH([xml2config], 
+	[AS_HELP_STRING([--with-xml2config=FILE], [Specifies an alternative xml2-config file])], 
+	[XML2CONFIG="$withval"], [XML2CONFIG=""])
+
+if test "x$XML2CONFIG" = "x"; then
+	# XML2CONFIG was not specified, so search within the current path
+	AC_PATH_PROG([XML2CONFIG], [xml2-config])
+
+	# If we couldn't find xml2-config, display a warning
+	if test "x$XML2CONFIG" = "x"; then
+		AC_MSG_ERROR([could not find xml2-config from libxml2 within the current path. You may need to try re-running configure with a --with-xml2config parameter.])
+	fi
+else
+	# XML2CONFIG was specified; display a message to the user
+	if test "x$XML2CONFIG" = "xyes"; then
+		AC_MSG_ERROR([you must Specifies a parameter to --with-xml2config, e.g. --with-xml2config=/path/to/xml2-config])
+	else
+		if test -f $XML2CONFIG; then
+			AC_MSG_RESULT([Using user-specified xml2-config file: $XML2CONFIG])
+		else
+			AC_MSG_ERROR([the user-specified xml2-config file $XML2CONFIG does not exist])
+		fi	
+	fi
+fi
+
+# Extract the linker and include flags 
+XML2_LDFLAGS=`$XML2CONFIG --libs`
+XML2_CPPFLAGS=`$XML2CONFIG --cflags`
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$XML2_CPPFLAGS"
+AC_CHECK_HEADERS([libxml/tree.h libxml/parser.h libxml/xpath.h libxml/xpathInternals.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libxml2])])
+
+# Ensure we can link against libxml2
+LIBS_SAVE="$LIBS"
+LIBS="$XML2_LDFLAGS"
+AC_CHECK_LIB([xml2], [xmlInitParser], [], [AC_MSG_ERROR([could not find libxml2])], [])
+
+AC_SUBST([XML2_CPPFLAGS])
+AC_SUBST([XML2_LDFLAGS])
+LIBS="$LIBS_SAVE"
+
+
+# ===========================================================================
+# Detect if libxslt is installed
+# ===========================================================================
+
+AC_ARG_WITH([xsltconfig], 
+	[AS_HELP_STRING([--with-xsltconfig=FILE], [Specifies an alternative xslt-config file])], 
+	[XSLTCONFIG="$withval"], [XSLTCONFIG=""])
+
+if test "x$XSLTCONFIG" = "x"; then
+	# XSLTCONFIG was not specified, so search within the current path
+	AC_PATH_PROG([XSLTCONFIG], [xslt-config])
+
+	# If we couldn't find xslt-config, display a warning
+	if test "x$XSLTCONFIG" = "x"; then
+		AC_MSG_ERROR([could not find xslt-config from libxslt within the current path. You may need to try re-running configure with a --with-xtltconfig parameter.])
+	fi
+else
+	# XSLTCONFIG was specified; display a message to the user
+	if test "x$XSLTCONFIG" = "xyes"; then
+		AC_MSG_ERROR([you must Specifies a parameter to --with-xsltconfig, e.g. --with-xsltconfig=/path/to/xslt-config])
+	else
+		if test -f $XSLTCONFIG; then
+			AC_MSG_RESULT([Using user-specified xslt-config file: $XSLTCONFIG])
+		else
+			AC_MSG_ERROR([the user-specified xslt-config file $XSLTCONFIG does not exist])
+		fi	
+	fi
+fi
+
+# Extract the linker and include flags 
+XSLT_LDFLAGS=`$XSLTCONFIG --libs`
+XSLT_CPPFLAGS=`$XSLTCONFIG --cflags`
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$XSLT_CPPFLAGS"
+AC_CHECK_HEADERS([libxslt/xslt.h libxslt/xsltInternals.h libxslt/transform.h libxslt/xsltutils.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libxlst])])
+
+AC_SUBST([XSLT_CPPFLAGS])
+AC_SUBST([XSLT_LDFLAGS])
+
+#============================================================================
+# Detect if gdal is installed
+#============================================================================
+
+AC_ARG_WITH([gdal-config], 
+	[AS_HELP_STRING([--with-gdal-config=FILE], [Specifies an alternative gdal-config file])], 
+	[GDAL_CONFIG="$withval"], [GDAL_CONFIG=""])
+if test -z $GDAL_CONFIG;
+then
+	AC_PATH_PROG([GDAL_CONFIG], [gdal-config])
+	if test -z $GDAL_CONFIG; 
+	then
+		AC_MSG_ERROR([could not find gdal-config from libgdal within the current path. You may need to try re-running configure with a --with-gdal-config parameter.])
+	fi
+	
+else
+	if test -f $GDAL_CONFIG; then
+		AC_MSG_RESULT([Using user-specified gdal-config file: $GDAL_CONFIG])
+	else
+		AC_MSG_ERROR([the user-specified gdal-config file $GDAL_CONFIG does not exist])
+	fi
+fi
+
+GDAL_CFLAGS="`$GDAL_CONFIG --cflags`"
+GDAL_LIBS="`$GDAL_CONFIG --libs`"
+
+AC_SUBST([GDAL_CFLAGS])
+AC_SUBST([GDAL_LIBS])
+
+# ===========================================================================
+# Detect if proj is installed
+# ===========================================================================
+
+AC_ARG_WITH([proj],
+        [AS_HELP_STRING([--with-proj=PATH], [Specifies an alternative location for PROJ4 setup])],
+        [PROJPATH="$withval"], [PROJPATH=""])
+
+# Extract the linker and include flags
+PROJ_LDFLAGS="-L$PROJPATH/lib"
+PROJ_CPPFLAGS="-I$PROJPATH/include"
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$PROJ_CPPFLAGS"
+AC_CHECK_HEADERS([proj_api.h],
+                 [], [AC_MSG_ERROR([could not find headers include related to PROJ4])])
+
+AC_SUBST([PROJ_CPPFLAGS])
+AC_SUBST([PROJ_LDFLAGS])
+
+# ===========================================================================
+# Detect if libgeos is installed
+# ===========================================================================
+
+AC_ARG_WITH([geosconfig], 
+	[AS_HELP_STRING([--with-geosconfig=FILE], [Specifies an alternative geos-config file])], 
+	[GEOSCONFIG="$withval"], [GEOSCONFIG=""])
+
+if test "x$GEOSCONFIG" = "x"; then
+	# GEOSCONFIG was not specified, so search within the current path
+	AC_PATH_PROG([GEOSCONFIG], [geos-config])
+
+	# If we couldn't find geos-config, display a warning
+	if test "x$GEOSCONFIG" = "x"; then
+		AC_MSG_WARN([could not find geos-config from libgeos within the current path. You may need to try re-running configure with a --with-geosconfig parameter.])
+	fi
+else
+	# GEOSCONFIG was specified; display a message to the user
+	if test "x$GEOSCONFIG" = "xyes"; then
+		AC_MSG_WARN([you must Specifies a parameter to --with-geosconfig, e.g. --with-geosconfig=/path/to/geos-config])
+	else
+		if test -f $GEOSCONFIG; then
+			AC_MSG_RESULT([Using user-specified geos-config file: $GEOSCONFIG])
+		else
+			AC_MSG_ERROR([the user-specified geos-config file $GEOSCONFIG does not exist])
+		fi	
+	fi
+fi
+
+GEOS_LDFLAGS=`$GEOSCONFIG --libs`
+GEOS_CPPFLAGS=`$GEOSCONFIG --cflags`
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$GEOS_CPPFLAGS"
+AC_CHECK_HEADERS([geos_c.h],
+		 [], [AC_MSG_WARN([could not find headers include related to libgeos])])
+
+AC_SUBST([GEOS_CPPFLAGS])
+AC_SUBST([GEOS_LDFLAGS])
+
+
+# ===========================================================================
+# Detect if cgal is installed
+# ===========================================================================
+
+AC_ARG_WITH([cgal],
+        [AS_HELP_STRING([--with-cgal=PATH], [Specifies an alternative location for CGAL setup])],
+        [CGALPATH="$withval"], [CGALPATH="/usr"])
+
+
+# Check headers file
+CPPFLAGS_SAVE="$CPPFLAGS"
+CPPFLAGS="$CGAL_CPPFLAGS"
+AC_CHECK_HEADERS([CGAL/Delaunay_triangulation_2.h],
+         [], [AC_MSG_WARN([could not find headers include related to libCGAL])])
+
+# Extract the linker and include flags
+CGAL_LDFLAGS="-L$CGALPATH/lib"
+CGAL_CPPFLAGS="-I$CGALPATH/include"
+
+
+AC_SUBST([CGAL_CPPFLAGS])
+AC_SUBST([CGAL_LDFLAGS])
+#============================================================================
+# Detect if mapserver is installed
+#============================================================================
+
+AC_ARG_WITH([mapserver], 
+       [AS_HELP_STRING([--with-mapserver=PATH], [Specifies the path for MapServer compiled source tree])], 
+       [MS_SRC_PATH="$withval"], [MS_SRC_PATH=""])
+
+if test -z $MS_SRC_PATH;
+then
+	MS_CPPFLAGS=""
+	MS_LDFLAGS=""
+else
+       if test "x$MS_SRC_PATH" = "xmacos";
+       then
+               MS_LDFLAGS="/Library/Frameworks/MapServer.framework//Versions/6.0/MapServer -lintl"
+               MS_CPPFLAGS="-DUSE_MS `/Library/Frameworks/MapServer.framework/Programs/mapserver-config --includes` -I/Library/Frameworks/MapServer.framework/Versions/Current/Headers/ -I../mapserver "
+               AC_MSG_WARN([Please make sure that ../mapserver exists and contains MapServer source tree])
+               AC_MSG_RESULT([Using MacOS X Framework for MapServer])
+       else
+               if test -d $MS_SRC_PATH; then
+                       MS_LDFLAGS="-L$MS_SRC_PATH -lmapserver `$MS_SRC_PATH/mapserver-config --libs`"
+                       MS_CPPFLAGS="-DUSE_MS `$MS_SRC_PATH/mapserver-config --includes` `$MS_SRC_PATH/mapserver-config --cflags` -I$MS_SRC_PATH "
+               
+                       AC_MSG_RESULT([Using user-specified MapServer src path: $MS_SRC_PATH])
+               else
+                       AC_MSG_ERROR([the user-specified mapserver-config file $MS_SRC_PATH does not exist])
+               fi
+       fi
+       MS_FILE="service_internal_ms.o"
+fi
+
+MS_CFLAGS="$MS_CPPFLAGS"
+MS_LIBS="$MS_LDFLAGS"
+
+AC_SUBST([MS_CFLAGS])
+AC_SUBST([MS_LIBS])
+AC_SUBST([MS_FILE])
+
+# ===========================================================================
+# Detect if python is installed
+# ===========================================================================
+
+AC_ARG_WITH([python], 
+	[AS_HELP_STRING([--with-python=PATH], [To enable python support or Specifies an alternative directory for python installation,  disabled by default])], 
+	[PYTHON_PATH="$withval"; PYTHON_ENABLED="-DUSE_PYTHON"], [PYTHON_ENABLED=""])
+
+AC_ARG_WITH([pyvers], 
+	[AS_HELP_STRING([--with-pyvers=NUM], [To use a specific python version])], 
+	[PYTHON_VERS="$withval"], [PYTHON_VERS=""])
+
+
+if test -z "$PYTHON_ENABLED"
+then
+	PYTHON_FILE=""
+else
+	PYTHONCONFIG="$PYTHON_PATH/bin/python${PYTHON_VERS}-config"
+	PYTHON_FILE="service_internal_python.o"
+	if test  "$PYTHON_PATH" = "yes"
+	then
+		# PHP was not specified, so search within the current path
+		PYTHONCFG_PATH=`which python${PYTHON_VERS}-config`
+		if test -z "${PYTHONCFG_PATH}" ; then
+		AC_PATH_PROG([PYTHONCONFIG], [python-config-${PYTHON_VERS}])
+		else
+		AC_PATH_PROG([PYTHONCONFIG], [python${PYTHON_VERS}-config])
+		fi
+	else
+		PYTHONCONFIG="$PYTHON_PATH/bin/python${PYTHON_VERS}-config"
+	fi
+
+	# Extract the linker and include flags 
+	PYTHON_LDFLAGS=`$PYTHONCONFIG --ldflags`
+	PYTHON_CPPFLAGS=`$PYTHONCONFIG --includes`
+
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$PYTHON_CPPFLAGS"
+	AC_CHECK_HEADERS([Python.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libpython])])
+
+	# Ensure we can link against libphp
+	LIBS_SAVE="$LIBS"
+	LIBS="$PYTHON_LDFLAGS"
+	PY_LIB=`$PYTHONCONFIG --libs | sed -e 's/^.*\(python2\..\)$/\1/'`
+	AC_CHECK_LIB([$PY_LIB], [PyObject_CallObject], [], [AC_MSG_ERROR([could not find libpython])], [])
+	AC_SUBST([PYTHON_CPPFLAGS])
+	AC_SUBST([PYTHON_LDFLAGS])
+	LIBS="$LIBS_SAVE"
+fi
+
+AC_SUBST([PYTHON_ENABLED])
+AC_SUBST([PYTHON_FILE])
+
+# ===========================================================================
+# Detect if spidermonkey is installed
+# ===========================================================================
+
+AC_ARG_WITH([js], 
+	[AS_HELP_STRING([--with-js=PATH], [Specifies --with-js=path-to-js to enable js support, specify --with-js on linux debian like, js support is disabled by default ])], 
+	[JSHOME="$withval";JS_ENABLED="-DUSE_JS"], [JS_ENABLED=""])
+
+if test -z "$JS_ENABLED"
+then
+	JS_FILE=""
+else
+	JS_FILE="service_internal_js.o"
+	if test "$JSHOME" = "yes"
+	then
+
+		#on teste si on est sous debian like 
+		if test -f "/usr/bin/dpkg"
+		then
+			if test -n "`dpkg -l | grep libmozjs185-dev`"
+			then
+				JS_CPPFLAGS="-I/usr/include/js/"
+                        	JS_LDFLAGS="-L/usr/lib -lmozjs185 -lm"
+                        	JS_LIB="mozjs185"
+			else 
+				XUL_VERSION="`dpkg -l | grep xulrunner | grep dev | head -1| awk '{print $3;}' | cut -d'+' -f1`"
+				if test -n "$XUL_VERSION"
+				then
+					JS_CPPFLAGS="-I/usr/include/xulrunner-$XUL_VERSION"
+					JS_LDFLAGS="-L/usr/lib/xulrunner-$XUL_VERSION -lmozjs -lm"
+					JS_LIB="mozjs"
+				else
+					AC_MSG_ERROR([You must install libmozjs185-dev or xulrunner-dev ])
+				fi
+			fi
+		else
+			AC_MSG_ERROR([You must  specify your custom install of libmozjs185])
+		fi
+	else
+		JS_CPPFLAGS="-I$JSHOME/include/js/"
+                JS_LDFLAGS="-L$JSHOME/lib -lmozjs185 -lm"
+                JS_LIB="mozjs185"
+
+	fi 
+	CPPFLAGS_SAVE="$CPPFLAGS"
+        CPPFLAGS="$JS_CPPFLAGS"
+	AC_LANG_PUSH([C++])
+	AC_CHECK_HEADERS([jsapi.h],
+                        [], [AC_MSG_ERROR([could not find headers include related to libjs])])
+
+	AC_LANG_POP([C++])
+	LIBS_SAVE="$LIBS"
+        LIBS="$JS_LDFLAGS"
+
+        AC_CHECK_LIB([$JS_LIB], [JS_CompileFile,JS_CallFunctionName], [], [AC_MSG_ERROR([could not find $JS_LIB])], [])
+	LIBS="$LIBS_SAVE"
+	
+        AC_SUBST([JS_CPPFLAGS])
+        AC_SUBST([JS_LDFLAGS])
+fi
+
+AC_SUBST([JS_ENABLED])
+AC_SUBST([JS_FILE])
+
+# ===========================================================================
+# Detect if php is installed
+# ===========================================================================
+
+AC_ARG_WITH([php], 
+	[AS_HELP_STRING([--with-php=PATH], [To enable php support or specify an alternative directory for php installation,  disabled by default])], 
+	[PHP_PATH="$withval"; PHP_ENABLED="-DUSE_PHP"], [PHP_ENABLED=""])
+
+
+if test -z "$PHP_ENABLED"
+then
+	PHP_FILE=""
+else
+	PHPCONFIG="$PHP_PATH/bin/php-config"
+	PHP_FILE="service_internal_php.o"
+	if test  "$PHP_PATH" = "yes"
+	then
+		# PHP was not specified, so search within the current path
+		AC_PATH_PROG([PHPCONFIG], [php-config])
+	else
+		PHPCONFIG="$PHP_PATH/bin/php-config"
+	fi
+
+	# Extract the linker and include flags 
+	PHP_LDFLAGS="-L/`$PHPCONFIG --prefix`/lib -lphp5"
+	PHP_CPPFLAGS=`$PHPCONFIG --includes`
+
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$PHP_CPPFLAGS"
+	AC_CHECK_HEADERS([sapi/embed/php_embed.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libphp])])
+
+	# Ensure we can link against libphp
+	LIBS_SAVE="$LIBS"
+	LIBS="$PHP_LDFLAGS"
+	# Shouldn't we get php here rather than php5 :) ??
+	AC_CHECK_LIB([php5], [call_user_function], [], [AC_MSG_ERROR([could not find libphp])], [])
+	LIBS="$LIBS_SAVE"
+	AC_SUBST([PHP_CPPFLAGS])
+	AC_SUBST([PHP_LDFLAGS])
+fi
+
+AC_SUBST([PHP_ENABLED])
+AC_SUBST([PHP_FILE])
+
+# ===========================================================================
+# Detect if java is installed
+# ===========================================================================
+
+AC_ARG_WITH([java], 
+	[AS_HELP_STRING([--with-java=PATH], [To enable java support, specify a JDK_HOME,  disabled by default])], 
+	[JDKHOME="$withval"; JAVA_ENABLED="-DUSE_JAVA"], [JAVA_ENABLED=""])
+
+if test -z "$JAVA_ENABLED"
+then
+	JAVA_FILE=""
+else
+	JAVA_FILE="service_internal_java.o"
+	if test "x$JDKHOME" = "x"; 
+	then
+		AC_MSG_ERROR([could not find java installation path within the current path. You may need to try re-running configure with a --with-java parameter.])
+	fi	# JAVA was specified; display a message to the user
+	if test "x$JDKHOME" = "xyes"; 
+	then
+		AC_MSG_ERROR([you must specify a parameter to --with-java, e.g. --with-java=/path/to/java])
+	fi
+
+	# Extract the linker and include flags
+	if test "x$JDKHOME" = "xmacos";
+	then
+		JAVA_LDFLAGS="-framework JavaVM"
+		JAVA_CPPFLAGS="-I/Applications/Xcode.app/Contents/Developer//Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/"
+	else
+		if test -d "$JDKHOME/jre/lib/i386";
+		then
+			JAVA_LDFLAGS="-L$JDKHOME/jre/lib/i386/server/ -ljvm -lpthread"
+			JAVA_CPPFLAGS="-I$JDKHOME/include -I$JDKHOME/include/linux"
+		else
+			JAVA_LDFLAGS="-L$JDKHOME/jre/lib/amd64/server/ -ljvm -lpthread"
+			JAVA_CPPFLAGS="-I$JDKHOME/include -I$JDKHOME/include/linux"
+		fi
+	fi
+
+	# Check headers file (second time we check that in fact)
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$JAVA_CPPFLAGS"
+	AC_CHECK_HEADERS([jni.h],
+			 [], [AC_MSG_ERROR([could not find jni.h file])])
+
+	# Ensure we can link against libjava
+	LIBS_SAVE="$LIBS"
+	LIBS="$JAVA_LDFLAGS"
+	if test "x$JDKHOME" != "xmacos";
+	then
+		AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [], [AC_MSG_ERROR([could not find libjvm])], [])
+	fi
+	LIBS="$LIBS_SAVE"
+
+	AC_SUBST([JAVA_CPPFLAGS])
+	AC_SUBST([JAVA_LDFLAGS])
+fi 
+
+AC_SUBST([JAVA_ENABLED])
+AC_SUBST([JAVA_FILE])
+
+# ===========================================================================
+# Detect if ruby is installed
+# ===========================================================================
+AC_ARG_WITH([ruby], 
+	[AS_HELP_STRING([--with-ruby=PATH], [To enable ruby support or specify an alternative directory for ruby installation,  disabled by default])], 
+	[RUBY_PATH="$withval"; RUBY_ENABLED="-DUSE_RUBY"], [RUBY_ENABLED=""])
+
+AC_ARG_WITH([rvers], 
+	[AS_HELP_STRING([--with-rvers=NUM], [To use a specific ruby version])], 
+	[RUBY_VERS="$withval"], [RUBY_VERS=""])
+
+
+if test -z "$RUBY_ENABLED"
+then
+	RUBY_FILE=""
+else
+	RUBY_FILE="service_internal_ruby.o"
+
+	# Extract the linker and include flags 
+	RUBY_LDFLAGS="-lruby"
+	RUBY_CPPFLAGS="-I$RUBY_PATH -I$RUBY_PATH/x86_64-darwin13.0/ -DZRUBY_VERSION=$RUBY_VERS"
+
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$RUBY_CPPFLAGS"
+	AC_CHECK_HEADERS([ruby.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libruby])])
+
+	# Ensure we can link against libphp
+	LIBS_SAVE="$LIBS"
+	LIBS="$RUBY_LDFLAGS"
+	# AC_CHECK_LIB([lruby], [PyObject_CallObject], [], [AC_MSG_ERROR([could not find libpython])], [])
+	LIBS="$LIBS_SAVE"
+	AC_SUBST([RUBY_CPPFLAGS])
+	AC_SUBST([RUBY_LDFLAGS])
+fi
+
+AC_SUBST([RUBY_ENABLED])
+AC_SUBST([RUBY_FILE])
+
+# ===========================================================================
+# Detect if perl is installed
+# ===========================================================================
+
+AC_ARG_WITH([perl], 
+	[AS_HELP_STRING([--with-perl=PATH], [To enable perl support or specify an alternative directory for perl installation,  disabled by default])], 
+	[PERL_PATH="$withval"; PERL_ENABLED="-DUSE_PERL"], [PERL_ENABLED=""])
+
+
+if test -z "$PERL_ENABLED"
+then
+	PERL_FILE=""
+else
+	PERL_FILE="service_internal_perl.o"
+	if test  "$PERL_PATH" = "yes"
+	then
+		# Perl was not specified, so search within the current path
+		AC_PATH_PROG([PERLCONFIG], [perl])
+	else
+		PERLCONFIG="$PERL_PATH/bin/perl"
+	fi
+
+	# Extract the linker and include flags 
+	PERL_LDFLAGS=`$PERLCONFIG -MExtUtils::Embed -e ldopts`
+	PERL_CPPFLAGS=`$PERLCONFIG -MExtUtils::Embed -e ccopts`
+
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$PERL_CPPFLAGS"
+	AC_CHECK_HEADERS([EXTERN.h],
+		 [], [AC_MSG_ERROR([could not find headers include related to libperl])])
+
+	AC_SUBST([PERL_CPPFLAGS])
+	AC_SUBST([PERL_LDFLAGS])
+fi
+
+AC_SUBST([PERL_ENABLED])
+AC_SUBST([PERL_FILE])
+
+# ===========================================================================
+# Detect if otb is available
+# ===========================================================================
+
+AC_ARG_WITH([itk],
+        [AS_HELP_STRING([--with-itk=PATH], [Specifies an alternative location for the itk library])],
+        [ITKPATH="$withval"], [ITKPATH=""])
+
+AC_ARG_WITH([itk-version],
+        [AS_HELP_STRING([--with-itk-version=VERSION], [Specifies an alternative version for the itk library])],
+        [ITKVERS="$withval"], [ITKVERS=""])
+
+AC_ARG_WITH([otb],
+        [AS_HELP_STRING([--with-otb=PATH], [Specifies an alternative location for the otb library])],
+        [OTBPATH="$withval"], [OTBPATH=""])
+
+if test -z "$OTBPATH"
+then
+	OTB_LDFLAGS=""
+	OTB_CPPFLAGS=""
+	OTB_FILE=""
+	OTB_ENABLED=""
+else
+	if test -z "$ITKVERS" 
+    	then
+		ITKVERS="4.5"
+    	fi
+	OTB_ENABLED="-DUSE_OTB"
+	OTB_LDFLAGS="-L$OTBPATH/lib/otb -lOTBIO -lOTBCommon -lOTBApplicationEngine -L$ITKPATH/lib -lITKBiasCorrection-$ITKVERS -lITKCommon-$ITKVERS -lITKIOImageBase-$ITKVERS -lITKKLMRegionGrowing-$ITKVERS -lITKLabelMap-$ITKVERS -lITKMesh-$ITKVERS -lITKMetaIO-$ITKVERS -lITKOptimizers-$ITKVERS -lITKPath-$ITKVERS -lITKPolynomials-$ITKVERS -lITKQuadEdgeMesh-$ITKVERS -lITKSpatialObjects-$ITKVERS -lITKStatistics-$ITKVERS -lITKVNLInstantiation-$ITKVERS -lITKWatersheds-$ITKVERS -litkNetlibSlatec-$ITKVERS -litksys-$ITKVERS -litkdouble-conversion-$ITKVERS -litkv3p_lsqr-$ITKVERS -litkv3p_netlib-$ITKVERS -litkvcl-$ITKVERS -litkvnl-$ITKVERS -litkvnl_algo-$ITKVERS -litkzlib-$ITKVERS"
+	OTB_CPPFLAGS="-I$OTBPATH/include/otb/ApplicationEngine -I$OTBPATH/include/otb/Common -I$ITKPATH/include/ITK-$ITKVERS -I$OTBPATH/include/otb/Utilities/ITK -I$OTBPATH/include/otb/ -I$OTBPATH/include/otb/IO -I$OTBPATH/include/otb/UtilitiesAdapters/OssimAdapters -I$OTBPATH/include/otb/UtilitiesAdapters/CurlAdapters -I$OTBPATH/include/otb/Utilities/BGL -I$OTBPATH/include/otb/UtilitiesAdapters/ITKPendingPatches -I$OTBPATH/include/otb/Utilities/otbconfigfile $GDAL_CFLAGS"
+	OTB_FILE="otbZooWatcher.o service_internal_otb.o"
+	
+	AC_LANG_PUSH([C++])
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$OTB_CPPFLAGS"
+	LDFLAGS_SAVE="$LDFLAGS"
+	LIBS="$LIBS_SAVE $OTB_LDFLAGS"
+	AC_CHECK_HEADERS([otbWrapperApplication.h otbWrapperInputImageListParameter.h otbWrapperApplicationRegistry.h],
+			[], [AC_MSG_ERROR([could not find header file $i related to OTB])])
+	AC_LANG_POP([C++])
+	AC_LANG(C++)
+	LDFLAGS_SAVE="$LDFLAGS"
+	LDFLAGS="$OTB_LDFLAGS"
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "otbWrapperApplication.h"],[std::vector<std::string> list = otb::Wrapwper::ApplicationRegistry::GetAvailableApplication();]])],
+		[AC_MSG_RESULT([checking for GetAvailableApplication... yes])],[AC_MSG_ERROR([checking for GetAvailableApplication... failed])])
+	LDFLAGS="$LDFLAGS_SAVE"
+			
+fi
+AC_SUBST([OTB_CPPFLAGS])
+AC_SUBST([OTB_LDFLAGS])
+AC_SUBST([OTB_FILE])
+AC_SUBST([OTB_ENABLED])
+
+# ===========================================================================
+# Detect if saga-gis is available
+# ===========================================================================
+
+AC_ARG_WITH([wx-config],
+        [AS_HELP_STRING([--with-wx-config=PATH], [Specifies an alternative path for the wx-config tool])],
+        [WXCFG="$withval"], [WXCFG=""])
+
+AC_ARG_WITH([saga],
+        [AS_HELP_STRING([--with-saga=PATH], [Specifies an alternative location for the SAGA-GIS library])],
+        [SAGAPATH="$withval"], [SAGAPATH=""])
+
+if test -z "$SAGAPATH"
+then
+	SAGA_LDFLAGS=""
+	SAGA_CPPFLAGS=""
+	SAGA_FILE=""
+	SAGA_ENABLED=""
+else
+	if test -z "$WXCFG" ; then
+	   WXCFG="$(which wx-config)"
+	fi
+	if test "`$WXCFG --list | grep unicode`" == "" ; then
+	   AC_MSG_ERROR(SAGA requires a unicode build of wxGTK)
+	fi
+	WX_ISSUE="-D_WX_WXCRTVARARG_H_"
+	SAGA_DEFS="-D_SAGA_LINUX -D_TYPEDEF_BYTE -D_TYPEDEF_WORD -DMODULE_LIBRARY_PATH=\\\"$SAGAPATH/lib/saga\\\""
+	SAGA_CPPFLAGS=" -fPIC -I$SAGAPATH/include/saga/saga_core/saga_api/ `$WXCFG --unicode=yes --static=no --cxxflags` -D_SAGA_UNICODE $SAGA_DEFS $WX_ISSUE"
+	SAGA_LDFLAGS="-fPIC `$WXCFG --unicode=yes --static=no --libs` -lsaga_api"
+	SAGA_ENABLED="-DUSE_SAGA"
+	SAGA_FILE="service_internal_saga.o"
+	
+	AC_LANG_PUSH([C++])
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$SAGA_CPPFLAGS"
+	LIBS_SAVE="$LIBS"
+	LIBS="$SAGA_LDFLAGS"
+	AC_CHECK_HEADERS([module_library.h],
+			[], [AC_MSG_ERROR([could not find header file $i related to SAGA-GIS])])
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "module_library.h"],[SG_Get_Module_Library_Manager();]])],
+		[AC_MSG_RESULT([checking for SG_Get_Module_Library_Manager... yes])],[AC_MSG_ERROR([checking for SG_Get_Module_Library_Manager... failed])])
+	LIBS="$LIBS_SAVE"
+	AC_LANG_POP([C++])
+fi
+AC_SUBST([SAGA_CPPFLAGS])
+AC_SUBST([SAGA_LDFLAGS])
+AC_SUBST([SAGA_FILE])
+AC_SUBST([SAGA_ENABLED])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([ZOOMakefile.opts])
+AC_OUTPUT
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/doc/index.dox
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/doc/index.dox	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/doc/index.dox	(revision 672)
@@ -0,0 +1,20 @@
+#ifndef DOXYGEN_SKIP                                                            
+/* $Id$ */               
+#endif /* DOXYGEN_SKIP */                                                       
+
+/*! \mainpage ZOO-Project C-API Documentation
+
+
+<a href="http://zoo-project.org/">ZOO-Project</a> is an open source WPS platform
+that is released under an <a href="http://zoo-project.org/trac/browser/trunk/zoo-project/LICENSE">X/MIT</a> style 
+<a href="http://www.opensource.org/"> Open Source</a> license. ZOO-Project software is incubating at the <a href="http://www.osgeo.org/">Open Source
+Geospatial Foundation</a>. 
+
+Home: http://www.zoo-project.org<br>
+Download: 
+ <a href="http://zoo-project.org/site/Downloads#Downloads">http at zoo-project.org</a>,
+ <a href="http://zoo-project.org/site/Downloads#Fordevelopers">svn at zoo-project.org</a>
+
+This documentation describes the ZOO-Project C-API. You can start your visit by the Data Structures link above which details all available structures in ZOO-Project. The Files link presents all source files used to generate this documentation.
+
+*/
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/en_US.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/en_US.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/en_US.utf8.po	(revision 672)
@@ -0,0 +1,171 @@
+# English translations for ZOO Kernel package.
+# Copyright (C) 2010 THE ZOO Kernel'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ZOO Kernel package.
+# root <gerald.fenoy@geolabs.fr>, 2010.
+#
+#: service_internal.c:1672 zoo_service_loader.c:158 zoo_service_loader.c:160
+#: zoo_service_loader.c:220 zoo_service_loader.c:267 zoo_service_loader.c:341
+#: zoo_service_loader.c:1135 zoo_service_loader.c:1277
+#: zoo_service_loader.c:1364
+msgid ""
+msgstr ""
+"Project-Id-Version: ZOO Kernel 0.0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 00:38+0200\n"
+"PO-Revision-Date: 2010-09-28 00:39+0200\n"
+"Last-Translator: root <gerald.fenoy@geolabs.fr>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: service_internal.c:1056
+#, c-format
+msgid ""
+"ZOO Service \"%s\" is currently running. Please, reload this document to get "
+"the up-to-date status of the Service."
+msgstr ""
+"ZOO Service \"%s\" is currently running. Please, reload this document to get "
+"the up-to-date status of the Service."
+
+#: service_internal.c:1062
+#, c-format
+msgid ""
+"Service \"%s\" was accepted by the ZOO Kernel and it run as a background "
+"task. Please consult the statusLocation attribtue providen in this document "
+"to get the up-to-date document."
+msgstr ""
+"Service \"%s\" was accepted by the ZOO Kernel and it run as a background "
+"task. Please consult the statusLocation attribtue providen in this document "
+"to get the up-to-date document."
+
+#: service_internal.c:1079
+msgid "No more information available"
+msgstr "No more information available"
+
+#: service_internal.c:1432 service_internal.c:1485
+msgid "No debug message available"
+msgstr "No debug message available"
+
+#: service_internal.c:1546
+msgid "Unable to fetch any result"
+msgstr "Unable to fetch any result"
+
+#: service_internal.c:1587
+#, c-format
+msgid ""
+"Unable to run the Service. The message returned back by the Service was the "
+"following : %s"
+msgstr ""
+"Unable to run the Service. The message returned back by the Service was the "
+"following : %s"
+
+#: service_internal.c:1589
+#, c-format
+msgid ""
+"Unable to run the Service. No more information was returned back by the "
+"Service."
+msgstr ""
+"Unable to run the Service. No more information was returned back by the "
+"Service."
+
+#: zoo_service_loader.c:119
+#, c-format
+msgid "ZOO Kernel failed to process your request receiving signal %d = %s"
+msgstr "ZOO Kernel failed to process your request receiving signal %d = %s"
+
+#: zoo_service_loader.c:147 zoo_service_loader.c:280 zoo_service_loader.c:367
+#: zoo_service_loader.c:420 zoo_service_loader.c:547 zoo_service_loader.c:623
+#: zoo_service_loader.c:637 zoo_service_loader.c:664 zoo_service_loader.c:705
+#: zoo_service_loader.c:788 zoo_service_loader.c:806 zoo_service_loader.c:864
+#: zoo_service_loader.c:905 zoo_service_loader.c:952 zoo_service_loader.c:987
+#: zoo_service_loader.c:1005 zoo_service_loader.c:1146
+#: zoo_service_loader.c:1218 zoo_service_loader.c:1238
+#: zoo_service_loader.c:1298 zoo_service_loader.c:1324
+msgid "Unable to allocate memory."
+msgstr "Unable to allocate memory."
+
+#: zoo_service_loader.c:181
+msgid "Parameter <request> was not specified"
+msgstr "Parameter <request> was not specified"
+
+#: zoo_service_loader.c:191 zoo_service_loader.c:402
+msgid ""
+"Unenderstood <request> value. Please check that it was set to "
+"GetCapabilities, DescribeProcess or Execute."
+msgstr ""
+"Unenderstood <request> value. Please check that it was set to "
+"GetCapabilities, DescribeProcess or Execute."
+
+#: zoo_service_loader.c:201
+msgid "Parameter <service> was not specified"
+msgstr "Parameter <service> was not specified"
+
+#: zoo_service_loader.c:210
+msgid "Parameter <version> was not specified"
+msgstr "Parameter <version> was not specified"
+
+#: zoo_service_loader.c:257
+msgid "The specified path doesn't exist."
+msgstr "The specified path doesn't exist."
+
+#: zoo_service_loader.c:311
+msgid "Mandatory <identifier> was not specified"
+msgstr "Mandatory <identifier> was not specified"
+
+#: zoo_service_loader.c:322
+msgid "The specified path path doesn't exist."
+msgstr "The specified path path doesn't exist."
+
+#: zoo_service_loader.c:404
+#, c-format
+msgid "No request found %s"
+msgstr "No request found %s"
+
+#: zoo_service_loader.c:441
+#, c-format
+msgid ""
+"The value for <indetifier> seems to be wrong (%s). Please, ensure that the "
+"process exist using the GetCapabilities request."
+msgstr ""
+"The value for <indetifier> seems to be wrong (%s). Please, ensure that the "
+"process exist using the GetCapabilities request."
+
+#: zoo_service_loader.c:519 zoo_service_loader.c:530
+msgid "Unable to allocate memory"
+msgstr "Unable to allocate memory"
+
+#: zoo_service_loader.c:606
+msgid "Parameter <DataInputs> was not specified"
+msgstr "Parameter <DataInputs> was not specified"
+
+#: service_internal.c:1048
+#, c-format
+msgid "Service \"%s\" run successfully."
+msgstr "Service \"%s\" run successfully."
+
+#: zoo_service_loader.c:1366
+#, c-format
+msgid ""
+"The <%s> argument was not specified in DataInputs but defined as requested "
+"in ZOO ServicesProvider configuration file, please correct your query or the "
+"ZOO Configuration file."
+msgstr ""
+"The <%s> argument was not specified in DataInputs but defined as requested "
+"in ZOO ServicesProvider configuration file, please correct your query or the "
+"ZOO Configuration file."
+
+#: zoo_service_loader.c:1651 zoo_service_loader.c:1871
+#, c-format
+msgid ""
+"Programming Language (%s) set in ZCFG file is not currently supported by ZOO "
+"Kernel.\n"
+msgstr ""
+"Programming Language (%s) set in ZCFG file is not currently supported by ZOO "
+"Kernel.\n"
+
+
+#: zoo_service_loader.c:1700
+msgid "Unable to run the child process properly"
+msgstr "Unable to run the child process properly"
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/fr_FR.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/fr_FR.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/fr_FR.utf8.po	(revision 672)
@@ -0,0 +1,174 @@
+# French translations for ZOO Kernel package.
+# Copyright (C) 2010 THE ZOO Kernel'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ZOO Kernel package.
+# root <gerald.fenoy@geolabs.fr>, 2010.
+#
+#: service_internal.c:1672 zoo_service_loader.c:158 zoo_service_loader.c:160
+#: zoo_service_loader.c:220 zoo_service_loader.c:267 zoo_service_loader.c:341
+#: zoo_service_loader.c:1135 zoo_service_loader.c:1277
+#: zoo_service_loader.c:1364
+msgid ""
+msgstr ""
+"Project-Id-Version: ZOO Kernel 0.0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 00:38+0200\n"
+"PO-Revision-Date: 2010-09-28 00:39+0200\n"
+"Last-Translator: root <gerald.fenoy@geolabs.fr>\n"
+"Language-Team: French\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: service_internal.c:34
+msgid "0123456789abcdef"
+msgstr ""
+
+#: service_internal.c:1056
+#, c-format
+msgid ""
+"ZOO Service \"%s\" is currently running. Please, reload this document to get "
+"the up-to-date status of the Service."
+msgstr ""
+"Le Service ZOO \"%s\" est en cous d'exécution. Merci de recharger document pour"
+" obtenir une version à jour du status du Service."
+
+#: service_internal.c:1062
+#, c-format
+msgid ""
+"Service \"%s\" was accepted by the ZOO Kernel and it run as a background "
+"task. Please consult the statusLocation attribtue providen in this document "
+"to get the up-to-date document."
+msgstr ""
+"Le Service \"%s\" a été accepté par le Noyau ZOO et tourne en tâche de fond. "
+"Merci de consulter le lien fourni dans ce document afin d'obtenir le status actuel du "
+"Service."
+
+#: service_internal.c:1079
+msgid "No more information available"
+msgstr "Pas plus d'information disponible"
+
+#: service_internal.c:1432 service_internal.c:1485
+msgid "No debug message available"
+msgstr "Pas de message de débuguage disponible"
+
+#: service_internal.c:1546
+msgid "Unable to fetch any result"
+msgstr "Impossible de récupérer un résultat"
+
+#: service_internal.c:1587
+#, c-format
+msgid ""
+"Unable to run the Service. The message returned back by the Service was the "
+"following : %s"
+msgstr ""
+"Impossible d'exécuter le Service. Le message retourné par le Service est le suivant : %s"
+
+#: service_internal.c:1589
+#, c-format
+msgid ""
+"Unable to run the Service. No more information was returned back by the "
+"Service."
+msgstr ""
+"Impossible d'exécuter le Service. Pas plus d'information disponible."
+
+#: zoo_service_loader.c:119
+#, c-format
+msgid "ZOO Kernel failed to process your request receiving signal %d = %s"
+msgstr ""
+"Le Noyau ZOO a rencontré un problème lors de l'exécution de votre resquête et a "
+"reçu le signal %d : %s "
+
+#: zoo_service_loader.c:147 zoo_service_loader.c:280 zoo_service_loader.c:367
+#: zoo_service_loader.c:420 zoo_service_loader.c:547 zoo_service_loader.c:623
+#: zoo_service_loader.c:637 zoo_service_loader.c:664 zoo_service_loader.c:705
+#: zoo_service_loader.c:788 zoo_service_loader.c:806 zoo_service_loader.c:864
+#: zoo_service_loader.c:905 zoo_service_loader.c:952 zoo_service_loader.c:987
+#: zoo_service_loader.c:1005 zoo_service_loader.c:1146
+#: zoo_service_loader.c:1218 zoo_service_loader.c:1238
+#: zoo_service_loader.c:1298 zoo_service_loader.c:1324
+msgid "Unable to allocate memory."
+msgstr "Impossible d'allouer de la mémoire."
+
+#: zoo_service_loader.c:181
+msgid "Parameter <request> was not specified"
+msgstr "Le paramètre <request> n'a pas été spécifié"
+
+#: zoo_service_loader.c:191 zoo_service_loader.c:402
+msgid ""
+"Unenderstood <request> value. Please check that it was set to "
+"GetCapabilities, DescribeProcess or Execute."
+msgstr ""
+"La valeur de <request> est incompréhensible. Merci d'utiliser l'une des valeurs "
+"suivantes : GetCapabilities, DescribeProcess ou Execute."
+
+#: zoo_service_loader.c:201
+msgid "Parameter <service> was not specified"
+msgstr "La paramètre <service> n'a pas été spécifié"
+
+#: zoo_service_loader.c:210
+msgid "Parameter <version> was not specified"
+msgstr "Le paramètre <version> n'a pas été spécifié"
+
+#: zoo_service_loader.c:257
+msgid "The specified path doesn't exist."
+msgstr "Le chemin spécifié n'existe pas"
+
+#: zoo_service_loader.c:311
+msgid "Mandatory <identifier> was not specified"
+msgstr "Le paramètre obligatoire <identifier> n'a pas été précisé"
+
+#: zoo_service_loader.c:322
+msgid "The specified path path doesn't exist."
+msgstr "Le chemin fourni n'existe pas."
+
+#: zoo_service_loader.c:404
+#, c-format
+msgid "No request found %s"
+msgstr "Aucune requête trouvée %s"
+
+#: zoo_service_loader.c:441
+#, c-format
+msgid ""
+"The value for <indetifier> seems to be wrong (%s). Please, ensure that the "
+"process exist using the GetCapabilities request."
+msgstr ""
+"La valeur pour le paramètre <identifier> semble éronné (%s). Merci de vous assurer que"
+" le service existe en utilisant une requête GetCapabilities."
+
+#: zoo_service_loader.c:519 zoo_service_loader.c:530
+msgid "Unable to allocate memory"
+msgstr "Impossible d'allouer de la mémoire"
+
+#: zoo_service_loader.c:606
+msgid "Parameter <DataInputs> was not specified"
+msgstr "Paramètre <DataInputs> n'a pas été précisé"
+
+#: service_internal.c:1048
+#, c-format
+msgid "Service \"%s\" run successfully."
+msgstr "Le Service \"%s\" a été exécuté avec succès."
+
+#: zoo_service_loader.c:1366
+#, c-format
+msgid ""
+"The <%s> argument was not specified in DataInputs but defined as requested "
+"in ZOO ServicesProvider configuration file, please correct your query or the "
+"ZOO Configuration file."
+msgstr ""
+"L'argument <%s> n'a pas été précisé dans les données en entrée (DataInputs) mais "
+"est défini comme obligatoire dans le fichier de méta-données du Service ZOO (zcfg). "
+"Merci de corriger votre requête ou le fichier de méta-données."
+
+#: zoo_service_loader.c:1651 zoo_service_loader.c:1871
+#, c-format
+msgid ""
+"Programming Language (%s) set in ZCFG file is not currently supported by ZOO "
+"Kernel.\n"
+msgstr ""
+"Le langage de programmation (%s) utilisé dans le fichier ZCFG n'est actuellement pas "
+"supporté par votre installation du noyau ZOO.\n"
+
+#: zoo_service_loader.c:1700
+msgid "Unable to run the child process properly"
+msgstr "Impossible d'exécuter le processus en tâche de fond"
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/ja_JP.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/ja_JP.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/ja_JP.utf8.po	(revision 672)
@@ -0,0 +1,174 @@
+# Japanese translations for ZOO Kernel package.
+# Copyright (C) 2010 THE ZOO Kernel'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ZOO Kernel package.
+# Daisuke YOSHIDA <yoshida@la.tezuka-gu.ac.jp>, 2010.
+#
+#: service_internal.c:1672 zoo_service_loader.c:158 zoo_service_loader.c:160
+#: zoo_service_loader.c:220 zoo_service_loader.c:267 zoo_service_loader.c:341
+#: zoo_service_loader.c:1135 zoo_service_loader.c:1277
+#: zoo_service_loader.c:1364
+msgid ""
+msgstr ""
+"Project-Id-Version: ZOO Kernel 0.0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 00:38+0200\n"
+"PO-Revision-Date: 2010-09-28 00:39+0200\n"
+"Last-Translator: Daisuke YOSHIDA <yoshida@la.tezuka-gu.ac.jp>\n"
+"Language-Team: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: service_internal.c:34
+msgid "0123456789abcdef"
+msgstr ""
+
+#: service_internal.c:1056
+#, c-format
+msgid ""
+"ZOO Service \"%s\" is currently running. Please, reload this document to get "
+"the up-to-date status of the Service."
+msgstr ""
+"現在，ZOOサービス \"%s\" が動作しています. このサービスのステータスを最新のものにするために，"
+"このドキュメントを再読込してください."
+
+#: service_internal.c:1062
+#, c-format
+msgid ""
+"Service \"%s\" was accepted by the ZOO Kernel and it run as a background "
+"task. Please consult the statusLocation attribtue providen in this document "
+"to get the up-to-date document."
+msgstr ""
+"ZOOカーネルが \"%s\" サービスをアクセプトし，バックグラウンドタスクとして動作しています．"
+"ドキュメントを最新の状態に保つために，ドキュメントで提供されている"
+"statusLocation属性を確認してください．"
+
+#: service_internal.c:1079
+msgid "No more information available"
+msgstr "情報はありません．"
+
+#: service_internal.c:1432 service_internal.c:1485
+msgid "No debug message available"
+msgstr "デバッグメッセージはありません．"
+
+#: service_internal.c:1546
+msgid "Unable to fetch any result"
+msgstr "結果が取得できませんでした．"
+
+#: service_internal.c:1587
+#, c-format
+msgid ""
+"Unable to run the Service. The message returned back by the Service was the "
+"following : %s"
+msgstr ""
+"サービスを開始することができませんでした．このサービスによって返されたメッセージは  %s　です。"
+
+#: service_internal.c:1589
+#, c-format
+msgid ""
+"Unable to run the Service. No more information was returned back by the "
+"Service."
+msgstr ""
+"サービスを開始できませんでした．このサービスによって返された情報はありません ."
+
+#: zoo_service_loader.c:119
+#, c-format
+msgid "ZOO Kernel failed to process your request receiving signal %d = %s"
+msgstr ""
+"ZOOカーネルはリクエストを処理することができませんでした．受け取ったシグナルは"
+"%d : %s です．"
+
+#: zoo_service_loader.c:147 zoo_service_loader.c:280 zoo_service_loader.c:367
+#: zoo_service_loader.c:420 zoo_service_loader.c:547 zoo_service_loader.c:623
+#: zoo_service_loader.c:637 zoo_service_loader.c:664 zoo_service_loader.c:705
+#: zoo_service_loader.c:788 zoo_service_loader.c:806 zoo_service_loader.c:864
+#: zoo_service_loader.c:905 zoo_service_loader.c:952 zoo_service_loader.c:987
+#: zoo_service_loader.c:1005 zoo_service_loader.c:1146
+#: zoo_service_loader.c:1218 zoo_service_loader.c:1238
+#: zoo_service_loader.c:1298 zoo_service_loader.c:1324
+msgid "Unable to allocate memory."
+msgstr "Impossible d'allouer de la mémoire."
+
+#: zoo_service_loader.c:181
+msgid "Parameter <request> was not specified"
+msgstr "パラメーターが指定されていません．"
+
+#: zoo_service_loader.c:191 zoo_service_loader.c:402
+msgid ""
+"Unenderstood <request> value. Please check that it was set to "
+"GetCapabilities, DescribeProcess or Execute."
+msgstr ""
+"<request>値を認識しました. 値が下記のリクエストを指定されているか確認してください．"
+"GetCapabilities, DescribeProcess, Execute."
+
+#: zoo_service_loader.c:201
+msgid "Parameter <service> was not specified"
+msgstr "<service> パラメーターが指定されていません．"
+
+#: zoo_service_loader.c:210
+msgid "Parameter <version> was not specified"
+msgstr "<version>パラメーターが指定されていません．"
+
+#: zoo_service_loader.c:257
+msgid "The specified path doesn't exist."
+msgstr "指定されたパスが存在しません．"
+
+#: zoo_service_loader.c:311
+msgid "Mandatory <identifier> was not specified"
+msgstr "<identifier>値（要指定）が指定されていません．"
+
+#: zoo_service_loader.c:322
+msgid "The specified path path doesn't exist."
+msgstr "指定されたパスが存在しません．"
+
+#: zoo_service_loader.c:404
+#, c-format
+msgid "No request found %s"
+msgstr "%sのリクエストが見つかりません．"
+
+#: zoo_service_loader.c:441
+#, c-format
+msgid ""
+"The value for <indetifier> seems to be wrong (%s). Please, ensure that the "
+"process exist using the GetCapabilities request."
+msgstr ""
+"<identifier>についての値が不正です(%s). GetCapabilitiesにより"
+"そのプロセスが存在しているか確認してください."
+
+#: zoo_service_loader.c:519 zoo_service_loader.c:530
+msgid "Unable to allocate memory"
+msgstr "メモリを割り当てられません．"
+
+#: zoo_service_loader.c:606
+msgid "Parameter <DataInputs> was not specified"
+msgstr "<DataInputs> パラメーターが指定されていません．"
+
+#: service_internal.c:1048
+#, c-format
+msgid "Service \"%s\" run successfully."
+msgstr " \"%s\"サービスが動作しました."
+
+#: zoo_service_loader.c:1366
+#, c-format
+msgid ""
+"The <%s> argument was not specified in DataInputs but defined as requested "
+"in ZOO ServicesProvider configuration file, please correct your query or the "
+"ZOO Configuration file."
+msgstr ""
+"DataInputsの中の引数 <%s>が指定されていませんでしたが，"
+"ZOO ServicesProviderの設定ファイル(zcfg)の中で定義されています．"
+"クエリー，もしくはZOO設定ファイルを修正してください．"
+
+#: zoo_service_loader.c:1651 zoo_service_loader.c:1871
+#, c-format
+msgid ""
+"Programming Language (%s) set in ZCFG file is not currently supported by ZOO "
+"Kernel.\n"
+msgstr ""
+"ZCFGファイルの中で設定されているプログラム言語 (%s) は "
+"現在のZOOカーネルではサポートしていません.\n"
+
+#: zoo_service_loader.c:1700
+msgid "Unable to run the child process properly"
+msgstr "子プロセスを開始することができません．"
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/messages.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/messages.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/locale/po/messages.po	(revision 672)
@@ -0,0 +1,1725 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#: service_internal.c:1672 zoo_service_loader.c:158 zoo_service_loader.c:160
+#: zoo_service_loader.c:220 zoo_service_loader.c:267 zoo_service_loader.c:341
+#: zoo_service_loader.c:1135 zoo_service_loader.c:1277
+#: zoo_service_loader.c:1364
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 00:38+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: service_internal.c:34
+msgid "0123456789abcdef"
+msgstr ""
+
+#: service_internal.c:44 service_internal.c:88 service_internal.c:90
+#: service_internal.c:92 service_internal.c:108 service_internal.c:122
+#: service_internal.c:986 service_internal.c:1054 service_internal.c:1070
+#: service_internal.c:1075 service_internal.c:1398 service_internal.c:1585
+#: zoo_service_loader.c:1443
+msgid "lenv"
+msgstr ""
+
+#: service_internal.c:44 service_internal.c:108 service_internal.c:986
+#: service_internal.c:1398 zoo_service_loader.c:1446
+msgid "sid"
+msgstr ""
+
+#: service_internal.c:49 service_internal.c:113
+#, c-format
+msgid "shmget failed to update value\n"
+msgstr ""
+
+#: service_internal.c:54 service_internal.c:118
+#, c-format
+msgid "shmat failed to update value\n"
+msgstr ""
+
+#: service_internal.c:77
+#, c-format
+msgid "Number of arguments used to call the function : %i"
+msgstr ""
+
+#: service_internal.c:84 service_internal.c:988 zoo_service_loader.c:1445
+#, c-format
+msgid "%i"
+msgstr ""
+
+#: service_internal.c:88 service_internal.c:90 service_internal.c:92
+#: service_internal.c:122 service_internal.c:1054 service_internal.c:1285
+#: service_internal.c:1327 zoo_service_loader.c:1158 zoo_service_loader.c:1448
+msgid "status"
+msgstr ""
+
+#: service_internal.c:92
+msgid "15"
+msgstr ""
+
+#: service_internal.c:140
+#, c-format
+msgid "shmget failed in getStatus\n"
+msgstr ""
+
+#: service_internal.c:145
+#, c-format
+msgid "shmat failed in getStatus\n"
+msgstr ""
+
+#: service_internal.c:151
+msgid "-1"
+msgstr ""
+
+#: service_internal.c:223
+#, c-format
+msgid "zooXmlAddNs %d \n"
+msgstr ""
+
+#: service_internal.c:246 service_internal.c:250
+#, c-format
+msgid "zooXmlCleanup %d\n"
+msgstr ""
+
+#: service_internal.c:269 service_internal.c:276 service_internal.c:546
+#: service_internal.c:584 service_internal.c:940 service_internal.c:950
+msgid "http://www.opengis.net/wps/1.0.0"
+msgstr ""
+
+#: service_internal.c:269 service_internal.c:276 service_internal.c:546
+#: service_internal.c:579 service_internal.c:584 service_internal.c:606
+#: service_internal.c:940 service_internal.c:950
+msgid "wps"
+msgstr ""
+
+#: service_internal.c:271 service_internal.c:494 service_internal.c:961
+#: service_internal.c:1395 service_internal.c:1454 service_internal.c:1513
+#: service_internal.c:1517 service_internal.c:1518 zoo_service_loader.c:225
+#: zoo_service_loader.c:1683
+msgid "main"
+msgstr ""
+
+#: service_internal.c:273
+msgid "Capabilities"
+msgstr ""
+
+#: service_internal.c:274 service_internal.c:548 service_internal.c:582
+#: service_internal.c:608 service_internal.c:944 service_internal.c:1408
+#: service_internal.c:1410 service_internal.c:1456 service_internal.c:1460
+msgid "http://www.opengis.net/ows/1.1"
+msgstr ""
+
+#: service_internal.c:274 service_internal.c:548 service_internal.c:582
+#: service_internal.c:608 service_internal.c:944 service_internal.c:1408
+#: service_internal.c:1410 service_internal.c:1456 service_internal.c:1460
+msgid "ows"
+msgstr ""
+
+#: service_internal.c:277 service_internal.c:586 service_internal.c:948
+#: service_internal.c:1412 service_internal.c:1461
+msgid "http://www.w3.org/2001/XMLSchema-instance"
+msgstr ""
+
+#: service_internal.c:277 service_internal.c:586 service_internal.c:948
+#: service_internal.c:1412 service_internal.c:1461
+msgid "xsi"
+msgstr ""
+
+#: service_internal.c:279 service_internal.c:550 service_internal.c:585
+#: service_internal.c:610 service_internal.c:946 service_internal.c:1411
+#: service_internal.c:1463
+msgid "http://www.w3.org/1999/xlink"
+msgstr ""
+
+#: service_internal.c:279 service_internal.c:550 service_internal.c:585
+#: service_internal.c:610 service_internal.c:946 service_internal.c:1411
+#: service_internal.c:1463
+msgid "xlink"
+msgstr ""
+
+#: service_internal.c:281 service_internal.c:589 service_internal.c:952
+#: service_internal.c:1465
+msgid "schemaLocation"
+msgstr ""
+
+#: service_internal.c:281
+msgid ""
+"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/"
+"wpsGetCapabilities_response.xsd"
+msgstr ""
+
+#: service_internal.c:282 service_internal.c:590 service_internal.c:954
+msgid "service"
+msgstr ""
+
+#: service_internal.c:282 service_internal.c:340 service_internal.c:590
+#: service_internal.c:954
+msgid "WPS"
+msgstr ""
+
+#: service_internal.c:285 service_internal.c:287 service_internal.c:290
+#: service_internal.c:293 service_internal.c:306 service_internal.c:591
+#: service_internal.c:955 service_internal.c:1375 service_internal.c:1415
+#: service_internal.c:1468
+msgid "version"
+msgstr ""
+
+#: service_internal.c:290 service_internal.c:293 service_internal.c:343
+#: service_internal.c:591 service_internal.c:955 service_internal.c:1380
+#: service_internal.c:1383
+msgid "1.0.0"
+msgstr ""
+
+#: service_internal.c:297
+msgid "ServiceIdentification"
+msgstr ""
+
+#: service_internal.c:298
+msgid "identification"
+msgstr ""
+
+#: service_internal.c:302 service_internal.c:313 service_internal.c:364
+#: service_internal.c:407
+msgid "keywords"
+msgstr ""
+
+#: service_internal.c:303 service_internal.c:365 service_internal.c:455
+#: service_internal.c:963 service_internal.c:1518 zoo_service_loader.c:225
+msgid "serverAddress"
+msgstr ""
+
+#: service_internal.c:304 service_internal.c:366 service_internal.c:496
+msgid "lang"
+msgstr ""
+
+#: service_internal.c:305 service_internal.c:1293 service_internal.c:1362
+#: service_internal.c:1559 zoo_service_loader.c:840 zoo_service_loader.c:1073
+#: zoo_service_loader.c:1186 zoo_service_loader.c:1286
+msgid "encoding"
+msgstr ""
+
+#: service_internal.c:314 service_internal.c:408
+msgid "Keywords"
+msgstr ""
+
+#: service_internal.c:326 service_internal.c:334 service_internal.c:420
+#: service_internal.c:428
+msgid "Keyword"
+msgstr ""
+
+#: service_internal.c:339
+msgid "ServiceType"
+msgstr ""
+
+#: service_internal.c:342
+msgid "ServiceTypeVersion"
+msgstr ""
+
+#: service_internal.c:350 service_internal.c:438
+#, c-format
+msgid "TMP4 NOT FOUND !!"
+msgstr ""
+
+#: service_internal.c:355 zoo_service_loader.c:261 zoo_service_loader.c:335
+#: zoo_service_loader.c:1477 zoo_service_loader.c:1684
+#: zoo_service_loader.c:1728
+msgid "ServiceProvider"
+msgstr ""
+
+#: service_internal.c:356
+msgid "ServiceContact"
+msgstr ""
+
+#: service_internal.c:357
+msgid "ContactInfo"
+msgstr ""
+
+#: service_internal.c:358 service_internal.c:387 service_internal.c:390
+msgid "Phone"
+msgstr ""
+
+#: service_internal.c:359 service_internal.c:396 service_internal.c:399
+msgid "Address"
+msgstr ""
+
+#: service_internal.c:360
+msgid "provider"
+msgstr ""
+
+#: service_internal.c:368
+msgid "ProviderName"
+msgstr ""
+
+#: service_internal.c:374
+msgid "ProviderSite"
+msgstr ""
+
+#: service_internal.c:376 service_internal.c:472 service_internal.c:476
+#: service_internal.c:1320 zoo_service_loader.c:843 zoo_service_loader.c:942
+#: zoo_service_loader.c:968 zoo_service_loader.c:994
+msgid "href"
+msgstr ""
+
+#: service_internal.c:380
+msgid "IndividualName"
+msgstr ""
+
+#: service_internal.c:381
+msgid "PositionName"
+msgstr ""
+
+#: service_internal.c:447
+msgid "OperationsMetadata"
+msgstr ""
+
+#: service_internal.c:449 zoo_service_loader.c:188 zoo_service_loader.c:207
+#: zoo_service_loader.c:249
+msgid "GetCapabilities"
+msgstr ""
+
+#: service_internal.c:450 zoo_service_loader.c:189 zoo_service_loader.c:329
+msgid "DescribeProcess"
+msgstr ""
+
+#: service_internal.c:451 zoo_service_loader.c:190 zoo_service_loader.c:401
+msgid "Execute"
+msgstr ""
+
+#: service_internal.c:460 service_internal.c:463
+msgid "not_found"
+msgstr ""
+
+#: service_internal.c:466
+msgid "Operation"
+msgstr ""
+
+#: service_internal.c:467
+msgid "name"
+msgstr ""
+
+#: service_internal.c:468
+msgid "DCP"
+msgstr ""
+
+#: service_internal.c:469
+msgid "HTTP"
+msgstr ""
+
+#: service_internal.c:470
+msgid "Get"
+msgstr ""
+
+#: service_internal.c:471 zoo_service_loader.c:245 zoo_service_loader.c:277
+#: zoo_service_loader.c:363 zoo_service_loader.c:424 zoo_service_loader.c:1473
+#: zoo_service_loader.c:1478 zoo_service_loader.c:1727
+#: zoo_service_loader.c:1730
+#, c-format
+msgid "%s/%s"
+msgstr ""
+
+#: service_internal.c:475
+msgid "Post"
+msgstr ""
+
+#: service_internal.c:487
+msgid "ProcessOfferings"
+msgstr ""
+
+#: service_internal.c:490
+msgid "Languages"
+msgstr ""
+
+#: service_internal.c:491 service_internal.c:674 service_internal.c:679
+#: service_internal.c:830 service_internal.c:833
+msgid "Default"
+msgstr ""
+
+#: service_internal.c:492 service_internal.c:757 service_internal.c:761
+#: service_internal.c:876 service_internal.c:880
+msgid "Supported"
+msgstr ""
+
+#: service_internal.c:509 service_internal.c:517 service_internal.c:526
+msgid "Language"
+msgstr ""
+
+#: service_internal.c:514 service_internal.c:592 service_internal.c:956
+#: service_internal.c:1414 service_internal.c:1467
+msgid "xml:lang"
+msgstr ""
+
+#: service_internal.c:556 service_internal.c:1017
+msgid "Process"
+msgstr ""
+
+#: service_internal.c:557 service_internal.c:559 service_internal.c:615
+#: service_internal.c:624 service_internal.c:1018 service_internal.c:1021
+msgid "processVersion"
+msgstr ""
+
+#: service_internal.c:563 service_internal.c:638
+msgid "Metadata"
+msgstr ""
+
+#: service_internal.c:579 service_internal.c:606
+msgid "http://schemas.opengis.net/wps/1.0.0"
+msgstr ""
+
+#: service_internal.c:581
+msgid "ProcessDescriptions"
+msgstr ""
+
+#: service_internal.c:589
+msgid ""
+"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/"
+"wpsDescribeProcess_response.xsd"
+msgstr ""
+
+#: service_internal.c:592 service_internal.c:956 service_internal.c:1414
+#: service_internal.c:1467
+msgid "en"
+msgstr ""
+
+#: service_internal.c:613
+msgid "ProcessDescription"
+msgstr ""
+
+#: service_internal.c:616
+msgid "storeSupported"
+msgstr ""
+
+#: service_internal.c:617
+msgid "statusSupported"
+msgstr ""
+
+#: service_internal.c:630 service_internal.c:991 service_internal.c:1199
+#: service_internal.c:1227 zoo_service_loader.c:1458
+msgid "false"
+msgstr ""
+
+#: service_internal.c:644 service_internal.c:646
+msgid "Profile"
+msgstr ""
+
+#: service_internal.c:651 service_internal.c:1098 zoo_service_loader.c:597
+msgid "DataInputs"
+msgstr ""
+
+#: service_internal.c:655 service_internal.c:1103
+msgid "Input"
+msgstr ""
+
+#: service_internal.c:656 service_internal.c:805 service_internal.c:1626
+msgid "minOccurs"
+msgstr ""
+
+#: service_internal.c:660 service_internal.c:809
+msgid "maxOccurs"
+msgstr ""
+
+#: service_internal.c:673 service_internal.c:789 service_internal.c:827
+#: service_internal.c:1274 zoo_service_loader.c:1041
+msgid "LiteralData"
+msgstr ""
+
+#: service_internal.c:675 service_internal.c:758 service_internal.c:834
+#: service_internal.c:877
+msgid "Format"
+msgstr ""
+
+#: service_internal.c:678 service_internal.c:829
+msgid "UOMs"
+msgstr ""
+
+#: service_internal.c:687 service_internal.c:839
+#, c-format
+msgid "DATATYPE DEFAULT ? %s\n"
+msgstr ""
+
+#: service_internal.c:689 service_internal.c:690 service_internal.c:700
+#: service_internal.c:841 service_internal.c:842 service_internal.c:853
+#: service_internal.c:887
+msgid "DataType"
+msgstr ""
+
+#: service_internal.c:693 service_internal.c:845
+#, c-format
+msgid "http://www.w3.org/TR/xmlschema-2/#%s"
+msgstr ""
+
+#: service_internal.c:694 service_internal.c:846 service_internal.c:1324
+msgid "reference"
+msgstr ""
+
+#: service_internal.c:699 service_internal.c:852 service_internal.c:886
+#: service_internal.c:1197 service_internal.c:1199 service_internal.c:1225
+#: service_internal.c:1227 service_internal.c:1284 service_internal.c:1329
+#: service_internal.c:1510 zoo_service_loader.c:1189
+msgid "asReference"
+msgstr ""
+
+#: service_internal.c:701 service_internal.c:723 service_internal.c:724
+msgid "AllowedValues"
+msgstr ""
+
+#: service_internal.c:702 service_internal.c:718 service_internal.c:1282
+#: service_internal.c:1295 service_internal.c:1323 service_internal.c:1522
+#: service_internal.c:1544 service_internal.c:1640 service_internal.c:1642
+#: zoo_service_loader.c:667 zoo_service_loader.c:709 zoo_service_loader.c:870
+#: zoo_service_loader.c:890 zoo_service_loader.c:960 zoo_service_loader.c:1013
+#: zoo_service_loader.c:1093
+msgid "value"
+msgstr ""
+
+#: service_internal.c:703 service_internal.c:854 service_internal.c:888
+#: service_internal.c:1283 service_internal.c:1287 service_internal.c:1325
+#: service_internal.c:1512
+msgid "extension"
+msgstr ""
+
+#: service_internal.c:719
+msgid "DefaultValue"
+msgstr ""
+
+#: service_internal.c:726 service_internal.c:734 zoo_service_loader.c:344
+#: zoo_service_loader.c:382
+msgid ","
+msgstr ""
+
+#: service_internal.c:728
+msgid "Value"
+msgstr ""
+
+#: service_internal.c:732
+#, c-format
+msgid "strgin : %s\n"
+msgstr ""
+
+#: service_internal.c:745
+msgid "AnyValue"
+msgstr ""
+
+#: service_internal.c:800 service_internal.c:1131
+msgid "ProcessOutputs"
+msgstr ""
+
+#: service_internal.c:804 service_internal.c:1117 service_internal.c:1135
+#: zoo_service_loader.c:1179
+msgid "Output"
+msgstr ""
+
+#: service_internal.c:816
+msgid "LITERALDATA"
+msgstr ""
+
+#: service_internal.c:817 service_internal.c:826
+msgid "LiteralOutput"
+msgstr ""
+
+#: service_internal.c:819
+msgid "COMPLEXDATA"
+msgstr ""
+
+#: service_internal.c:820
+msgid "ComplexOutput"
+msgstr ""
+
+#: service_internal.c:884
+#, c-format
+msgid "DATATYPE SUPPORTED ? %s\n"
+msgstr ""
+
+#: service_internal.c:939 service_internal.c:1394 zoo_service_loader.c:259
+#: zoo_service_loader.c:333 zoo_service_loader.c:928
+msgid "1.0"
+msgstr ""
+
+#: service_internal.c:943
+msgid "ExecuteResponse"
+msgstr ""
+
+#: service_internal.c:952
+msgid ""
+"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/"
+"wpsExecute_response.xsd"
+msgstr ""
+
+#: service_internal.c:980
+#, c-format
+msgid "%s/GetStatus.zcfg"
+msgstr ""
+
+#: service_internal.c:984
+msgid "rewriteUrl"
+msgstr ""
+
+#: service_internal.c:990 service_internal.c:1439 service_internal.c:1571
+#: service_internal.c:1577 zoo_service_loader.c:247 zoo_service_loader.c:503
+#: zoo_service_loader.c:532 zoo_service_loader.c:604 zoo_service_loader.c:635
+#: zoo_service_loader.c:901 zoo_service_loader.c:938
+#, c-format
+msgid "%s"
+msgstr ""
+
+#: service_internal.c:992 service_internal.c:1000
+#, c-format
+msgid ""
+"%s/?request=Execute&amp;service=WPS&amp;version=1.0.0&amp;"
+"Identifier=GetStatus&amp;DataInputs=sid=%s&amp;RawDataOutput=Result"
+msgstr ""
+
+#: service_internal.c:995 service_internal.c:1511
+msgid "true"
+msgstr ""
+
+#: service_internal.c:996
+#, c-format
+msgid "%s/%s/GetStatus/%s"
+msgstr ""
+
+#: service_internal.c:998
+#, c-format
+msgid "%s/GetStatus/%s"
+msgstr ""
+
+#: service_internal.c:1003 service_internal.c:1517
+msgid "tmpUrl"
+msgstr ""
+
+#: service_internal.c:1005
+#, c-format
+msgid "%s/%s/%s_%i.xml"
+msgstr ""
+
+#: service_internal.c:1009 zoo_service_loader.c:426 zoo_service_loader.c:1475
+#: zoo_service_loader.c:1732
+#, c-format
+msgid "%s/"
+msgstr ""
+
+#: service_internal.c:1012
+msgid "serviceInstance"
+msgstr ""
+
+#: service_internal.c:1014
+msgid "statusLocation"
+msgstr ""
+
+#: service_internal.c:1028
+msgid "Status"
+msgstr ""
+
+#: service_internal.c:1040
+msgid "%Y-%m-%dT%I:%M:%SZ"
+msgstr ""
+
+#: service_internal.c:1042
+msgid "creationTime"
+msgstr ""
+
+#: service_internal.c:1047
+msgid "ProcessSucceeded"
+msgstr ""
+
+#: service_internal.c:1048
+#, c-format
+msgid "Service \"%s\" run successfully."
+msgstr ""
+
+#: service_internal.c:1053
+msgid "ProcessStarted"
+msgstr ""
+
+#: service_internal.c:1055
+msgid "percentCompleted"
+msgstr ""
+
+#: service_internal.c:1056
+#, c-format
+msgid ""
+"ZOO Service \"%s\" is currently running. Please, reload this document to get "
+"the up-to-date status of the Service."
+msgstr ""
+
+#: service_internal.c:1061
+msgid "ProcessAccepted"
+msgstr ""
+
+#: service_internal.c:1062
+#, c-format
+msgid ""
+"Service \"%s\" was accepted by the ZOO Kernel and it run as a background "
+"task. Please consult the statusLocation attribtue providen in this document "
+"to get the up-to-date document."
+msgstr ""
+
+#: service_internal.c:1067
+msgid "ProcessFailed"
+msgstr ""
+
+#: service_internal.c:1070 service_internal.c:1072 service_internal.c:1074
+#: service_internal.c:1419 service_internal.c:1472 service_internal.c:1547
+#: service_internal.c:1591 zoo_service_loader.c:1368
+msgid "code"
+msgstr ""
+
+#: service_internal.c:1074 service_internal.c:1423 service_internal.c:1476
+msgid "NoApplicableCode"
+msgstr ""
+
+#: service_internal.c:1075 service_internal.c:1585
+msgid "message"
+msgstr ""
+
+#: service_internal.c:1077 service_internal.c:1079 service_internal.c:1425
+#: service_internal.c:1478 service_internal.c:1546 service_internal.c:1590
+#: zoo_service_loader.c:1367 zoo_service_loader.c:1608
+#: zoo_service_loader.c:1652 zoo_service_loader.c:1830
+#: zoo_service_loader.c:1872
+msgid "text"
+msgstr ""
+
+#: service_internal.c:1079
+msgid "No more information available"
+msgstr ""
+
+#: service_internal.c:1084
+#, c-format
+msgid "error code not know : %i\n"
+msgstr ""
+
+#: service_internal.c:1093
+#, c-format
+msgid "printProcessResponse 1 161\n"
+msgstr ""
+
+#: service_internal.c:1096 zoo_service_loader.c:1157
+msgid "lineage"
+msgstr ""
+
+#: service_internal.c:1110
+#, c-format
+msgid "printProcessResponse 1 177\n"
+msgstr ""
+
+#: service_internal.c:1113
+msgid "OutputDefinitions"
+msgstr ""
+
+#: service_internal.c:1124
+#, c-format
+msgid "printProcessResponse 1 190\n"
+msgstr ""
+
+#: service_internal.c:1142
+#, c-format
+msgid "printProcessResponse 1 202\n"
+msgstr ""
+
+#: service_internal.c:1156 service_internal.c:1401 service_internal.c:1404
+#: service_internal.c:1406
+#, c-format
+msgid ""
+"Content-Type: text/xml; charset=%s\r\n"
+"Status: 200 OK\r\n"
+"\r\n"
+msgstr ""
+
+#: service_internal.c:1190
+msgid "MIMETYPE"
+msgstr ""
+
+#: service_internal.c:1191
+msgid "ENCODING"
+msgstr ""
+
+#: service_internal.c:1192
+msgid "SCHEMA"
+msgstr ""
+
+#: service_internal.c:1193
+msgid "UOM"
+msgstr ""
+
+#: service_internal.c:1245 service_internal.c:1342 zoo_service_loader.c:308
+#: zoo_service_loader.c:343 zoo_service_loader.c:427 zoo_service_loader.c:783
+#: zoo_service_loader.c:1212 zoo_service_loader.c:1318
+#: zoo_service_loader.c:1515 zoo_service_loader.c:1562
+#: zoo_service_loader.c:1757 zoo_service_loader.c:1801
+msgid "Identifier"
+msgstr ""
+
+#: service_internal.c:1268
+#, c-format
+msgid "FORMAT %s %s\n"
+msgstr ""
+
+#: service_internal.c:1270 service_internal.c:1319 service_internal.c:1521
+#: zoo_service_loader.c:828
+msgid "Reference"
+msgstr ""
+
+#: service_internal.c:1272 zoo_service_loader.c:1031
+msgid "Data"
+msgstr ""
+
+#: service_internal.c:1273
+msgid "LITERALOUTPUT"
+msgstr ""
+
+#: service_internal.c:1276
+msgid "COMPLEXOUTPUT"
+msgstr ""
+
+#: service_internal.c:1277 zoo_service_loader.c:1066
+msgid "ComplexData"
+msgstr ""
+
+#: service_internal.c:1286 service_internal.c:1328 zoo_service_loader.c:1156
+#: zoo_service_loader.c:1438
+msgid "storeExecuteResponse"
+msgstr ""
+
+#: service_internal.c:1292 service_internal.c:1294 service_internal.c:1553
+#: zoo_service_loader.c:839 zoo_service_loader.c:1072
+#: zoo_service_loader.c:1185 zoo_service_loader.c:1285
+msgid "mimeType"
+msgstr ""
+
+#: service_internal.c:1296
+msgid "base64"
+msgstr ""
+
+#: service_internal.c:1297
+msgid "image/"
+msgstr ""
+
+#: service_internal.c:1298
+msgid "application/"
+msgstr ""
+
+#: service_internal.c:1299 service_internal.c:1573
+msgid "size"
+msgstr ""
+
+#: service_internal.c:1302
+#, c-format
+msgid "%d"
+msgstr ""
+
+#: service_internal.c:1303
+msgid "z"
+msgstr ""
+
+#: service_internal.c:1308
+msgid "text/js"
+msgstr ""
+
+#: service_internal.c:1309
+msgid "application/js"
+msgstr ""
+
+#: service_internal.c:1326
+msgid "abstract"
+msgstr ""
+
+#: service_internal.c:1347 zoo_service_loader.c:799 zoo_service_loader.c:1231
+msgid "Title"
+msgstr ""
+
+#: service_internal.c:1348 zoo_service_loader.c:800 zoo_service_loader.c:1232
+msgid "Abstract"
+msgstr ""
+
+#: service_internal.c:1367 service_internal.c:1370 zoo_service_loader.c:929
+msgid "UTF-8"
+msgstr ""
+
+#: service_internal.c:1409 service_internal.c:1457
+msgid "ExceptionReport"
+msgstr ""
+
+#: service_internal.c:1413
+msgid "xsi:schemaLocation"
+msgstr ""
+
+#: service_internal.c:1413 service_internal.c:1465
+msgid ""
+"http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/"
+"owsExceptionReport.xsd"
+msgstr ""
+
+#: service_internal.c:1415 service_internal.c:1468
+msgid "1.1.0"
+msgstr ""
+
+#: service_internal.c:1417 service_internal.c:1470
+msgid "Exception"
+msgstr ""
+
+#: service_internal.c:1421 service_internal.c:1423 service_internal.c:1474
+#: service_internal.c:1476
+msgid "exceptionCode"
+msgstr ""
+
+#: service_internal.c:1426 service_internal.c:1479
+msgid "ExceptionText"
+msgstr ""
+
+#: service_internal.c:1432 service_internal.c:1485
+msgid "No debug message available"
+msgstr ""
+
+#: service_internal.c:1498
+#, c-format
+msgid "printProcessResponse\n"
+msgstr ""
+
+#: service_internal.c:1500 zoo_service_loader.c:491 zoo_service_loader.c:1277
+msgid "RawDataOutput"
+msgstr ""
+
+#: service_internal.c:1507
+#, c-format
+msgid "REQUEST_OUTPUTS FINAL\n"
+msgstr ""
+
+#: service_internal.c:1513 zoo_service_loader.c:1683
+msgid "tmpPath"
+msgstr ""
+
+#: service_internal.c:1515
+#, c-format
+msgid "%s/%s_%i.%s"
+msgstr ""
+
+#: service_internal.c:1516
+msgid "w"
+msgstr ""
+
+#: service_internal.c:1520
+#, c-format
+msgid "%s/%s/%s_%i.%s"
+msgstr ""
+
+#: service_internal.c:1529
+msgid "serviceProvider"
+msgstr ""
+
+#: service_internal.c:1531
+#, c-format
+msgid "SERVICE : %s\n"
+msgstr ""
+
+#: service_internal.c:1546
+msgid "Unable to fetch any result"
+msgstr ""
+
+#: service_internal.c:1547 service_internal.c:1591 zoo_service_loader.c:120
+#: zoo_service_loader.c:147 zoo_service_loader.c:280 zoo_service_loader.c:367
+#: zoo_service_loader.c:420 zoo_service_loader.c:519 zoo_service_loader.c:530
+#: zoo_service_loader.c:547 zoo_service_loader.c:623 zoo_service_loader.c:637
+#: zoo_service_loader.c:664 zoo_service_loader.c:705 zoo_service_loader.c:788
+#: zoo_service_loader.c:806 zoo_service_loader.c:864 zoo_service_loader.c:905
+#: zoo_service_loader.c:952 zoo_service_loader.c:987 zoo_service_loader.c:1005
+#: zoo_service_loader.c:1146 zoo_service_loader.c:1218
+#: zoo_service_loader.c:1238 zoo_service_loader.c:1298
+#: zoo_service_loader.c:1324 zoo_service_loader.c:1700
+msgid "InternalError"
+msgstr ""
+
+#: service_internal.c:1555 service_internal.c:1557
+#, c-format
+msgid "SERVICE OUTPUTS\n"
+msgstr ""
+
+#: service_internal.c:1562
+#, c-format
+msgid ""
+"Content-Type: %s; charset=%s\r\n"
+"Status: 200 OK\r\n"
+"\r\n"
+msgstr ""
+
+#: service_internal.c:1567
+#, c-format
+msgid ""
+"Content-Type: %s; charset=UTF-8\r\n"
+"Status: 200 OK\r\n"
+"\r\n"
+msgstr ""
+
+#: service_internal.c:1570
+#, c-format
+msgid ""
+"Content-Type: text/plain; charset=utf-8\r\n"
+"Status: 200 OK\r\n"
+"\r\n"
+msgstr ""
+
+#: service_internal.c:1572
+msgid "image"
+msgstr ""
+
+#: service_internal.c:1587
+#, c-format
+msgid ""
+"Unable to run the Service. The message returned back by the Service was the "
+"following : %s"
+msgstr ""
+
+#: service_internal.c:1589
+#, c-format
+msgid ""
+"Unable to run the Service. No more information was returned back by the "
+"Service."
+msgstr ""
+
+#: service_internal.c:1616
+#, c-format
+msgid "BASE64 [%s] \n"
+msgstr ""
+
+#: service_internal.c:1627 zoo_service_loader.c:1363
+msgid "inputs"
+msgstr ""
+
+#: service_internal.c:1642
+msgid "NULL"
+msgstr ""
+
+#: service_internal.c:1660
+#, c-format
+msgid "addDefaultValues %s => %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:27 zoo_service_loader.c:28 zoo_service_loader.c:31
+#: zoo_service_loader.c:1470 zoo_service_loader.c:1723
+msgid "C"
+msgstr ""
+
+#: zoo_service_loader.c:98
+msgid "SIGSEGV"
+msgstr ""
+
+#: zoo_service_loader.c:101
+msgid "SIGTERM"
+msgstr ""
+
+#: zoo_service_loader.c:104
+msgid "SIGINT"
+msgstr ""
+
+#: zoo_service_loader.c:107
+msgid "SIGILL"
+msgstr ""
+
+#: zoo_service_loader.c:110
+msgid "SIGFPE"
+msgstr ""
+
+#: zoo_service_loader.c:113
+msgid "SIGABRT"
+msgstr ""
+
+#: zoo_service_loader.c:116
+msgid "UNKNOWN"
+msgstr ""
+
+#: zoo_service_loader.c:119
+#, c-format
+msgid "ZOO Kernel failed to process your request receiving signal %d = %s"
+msgstr ""
+
+#: zoo_service_loader.c:122
+#, c-format
+msgid "Not this time!\n"
+msgstr ""
+
+#: zoo_service_loader.c:147 zoo_service_loader.c:280 zoo_service_loader.c:367
+#: zoo_service_loader.c:420 zoo_service_loader.c:547 zoo_service_loader.c:623
+#: zoo_service_loader.c:637 zoo_service_loader.c:664 zoo_service_loader.c:705
+#: zoo_service_loader.c:788 zoo_service_loader.c:806 zoo_service_loader.c:864
+#: zoo_service_loader.c:905 zoo_service_loader.c:952 zoo_service_loader.c:987
+#: zoo_service_loader.c:1005 zoo_service_loader.c:1146
+#: zoo_service_loader.c:1218 zoo_service_loader.c:1238
+#: zoo_service_loader.c:1298 zoo_service_loader.c:1324
+msgid "Unable to allocate memory."
+msgstr ""
+
+#: zoo_service_loader.c:155 zoo_service_loader.c:158 zoo_service_loader.c:160
+#: zoo_service_loader.c:165 zoo_service_loader.c:243 zoo_service_loader.c:1471
+#: zoo_service_loader.c:1725
+msgid "metapath"
+msgstr ""
+
+#: zoo_service_loader.c:162
+#, c-format
+msgid "ADD METAPATH\n"
+msgstr ""
+
+#: zoo_service_loader.c:168
+#, c-format
+msgid "%s/%s/main.cfg"
+msgstr ""
+
+#: zoo_service_loader.c:171
+#, c-format
+msgid "***** BEGIN MAPS\n"
+msgstr ""
+
+#: zoo_service_loader.c:173
+#, c-format
+msgid "***** END MAPS\n"
+msgstr ""
+
+#: zoo_service_loader.c:179
+msgid "Request"
+msgstr ""
+
+#: zoo_service_loader.c:181
+msgid "Parameter <request> was not specified"
+msgstr ""
+
+#: zoo_service_loader.c:181 zoo_service_loader.c:201 zoo_service_loader.c:210
+#: zoo_service_loader.c:311 zoo_service_loader.c:606 zoo_service_loader.c:1368
+msgid "MissingParameterValue"
+msgstr ""
+
+#: zoo_service_loader.c:191 zoo_service_loader.c:402
+msgid ""
+"Unenderstood <request> value. Please check that it was set to "
+"GetCapabilities, DescribeProcess or Execute."
+msgstr ""
+
+#: zoo_service_loader.c:191 zoo_service_loader.c:257 zoo_service_loader.c:322
+#: zoo_service_loader.c:402 zoo_service_loader.c:442
+msgid "InvalidParameterValue"
+msgstr ""
+
+#: zoo_service_loader.c:199
+msgid "Service"
+msgstr ""
+
+#: zoo_service_loader.c:201
+msgid "Parameter <service> was not specified"
+msgstr ""
+
+#: zoo_service_loader.c:208
+msgid "Version"
+msgstr ""
+
+#: zoo_service_loader.c:210
+msgid "Parameter <version> was not specified"
+msgstr ""
+
+#: zoo_service_loader.c:218 zoo_service_loader.c:220
+msgid "serviceprovider"
+msgstr ""
+
+#: zoo_service_loader.c:257
+msgid "The specified path doesn't exist."
+msgstr ""
+
+#: zoo_service_loader.c:275
+msgid ".zcfg"
+msgstr ""
+
+#: zoo_service_loader.c:283 zoo_service_loader.c:370
+#, c-format
+msgid ""
+"#################\n"
+"%s\n"
+"#################\n"
+msgstr ""
+
+#: zoo_service_loader.c:311
+msgid "Mandatory <identifier> was not specified"
+msgstr ""
+
+#: zoo_service_loader.c:322
+msgid "The specified path path doesn't exist."
+msgstr ""
+
+#: zoo_service_loader.c:355
+#, c-format
+msgid "%s.zcfg"
+msgstr ""
+
+#: zoo_service_loader.c:358
+#, c-format
+msgid ""
+"\n"
+"#######%s\n"
+"########\n"
+msgstr ""
+
+#: zoo_service_loader.c:404
+#, c-format
+msgid "No request found %s"
+msgstr ""
+
+#: zoo_service_loader.c:422
+msgid "MetaPath"
+msgstr ""
+
+#: zoo_service_loader.c:429
+#, c-format
+msgid "%s/%s.zcfg"
+msgstr ""
+
+#: zoo_service_loader.c:432 zoo_service_loader.c:1481
+#: zoo_service_loader.c:1737
+#, c-format
+msgid "Trying to load %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:441
+#, c-format
+msgid ""
+"The value for <indetifier> seems to be wrong (%s). Please, ensure that the "
+"process exist using the GetCapabilities request."
+msgstr ""
+
+#: zoo_service_loader.c:470 zoo_service_loader.c:974
+msgid "ZooWPSClient"
+msgstr ""
+
+#: zoo_service_loader.c:476 zoo_service_loader.c:978
+#, c-format
+msgid "WARNING : hInternet handle failed to initialize"
+msgstr ""
+
+#: zoo_service_loader.c:481
+msgid "xrequest"
+msgstr ""
+
+#: zoo_service_loader.c:488 zoo_service_loader.c:494
+#, c-format
+msgid "OUTPUT Parsing ... \n"
+msgstr ""
+
+#: zoo_service_loader.c:490 zoo_service_loader.c:1135
+msgid "ResponseDocument"
+msgstr ""
+
+#: zoo_service_loader.c:498
+#, c-format
+msgid "OUTPUT Parsing start now ... \n"
+msgstr ""
+
+#: zoo_service_loader.c:514
+#, c-format
+msgid "OUTPUT [%s]\n"
+msgstr ""
+
+#: zoo_service_loader.c:516 zoo_service_loader.c:533 zoo_service_loader.c:620
+#: zoo_service_loader.c:639
+msgid ";"
+msgstr ""
+
+#: zoo_service_loader.c:519 zoo_service_loader.c:530
+msgid "Unable to allocate memory"
+msgstr ""
+
+#: zoo_service_loader.c:524 zoo_service_loader.c:526 zoo_service_loader.c:572
+#: zoo_service_loader.c:628 zoo_service_loader.c:632
+#, c-format
+msgid "***%s***\n"
+msgstr ""
+
+#: zoo_service_loader.c:540 zoo_service_loader.c:574 zoo_service_loader.c:647
+#: zoo_service_loader.c:670 zoo_service_loader.c:716
+msgid "@"
+msgstr ""
+
+#: zoo_service_loader.c:555 zoo_service_loader.c:652 zoo_service_loader.c:675
+msgid "="
+msgstr ""
+
+#: zoo_service_loader.c:561
+#, c-format
+msgid "OUTPUT DEF [%s]=[%s]\n"
+msgstr ""
+
+#: zoo_service_loader.c:599
+#, c-format
+msgid "DATA INPUTS [%s]\n"
+msgstr ""
+
+#: zoo_service_loader.c:606
+msgid "Parameter <DataInputs> was not specified"
+msgstr ""
+
+#: zoo_service_loader.c:650
+#, c-format
+msgid ""
+"***\n"
+"***%s***\n"
+msgstr ""
+
+#: zoo_service_loader.c:659
+#, c-format
+msgid ""
+"***\n"
+"*** %s = %s ***\n"
+msgstr ""
+
+#: zoo_service_loader.c:673
+#, c-format
+msgid ""
+"*** KVP NON URL-ENCODED \n"
+"***%s***\n"
+msgstr ""
+
+#: zoo_service_loader.c:677 zoo_service_loader.c:685
+#, c-format
+msgid ""
+"*** VALUE NON URL-ENCODED \n"
+"***%s***\n"
+msgstr ""
+
+#: zoo_service_loader.c:684
+#, c-format
+msgid ""
+"*** NAME NON URL-ENCODED \n"
+"***%s***\n"
+msgstr ""
+
+#: zoo_service_loader.c:687
+msgid "xlink:href"
+msgstr ""
+
+#: zoo_service_loader.c:691
+#, c-format
+msgid "REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n"
+msgstr ""
+
+#: zoo_service_loader.c:700
+#, c-format
+msgid "(%s) content-length : %d,,res.nDataAlloc %d \n"
+msgstr ""
+
+#: zoo_service_loader.c:745
+#, c-format
+msgid "BEFORE %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:751
+#, c-format
+msgid "AFTER\n"
+msgstr ""
+
+#: zoo_service_loader.c:759
+msgid "/*/*/*[local-name()='Input']"
+msgstr ""
+
+#: zoo_service_loader.c:762 zoo_service_loader.c:1132
+#: zoo_service_loader.c:1274
+#, c-format
+msgid "*****%d*****\n"
+msgstr ""
+
+#: zoo_service_loader.c:772
+#, c-format
+msgid "= element 0 node \"%s\"\n"
+msgstr ""
+
+#: zoo_service_loader.c:808 zoo_service_loader.c:1240
+msgid "missingIndetifier"
+msgstr ""
+
+#: zoo_service_loader.c:835
+#, c-format
+msgid "REFERENCE\n"
+msgstr ""
+
+#: zoo_service_loader.c:841 zoo_service_loader.c:1074
+#: zoo_service_loader.c:1187 zoo_service_loader.c:1287
+msgid "schema"
+msgstr ""
+
+#: zoo_service_loader.c:842 zoo_service_loader.c:855
+msgid "method"
+msgstr ""
+
+#: zoo_service_loader.c:847
+#, c-format
+msgid "*** %s ***"
+msgstr ""
+
+#: zoo_service_loader.c:857
+msgid "POST"
+msgstr ""
+
+#: zoo_service_loader.c:875 zoo_service_loader.c:909 zoo_service_loader.c:1061
+#: zoo_service_loader.c:1087 zoo_service_loader.c:1173
+#: zoo_service_loader.c:1202 zoo_service_loader.c:1308
+#: zoo_service_loader.c:1507
+#, c-format
+msgid "%s\n"
+msgstr ""
+
+#: zoo_service_loader.c:880
+#, c-format
+msgid "Parse Header and Body from Reference \n"
+msgstr ""
+
+#: zoo_service_loader.c:885
+msgid "Header"
+msgstr ""
+
+#: zoo_service_loader.c:889
+msgid "key"
+msgstr ""
+
+#: zoo_service_loader.c:897
+#, c-format
+msgid "%s = %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:907
+#, c-format
+msgid "%s: %s"
+msgstr ""
+
+#: zoo_service_loader.c:918
+#, c-format
+msgid "Try to fetch the body part of the request ...\n"
+msgstr ""
+
+#: zoo_service_loader.c:920
+msgid "Body"
+msgstr ""
+
+#: zoo_service_loader.c:922
+#, c-format
+msgid "Body part found !!!\n"
+msgstr ""
+
+#: zoo_service_loader.c:935
+#, c-format
+msgid "Body part found !!! %s %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:945 zoo_service_loader.c:997
+#, c-format
+msgid "%s %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:962 zoo_service_loader.c:1015
+#, c-format
+msgid "DL CONTENT : (%s)\n"
+msgstr ""
+
+#: zoo_service_loader.c:967
+msgid "BodyReference"
+msgstr ""
+
+#: zoo_service_loader.c:1023
+#, c-format
+msgid "Header and Body was parsed from Reference \n"
+msgstr ""
+
+#: zoo_service_loader.c:1027
+#, c-format
+msgid "= element 2 node \"%s\" = (%s)\n"
+msgstr ""
+
+#: zoo_service_loader.c:1033
+#, c-format
+msgid "DATA\n"
+msgstr ""
+
+#: zoo_service_loader.c:1047
+msgid "dataType"
+msgstr ""
+
+#: zoo_service_loader.c:1048 zoo_service_loader.c:1188
+#: zoo_service_loader.c:1288
+msgid "uom"
+msgstr ""
+
+#: zoo_service_loader.c:1051
+#, c-format
+msgid "*** LiteralData %s ***"
+msgstr ""
+
+#: zoo_service_loader.c:1077
+#, c-format
+msgid "*** ComplexData %s ***"
+msgstr ""
+
+#: zoo_service_loader.c:1099
+#, c-format
+msgid "cur2 next \n"
+msgstr ""
+
+#: zoo_service_loader.c:1105
+#, c-format
+msgid "ADD MAPS TO REQUEST MAPS !\n"
+msgstr ""
+
+#: zoo_service_loader.c:1111
+#, c-format
+msgid "******TMPMAPS*****\n"
+msgstr ""
+
+#: zoo_service_loader.c:1113
+#, c-format
+msgid "******REQUESTMAPS*****\n"
+msgstr ""
+
+#: zoo_service_loader.c:1125
+#, c-format
+msgid "Search for response document node\n"
+msgstr ""
+
+#: zoo_service_loader.c:1129
+msgid "/*/*/*[local-name()='ResponseDocument']"
+msgstr ""
+
+#: zoo_service_loader.c:1148 zoo_service_loader.c:1300
+msgid "unknownIdentifier"
+msgstr ""
+
+#: zoo_service_loader.c:1162 zoo_service_loader.c:1192
+#: zoo_service_loader.c:1291
+#, c-format
+msgid "*** %s ***\t"
+msgstr ""
+
+#: zoo_service_loader.c:1271
+msgid "/*/*/*[local-name()='RawDataOutput']"
+msgstr ""
+
+#: zoo_service_loader.c:1353
+#, c-format
+msgid ""
+"\n"
+"%i\n"
+msgstr ""
+
+#: zoo_service_loader.c:1366
+#, c-format
+msgid ""
+"The <%s> argument was not specified in DataInputs but defined as requested "
+"in ZOO ServicesProvider configuration file, please correct your query or the "
+"ZOO Configuration file."
+msgstr ""
+
+#: zoo_service_loader.c:1383
+msgid "outputs"
+msgstr ""
+
+#: zoo_service_loader.c:1386
+#, c-format
+msgid "REQUEST_INPUTS\n"
+msgstr ""
+
+#: zoo_service_loader.c:1388
+#, c-format
+msgid "REQUEST_OUTPUTS\n"
+msgstr ""
+
+#: zoo_service_loader.c:1392
+msgid "env"
+msgstr ""
+
+#: zoo_service_loader.c:1400 zoo_service_loader.c:1423
+#, c-format
+msgid "[ZOO: setenv (%s=%s)]\n"
+msgstr ""
+
+#: zoo_service_loader.c:1404
+#, c-format
+msgid "[ZOO: Env var finish with \r]\n"
+msgstr ""
+
+#: zoo_service_loader.c:1410
+#, c-format
+msgid "setting variable... %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1414
+msgid "OK"
+msgstr ""
+
+#: zoo_service_loader.c:1414
+msgid "FAILED"
+msgstr ""
+
+#: zoo_service_loader.c:1448
+msgid "0"
+msgstr ""
+
+#: zoo_service_loader.c:1465 zoo_service_loader.c:1504
+#: zoo_service_loader.c:1718 zoo_service_loader.c:1752
+msgid "serviceType"
+msgstr ""
+
+#: zoo_service_loader.c:1467
+#, c-format
+msgid "LOAD A %s SERVICE PROVIDER IN NORMAL MODE \n"
+msgstr ""
+
+#: zoo_service_loader.c:1492
+#, c-format
+msgid "%s loaded (%d) \n"
+msgstr ""
+
+#: zoo_service_loader.c:1501 zoo_service_loader.c:1799
+#, c-format
+msgid "Library loaded %s \n"
+msgstr ""
+
+#: zoo_service_loader.c:1502
+#, c-format
+msgid "Service Shared Object = %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1510 zoo_service_loader.c:1756
+msgid "C-FORTRAN"
+msgstr ""
+
+#: zoo_service_loader.c:1517 zoo_service_loader.c:1763
+#, c-format
+msgid "%s_"
+msgstr ""
+
+#: zoo_service_loader.c:1519 zoo_service_loader.c:1564
+#: zoo_service_loader.c:1759 zoo_service_loader.c:1765
+#: zoo_service_loader.c:1803
+#, c-format
+msgid "Try to load function %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1534 zoo_service_loader.c:1583
+#: zoo_service_loader.c:1816
+#, c-format
+msgid "Function loaded %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1552
+#, c-format
+msgid "Function run successfully \n"
+msgstr ""
+
+#: zoo_service_loader.c:1559 zoo_service_loader.c:1571
+#, c-format
+msgid "Function %s failed to load because of %d\n"
+msgstr ""
+
+#: zoo_service_loader.c:1587
+#, c-format
+msgid "Now run the function \n"
+msgstr ""
+
+#: zoo_service_loader.c:1592 zoo_service_loader.c:1889
+#, c-format
+msgid "Function loaded and returned %d\n"
+msgstr ""
+
+#: zoo_service_loader.c:1607 zoo_service_loader.c:1829
+#, c-format
+msgid "C Library can't be loaded %s \n"
+msgstr ""
+
+#: zoo_service_loader.c:1615 zoo_service_loader.c:1839
+msgid "PYTHON"
+msgstr ""
+
+#: zoo_service_loader.c:1622 zoo_service_loader.c:1844
+msgid "JAVA"
+msgstr ""
+
+#: zoo_service_loader.c:1629 zoo_service_loader.c:1851
+msgid "PHP"
+msgstr ""
+
+#: zoo_service_loader.c:1637 zoo_service_loader.c:1858
+msgid "PERL"
+msgstr ""
+
+#: zoo_service_loader.c:1644 zoo_service_loader.c:1864
+msgid "JS"
+msgstr ""
+
+#: zoo_service_loader.c:1651 zoo_service_loader.c:1871
+#, c-format
+msgid ""
+"Programming Language (%s) set in ZCFG file is not currently supported by ZOO "
+"Kernel.\n"
+msgstr ""
+
+#: zoo_service_loader.c:1661
+#, c-format
+msgid ""
+"\n"
+"PID : %d\n"
+msgstr ""
+
+#: zoo_service_loader.c:1675
+#, c-format
+msgid "father pid continue (origin %d) %d ...\n"
+msgstr ""
+
+#: zoo_service_loader.c:1686
+#, c-format
+msgid "%s/%s_%d.xml"
+msgstr ""
+
+#: zoo_service_loader.c:1688
+#, c-format
+msgid "%s/%s_%d_error.log"
+msgstr ""
+
+#: zoo_service_loader.c:1690
+#, c-format
+msgid "RUN IN BACKGROUND MODE \n"
+msgstr ""
+
+#: zoo_service_loader.c:1691
+#, c-format
+msgid "son pid continue (origin %d) %d ...\n"
+msgstr ""
+
+#: zoo_service_loader.c:1692
+#, c-format
+msgid ""
+"\n"
+"FILE TO STORE DATA %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1694 zoo_service_loader.c:1696
+msgid "w+"
+msgstr ""
+
+#: zoo_service_loader.c:1700
+msgid "Unable to run the child process properly"
+msgstr ""
+
+#: zoo_service_loader.c:1720
+#, c-format
+msgid "LOAD A %s SERVICE PROVIDER IN BACKGROUND MODE \n"
+msgstr ""
+
+#: zoo_service_loader.c:1754
+#, c-format
+msgid "r_inputs->value = %s\n"
+msgstr ""
+
+#: zoo_service_loader.c:1918
+#, c-format
+msgid "Processed response \n"
+msgstr ""
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main.cfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main.cfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main.cfg	(revision 672)
@@ -0,0 +1,32 @@
+[main]
+encoding = utf-8
+version = 1.0.0
+serverAddress = http://www.zoo-project.org/zoo/
+lang = fr-FR,en-CA,en-US
+tmpPath=/tmp/
+tmpUrl = ../mpPathRelativeToServerAdress/
+dataPath = /tmp/
+cacheDir = /tmp/
+
+[identification]
+title = The Zoo WPS Development Server
+abstract = Development version of ZooWPS. See http://www.zoo-project.org
+fees = None
+accessConstraints = none
+keywords = WPS,GIS,buffer
+
+[provider]
+providerName=ZOO Project
+providerSite=http://www.zoo-project.org
+individualName=Gerald FENOY
+positionName=Developer
+role=Dev
+addressDeliveryPoint=1280, avenue des Platanes
+addressCity=Lattes
+addressAdministrativeArea=False
+addressPostalCode=34970
+addressCountry=fr
+addressElectronicMailAddress=gerald@geolabs.fr
+phoneVoice=False
+phoneFacsimile=False
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.l
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.l	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.l	(revision 672)
@@ -0,0 +1,65 @@
+/*
+ * Zoo main configuration file parser
+ *
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 209-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+%option yylineno
+
+%{
+
+#include <string.h>
+#include "main_conf_read.tab.h"
+static int affichetrace = 0 ;
+
+%}
+
+attname	[a-zA-Z0-9_\-:]+
+
+attvalue1	[%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff]+
+
+whitesp                      [ ]
+newline                 [\r\n]|[\n]
+
+%x DANSBALISE HORSBALISE PAIRSTART
+
+%%
+
+"\n" {if (affichetrace==1) printf ("\n\nNEWLINE\n") ; return NEWLINE;}
+
+{newline}+{whitesp}*			{if (affichetrace==1) printf ("\n\nNEWLINE 1\n") ; return NEWLINE;}
+
+<INITIAL,HORSBALISE>"["{attname}"]"             {if (affichetrace==1) printf ("\n\nANID:%s\n",yytext); crlval.chaine=yytext;crlval.chaine[strlen(crlval.chaine)-1]=0;crlval.chaine+=1;return ANID; }
+
+<INITIAL,HORSBALISE>{attname}             {if (affichetrace==1) printf ("\n\nATT_NAME:%s\n",yytext); crlval.chaine=yytext; return SPAIR; }
+
+<PAIRSTART,HORSBALISE>{attvalue1}             {if (affichetrace==1) printf ("\n\nATT_VALUE:%s\n",yytext);crlval.chaine=yytext;BEGIN(INITIAL);return EPAIR;}
+
+<PAIRSTART,INITIAL,HORSBALISE>{whitesp}*"="{whitesp}*             {BEGIN(PAIRSTART);}
+
+<PAIRSTART,INITIAL,HORSBALISE,DANSBALISE>{newline}+{whitesp}*			{if (affichetrace==1) printf ("\n\nNEWLINE 2\n") ; BEGIN(INITIAL); return NEWLINE;}
+
+%%
+
+
+int crwrap()
+{return 1;}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.y
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.y	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/main_conf_read.y	(revision 672)
@@ -0,0 +1,175 @@
+/*
+ * Zoo main configuration file parser
+ *
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 209-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+%{
+#include <service.h>
+
+static maps* my_maps=NULL;
+static maps* current_maps=NULL;
+static map* current_content=NULL;
+static char* curr_key;
+static int debug=0;
+
+extern void crerror(const char *s);
+
+void usage(void) ;
+
+extern int crdebug;
+
+extern char crtext[];
+
+extern int crlineno;
+
+extern FILE* crin;
+
+extern int crlex(void);
+extern int crlex_destroy(void);
+
+%}
+
+%union { char* s;char* chaine; char* key;char* val;}
+
+%token <s> ID
+%token <s> CHAINE
+
+%token PAIR SPAIR EPAIR EPAIRS ANID
+%type <chaine> PAIR
+%type <chaine> EPAIRS
+%type <chaine> EPAIR
+%type <chaine> SPAIR
+
+%token WHITESPACE NEWLINE
+
+%type <s> ANID
+
+%%
+
+document
+ : miscetoile miscetoile {}
+ | contentetoile processid contentetoile document {}
+ ;
+
+miscetoile
+ : {}
+ ;
+
+Attributeetoile
+ : Attributeetoile  {}
+ | 	                          {/* Epsilon */}
+ ;
+
+contentetoile
+: contentetoile NEWLINE {}
+ | contentetoile pair {}
+ | {/* Epsilon */}
+ ;
+
+pair: PAIR {curr_key=zStrdup($1);}
+| EPAIR {
+  if(current_content==NULL) 
+    current_content=createMap(curr_key,$1);
+  else{ 
+    addToMap(current_content,curr_key,$1);
+  }
+  if(debug){ 
+    printf("EPAIR FOUND !! \n"); 
+    printf("[%s=>%s]\n",curr_key,$1);
+  }
+  free(curr_key);
+  }
+| SPAIR  {curr_key=zStrdup($1);if(debug) printf("SPAIR FOUND !!\n"); }
+ ;
+
+
+processid
+: ANID  {
+   if(current_maps->name!=NULL){
+     addMapToMap(&current_maps->content,current_content);
+     freeMap(&current_content);
+     free(current_content);
+     current_maps->next=NULL;
+     current_maps->next=(maps*)malloc(MAPS_SIZE);
+     current_maps->next->name=zStrdup($1);
+     current_maps->next->content=NULL;
+     current_maps->next->next=NULL;
+     current_maps=current_maps->next;
+     current_content=current_maps->content;
+   }
+   else{
+     current_maps->name=(char*)malloc((strlen($1)+1)*sizeof(char));
+     snprintf(current_maps->name,(strlen($1)+1),"%s",$1);
+     current_maps->content=NULL;
+     current_maps->next=NULL;
+     current_content=NULL;
+   }
+ }
+ ;
+
+%%
+
+/**
+ * Print on stderr the message and the line number of the error which occured.
+ *
+ * @param s the error message
+ */
+void crerror(const char *s)
+{
+  if(debug)
+    printf("\nligne %d : %s\n",crlineno,s);
+}
+
+/**
+ * Parse the main.cfg file and fill the maps structure.
+ *
+ * @param file the filename to parse
+ * @param my_map the maps structure to fill
+ */
+int conf_read(const char* file,maps* my_map){
+  
+  crin = fopen(file,"r");
+  if (crin==NULL){
+    return 2 ;
+  }
+
+  my_maps=my_map;
+  my_maps->name=NULL;
+  current_maps=my_maps;
+  
+  int resultatYYParse = crparse() ;
+  if(current_content!=NULL){
+    addMapToMap(&current_maps->content,current_content);
+    current_maps->next=NULL;
+    freeMap(&current_content);
+    free(current_content);
+  }
+
+  fclose(crin);
+#ifndef WIN32
+  crlex_destroy();
+#endif
+
+  return resultatYYParse;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/makefile.vc	(revision 672)
@@ -0,0 +1,77 @@
+# WIN32 Makefile tested using VC-9.0
+# Don't forget to set your PATH using the following command :
+# c:\Progam Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat
+# set PATH=%PATH%;$(TOOLS)
+# using value for TOOLS relative to your local installation
+#
+
+!INCLUDE nmake.opt
+
+all:  $(PROGRAMNAME) zcfg2yaml
+
+version.h:
+	set VERS=`svnversion .`
+	echo #define ZOO_VERSION "$(VERS)" > version.h
+
+main_conf_read.tab.c: main_conf_read.y service.h
+	bison -p cr -d main_conf_read.y
+
+main_conf_read.tab.obj: main_conf_read.tab.c service.h
+	$(CPP) /EHsc $(CFLAGS) main_conf_read.tab.c /c
+
+lex.cr.c: main_conf_read.y main_conf_read.l main_conf_read.tab.c service.h
+	flex -Pcr main_conf_read.l
+
+lex.cr.obj: lex.cr.c service.h
+	$(CPP) $(CFLAGS) /c lex.cr.c
+
+service_conf.tab.c: service_conf.y service.h
+	bison -p sr -d service_conf.y
+
+service_conf.tab.obj: service_conf.tab.c service.h
+	$(CPP) $(CFLAGS) service_conf.tab.c /c
+
+lex.sr.c: service_conf.y service_conf.l service_conf.tab.c service.h
+	flex -Psr service_conf.l
+
+lex.sr.obj: lex.sr.c service.h
+	$(CPP) $(CFLAGS) /c lex.sr.c
+
+zcfg2yaml.obj: zcfg2yaml.c
+	$(CPP) $(CFLAGS) /c zcfg2yaml.c
+
+service_internal.obj: service_internal.c mimetypes.h
+	$(CPP) $(CFLAGS) /c service_internal.c
+
+service_internal_js.obj: service_internal_js.c service.h
+	$(CPP) /c $(CFLAGS) service_internal_js.c
+
+service_internal_java.obj: service_internal_java.c service.h
+	$(CPP) /c $(CFLAGS) service_internal_java.c
+
+service_internal_ruby.obj: service_internal_ruby.c service_internal_ruby.h service.h
+	$(CPP) /c $(CFLAGS) service_internal_ruby.c
+
+service_internal_python.obj: service_internal_python.c service.h
+	$(CPP) /c $(CFLAGS) service_internal_python.c
+
+service_internal_ms.obj: service_internal_ms.c service.h
+	$(CPP) /c $(CFLAGS) service_internal_ms.c
+
+service_loader.obj: service_loader.c service.h
+	$(CPP) /c $(CFLAGS)  service_loader.c
+
+zoo_service_loader.obj: zoo_service_loader.c service.h
+	$(CPP) /c $(CFLAGS)  zoo_service_loader.c
+
+zoo_loader.obj: zoo_loader.c service.h
+	$(CPP) /EHsc /c $(CFLAGS) zoo_loader.c
+
+$(PROGRAMNAME): version.h zoo_loader.obj zoo_service_loader.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj
+	link zoo_loader.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) ulinet.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj  zoo_service_loader.obj /out:$(PROGRAMNAME) $(LDFLAGS) $(LDFLAGSCGI)
+
+zcfg2yaml: version.h zcfg2yaml.obj zoo_service_loader.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj
+	link zcfg2yaml.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) ulinet.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj /out:zcfg2yaml.exe $(LDFLAGS) $(LDFLAGSCGI)
+
+clean:
+	erase -f *.cgi *.obj *.tab.c* *.tab.h *.sr.c* lex.* *.lreg *.sibling
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/mimetypes.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/mimetypes.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/mimetypes.h	(revision 672)
@@ -0,0 +1,837 @@
+#include "service.h"
+ 
+typedef enum MimeTypes {
+	 M_Type,
+	 M_Extension
+} mimetype;
+
+#define NUM_MIME_TYPES 767
+
+/*
+ * This array has been constructed based on the
+ * Apache web server's mime.types file
+ */
+const char* const MIME[NUM_MIME_TYPES][2] = {
+	{ "application/andrew-inset", "ez" },
+	{ "application/applixware", "aw" },
+	{ "application/atom+xml", "atom" },
+	{ "application/atomcat+xml", "atomcat" },
+	{ "application/atomsvc+xml", "atomsvc" },
+	{ "application/ccxml+xml", "ccxml" },
+	{ "application/cdmi-capability", "cdmia" },
+	{ "application/cdmi-container", "cdmic" },
+	{ "application/cdmi-domain", "cdmid" },
+	{ "application/cdmi-object", "cdmio" },
+	{ "application/cdmi-queue", "cdmiq" },
+	{ "application/cu-seeme", "cu" },
+	{ "application/davmount+xml", "davmount" },
+	{ "application/docbook+xml", "dbk" },
+	{ "application/dssc+der", "dssc" },
+	{ "application/dssc+xml", "xdssc" },
+	{ "application/ecmascript", "ecma" },
+	{ "application/emma+xml", "emma" },
+	{ "application/epub+zip", "epub" },
+	{ "application/exi", "exi" },
+	{ "application/font-tdpfr", "pfr" },
+	{ "application/gml+xml", "gml" },
+	{ "application/gpx+xml", "gpx" },
+	{ "application/gxf", "gxf" },
+	{ "application/hyperstudio", "stk" },
+	{ "application/inkml+xml", "ink" },
+	{ "application/ipfix", "ipfix" },
+	{ "application/java-archive", "jar" },
+	{ "application/java-serialized-object", "ser" },
+	{ "application/java-vm", "class" },
+	{ "application/javascript", "js" },
+	{ "application/json", "json" },
+	{ "application/jsonml+json", "jsonml" },
+	{ "application/lost+xml", "lostxml" },
+	{ "application/mac-binhex40", "hqx" },
+	{ "application/mac-compactpro", "cpt" },
+	{ "application/mads+xml", "mads" },
+	{ "application/marc", "mrc" },
+	{ "application/marcxml+xml", "mrcx" },
+	{ "application/mathematica", "ma" },
+	{ "application/mathml+xml", "mathml" },
+	{ "application/mbox", "mbox" },
+	{ "application/mediaservercontrol+xml", "mscml" },
+	{ "application/metalink+xml", "metalink" },
+	{ "application/metalink4+xml", "meta4" },
+	{ "application/mets+xml", "mets" },
+	{ "application/mods+xml", "mods" },
+	{ "application/mp21", "m21" },
+	{ "application/mp4", "mp4s" },
+	{ "application/msword", "doc" },
+	{ "application/mxf", "mxf" },
+	{ "application/octet-stream", "bin" },
+	{ "application/oda", "oda" },
+	{ "application/oebps-package+xml", "opf" },
+	{ "application/ogg", "ogx" },
+	{ "application/omdoc+xml", "omdoc" },
+	{ "application/onenote", "onetoc" },
+	{ "application/oxps", "oxps" },
+	{ "application/patch-ops-error+xml", "xer" },
+	{ "application/pdf", "pdf" },
+	{ "application/pgp-encrypted", "pgp" },
+	{ "application/pgp-signature", "asc" },
+	{ "application/pics-rules", "prf" },
+	{ "application/pkcs10", "p10" },
+	{ "application/pkcs7-mime", "p7m" },
+	{ "application/pkcs7-signature", "p7s" },
+	{ "application/pkcs8", "p8" },
+	{ "application/pkix-attr-cert", "ac" },
+	{ "application/pkix-cert", "cer" },
+	{ "application/pkix-crl", "crl" },
+	{ "application/pkix-pkipath", "pkipath" },
+	{ "application/pkixcmp", "pki" },
+	{ "application/pls+xml", "pls" },
+	{ "application/postscript", "ps" },
+	{ "application/prs.cww", "cww" },
+	{ "application/pskc+xml", "pskcxml" },
+	{ "application/rdf+xml", "rdf" },
+	{ "application/reginfo+xml", "rif" },
+	{ "application/relax-ng-compact-syntax", "rnc" },
+	{ "application/resource-lists+xml", "rl" },
+	{ "application/resource-lists-diff+xml", "rld" },
+	{ "application/rls-services+xml", "rs" },
+	{ "application/rpki-ghostbusters", "gbr" },
+	{ "application/rpki-manifest", "mft" },
+	{ "application/rpki-roa", "roa" },
+	{ "application/rsd+xml", "rsd" },
+	{ "application/rss+xml", "rss" },
+	{ "application/rtf", "rtf" },
+	{ "application/sbml+xml", "sbml" },
+	{ "application/scvp-cv-request", "scq" },
+	{ "application/scvp-cv-response", "scs" },
+	{ "application/scvp-vp-request", "spq" },
+	{ "application/scvp-vp-response", "spp" },
+	{ "application/sdp", "sdp" },
+	{ "application/set-payment-initiation", "setpay" },
+	{ "application/set-registration-initiation", "setreg" },
+	{ "application/shf+xml", "shf" },
+	{ "application/smil+xml", "smi" },
+	{ "application/sparql-query", "rq" },
+	{ "application/sparql-results+xml", "srx" },
+	{ "application/srgs", "gram" },
+	{ "application/srgs+xml", "grxml" },
+	{ "application/sru+xml", "sru" },
+	{ "application/ssdl+xml", "ssdl" },
+	{ "application/ssml+xml", "ssml" },
+	{ "application/tei+xml", "tei" },
+	{ "application/thraud+xml", "tfi" },
+	{ "application/timestamped-data", "tsd" },
+	{ "application/vnd.3gpp.pic-bw-large", "plb" },
+	{ "application/vnd.3gpp.pic-bw-small", "psb" },
+	{ "application/vnd.3gpp.pic-bw-var", "pvb" },
+	{ "application/vnd.3gpp2.tcap", "tcap" },
+	{ "application/vnd.3m.post-it-notes", "pwn" },
+	{ "application/vnd.accpac.simply.aso", "aso" },
+	{ "application/vnd.accpac.simply.imp", "imp" },
+	{ "application/vnd.acucobol", "acu" },
+	{ "application/vnd.acucorp", "atc" },
+	{ "application/vnd.adobe.air-application-installer-package+zip", "air" },
+	{ "application/vnd.adobe.formscentral.fcdt", "fcdt" },
+	{ "application/vnd.adobe.fxp", "fxp" },
+	{ "application/vnd.adobe.xdp+xml", "xdp" },
+	{ "application/vnd.adobe.xfdf", "xfdf" },
+	{ "application/vnd.ahead.space", "ahead" },
+	{ "application/vnd.airzip.filesecure.azf", "azf" },
+	{ "application/vnd.airzip.filesecure.azs", "azs" },
+	{ "application/vnd.amazon.ebook", "azw" },
+	{ "application/vnd.americandynamics.acc", "acc" },
+	{ "application/vnd.amiga.ami", "ami" },
+	{ "application/vnd.android.package-archive", "apk" },
+	{ "application/vnd.anser-web-certificate-issue-initiation", "cii" },
+	{ "application/vnd.anser-web-funds-transfer-initiation", "fti" },
+	{ "application/vnd.antix.game-component", "atx" },
+	{ "application/vnd.apple.installer+xml", "mpkg" },
+	{ "application/vnd.apple.mpegurl", "m3u8" },
+	{ "application/vnd.aristanetworks.swi", "swi" },
+	{ "application/vnd.astraea-software.iota", "iota" },
+	{ "application/vnd.audiograph", "aep" },
+	{ "application/vnd.blueice.multipass", "mpm" },
+	{ "application/vnd.bmi", "bmi" },
+	{ "application/vnd.businessobjects", "rep" },
+	{ "application/vnd.chemdraw+xml", "cdxml" },
+	{ "application/vnd.chipnuts.karaoke-mmd", "mmd" },
+	{ "application/vnd.cinderella", "cdy" },
+	{ "application/vnd.claymore", "cla" },
+	{ "application/vnd.cloanto.rp9", "rp9" },
+	{ "application/vnd.clonk.c4group", "c4g" },
+	{ "application/vnd.cluetrust.cartomobile-config", "c11amc" },
+	{ "application/vnd.cluetrust.cartomobile-config-pkg", "c11amz" },
+	{ "application/vnd.commonspace", "csp" },
+	{ "application/vnd.contact.cmsg", "cdbcmsg" },
+	{ "application/vnd.cosmocaller", "cmc" },
+	{ "application/vnd.crick.clicker", "clkx" },
+	{ "application/vnd.crick.clicker.keyboard", "clkk" },
+	{ "application/vnd.crick.clicker.palette", "clkp" },
+	{ "application/vnd.crick.clicker.template", "clkt" },
+	{ "application/vnd.crick.clicker.wordbank", "clkw" },
+	{ "application/vnd.criticaltools.wbs+xml", "wbs" },
+	{ "application/vnd.ctc-posml", "pml" },
+	{ "application/vnd.cups-ppd", "ppd" },
+	{ "application/vnd.curl.car", "car" },
+	{ "application/vnd.curl.pcurl", "pcurl" },
+	{ "application/vnd.dart", "dart" },
+	{ "application/vnd.data-vision.rdz", "rdz" },
+	{ "application/vnd.dece.data", "uvf" },
+	{ "application/vnd.dece.ttml+xml", "uvt" },
+	{ "application/vnd.dece.unspecified", "uvx" },
+	{ "application/vnd.dece.zip", "uvz" },
+	{ "application/vnd.denovo.fcselayout-link", "fe_launch" },
+	{ "application/vnd.dna", "dna" },
+	{ "application/vnd.dolby.mlp", "mlp" },
+	{ "application/vnd.dpgraph", "dpg" },
+	{ "application/vnd.dreamfactory", "dfac" },
+	{ "application/vnd.ds-keypoint", "kpxx" },
+	{ "application/vnd.dvb.ait", "ait" },
+	{ "application/vnd.dvb.service", "svc" },
+	{ "application/vnd.dynageo", "geo" },
+	{ "application/vnd.ecowin.chart", "mag" },
+	{ "application/vnd.enliven", "nml" },
+	{ "application/vnd.epson.esf", "esf" },
+	{ "application/vnd.epson.msf", "msf" },
+	{ "application/vnd.epson.quickanime", "qam" },
+	{ "application/vnd.epson.salt", "slt" },
+	{ "application/vnd.epson.ssf", "ssf" },
+	{ "application/vnd.eszigno3+xml", "es3" },
+	{ "application/vnd.ezpix-album", "ez2" },
+	{ "application/vnd.ezpix-package", "ez3" },
+	{ "application/vnd.fdf", "fdf" },
+	{ "application/vnd.fdsn.mseed", "mseed" },
+	{ "application/vnd.fdsn.seed", "seed" },
+	{ "application/vnd.flographit", "gph" },
+	{ "application/vnd.fluxtime.clip", "ftc" },
+	{ "application/vnd.framemaker", "fm" },
+	{ "application/vnd.frogans.fnc", "fnc" },
+	{ "application/vnd.frogans.ltf", "ltf" },
+	{ "application/vnd.fsc.weblaunch", "fsc" },
+	{ "application/vnd.fujitsu.oasys", "oas" },
+	{ "application/vnd.fujitsu.oasys2", "oa2" },
+	{ "application/vnd.fujitsu.oasys3", "oa3" },
+	{ "application/vnd.fujitsu.oasysgp", "fg5" },
+	{ "application/vnd.fujitsu.oasysprs", "bh2" },
+	{ "application/vnd.fujixerox.ddd", "ddd" },
+	{ "application/vnd.fujixerox.docuworks", "xdw" },
+	{ "application/vnd.fujixerox.docuworks.binder", "xbd" },
+	{ "application/vnd.fuzzysheet", "fzs" },
+	{ "application/vnd.genomatix.tuxedo", "txd" },
+	{ "application/vnd.geogebra.file", "ggb" },
+	{ "application/vnd.geogebra.tool", "ggt" },
+	{ "application/vnd.geometry-explorer", "gex" },
+	{ "application/vnd.geonext", "gxt" },
+	{ "application/vnd.geoplan", "g2w" },
+	{ "application/vnd.geospace", "g3w" },
+	{ "application/vnd.gmx", "gmx" },
+	{ "application/vnd.google-earth.kml+xml", "kml" },
+	{ "application/vnd.google-earth.kmz", "kmz" },
+	{ "application/vnd.grafeq", "gqf" },
+	{ "application/vnd.groove-account", "gac" },
+	{ "application/vnd.groove-help", "ghf" },
+	{ "application/vnd.groove-identity-message", "gim" },
+	{ "application/vnd.groove-injector", "grv" },
+	{ "application/vnd.groove-tool-message", "gtm" },
+	{ "application/vnd.groove-tool-template", "tpl" },
+	{ "application/vnd.groove-vcard", "vcg" },
+	{ "application/vnd.hal+xml", "hal" },
+	{ "application/vnd.handheld-entertainment+xml", "zmm" },
+	{ "application/vnd.hbci", "hbci" },
+	{ "application/vnd.hhe.lesson-player", "les" },
+	{ "application/vnd.hp-hpgl", "hpgl" },
+	{ "application/vnd.hp-hpid", "hpid" },
+	{ "application/vnd.hp-hps", "hps" },
+	{ "application/vnd.hp-jlyt", "jlt" },
+	{ "application/vnd.hp-pcl", "pcl" },
+	{ "application/vnd.hp-pclxl", "pclxl" },
+	{ "application/vnd.hydrostatix.sof-data", "sfd-hdstx" },
+	{ "application/vnd.ibm.minipay", "mpy" },
+	{ "application/vnd.ibm.modcap", "afp" },
+	{ "application/vnd.ibm.rights-management", "irm" },
+	{ "application/vnd.ibm.secure-container", "sc" },
+	{ "application/vnd.iccprofile", "icc" },
+	{ "application/vnd.igloader", "igl" },
+	{ "application/vnd.immervision-ivp", "ivp" },
+	{ "application/vnd.immervision-ivu", "ivu" },
+	{ "application/vnd.insors.igm", "igm" },
+	{ "application/vnd.intercon.formnet", "xpw" },
+	{ "application/vnd.intergeo", "i2g" },
+	{ "application/vnd.intu.qbo", "qbo" },
+	{ "application/vnd.intu.qfx", "qfx" },
+	{ "application/vnd.ipunplugged.rcprofile", "rcprofile" },
+	{ "application/vnd.irepository.package+xml", "irp" },
+	{ "application/vnd.is-xpr", "xpr" },
+	{ "application/vnd.isac.fcs", "fcs" },
+	{ "application/vnd.jam", "jam" },
+	{ "application/vnd.jcp.javame.midlet-rms", "rms" },
+	{ "application/vnd.jisp", "jisp" },
+	{ "application/vnd.joost.joda-archive", "joda" },
+	{ "application/vnd.kahootz", "ktz" },
+	{ "application/vnd.kde.karbon", "karbon" },
+	{ "application/vnd.kde.kchart", "chrt" },
+	{ "application/vnd.kde.kformula", "kfo" },
+	{ "application/vnd.kde.kivio", "flw" },
+	{ "application/vnd.kde.kontour", "kon" },
+	{ "application/vnd.kde.kpresenter", "kpr" },
+	{ "application/vnd.kde.kspread", "ksp" },
+	{ "application/vnd.kde.kword", "kwd" },
+	{ "application/vnd.kenameaapp", "htke" },
+	{ "application/vnd.kidspiration", "kia" },
+	{ "application/vnd.kinar", "kne" },
+	{ "application/vnd.koan", "skp" },
+	{ "application/vnd.kodak-descriptor", "sse" },
+	{ "application/vnd.las.las+xml", "lasxml" },
+	{ "application/vnd.llamagraphics.life-balance.desktop", "lbd" },
+	{ "application/vnd.llamagraphics.life-balance.exchange+xml", "lbe" },
+	{ "application/vnd.lotus-1-2-3", "123" },
+	{ "application/vnd.lotus-approach", "apr" },
+	{ "application/vnd.lotus-freelance", "pre" },
+	{ "application/vnd.lotus-notes", "nsf" },
+	{ "application/vnd.lotus-organizer", "org" },
+	{ "application/vnd.lotus-screencam", "scm" },
+	{ "application/vnd.lotus-wordpro", "lwp" },
+	{ "application/vnd.macports.portpkg", "portpkg" },
+	{ "application/vnd.mcd", "mcd" },
+	{ "application/vnd.medcalcdata", "mc1" },
+	{ "application/vnd.mediastation.cdkey", "cdkey" },
+	{ "application/vnd.mfer", "mwf" },
+	{ "application/vnd.mfmp", "mfm" },
+	{ "application/vnd.micrografx.flo", "flo" },
+	{ "application/vnd.micrografx.igx", "igx" },
+	{ "application/vnd.mif", "mif" },
+	{ "application/vnd.mobius.daf", "daf" },
+	{ "application/vnd.mobius.dis", "dis" },
+	{ "application/vnd.mobius.mbk", "mbk" },
+	{ "application/vnd.mobius.mqy", "mqy" },
+	{ "application/vnd.mobius.msl", "msl" },
+	{ "application/vnd.mobius.plc", "plc" },
+	{ "application/vnd.mobius.txf", "txf" },
+	{ "application/vnd.mophun.application", "mpn" },
+	{ "application/vnd.mophun.certificate", "mpc" },
+	{ "application/vnd.mozilla.xul+xml", "xul" },
+	{ "application/vnd.ms-artgalry", "cil" },
+	{ "application/vnd.ms-cab-compressed", "cab" },
+	{ "application/vnd.ms-excel", "xls" },
+	{ "application/vnd.ms-excel.addin.macroenabled.12", "xlam" },
+	{ "application/vnd.ms-excel.sheet.binary.macroenabled.12", "xlsb" },
+	{ "application/vnd.ms-excel.sheet.macroenabled.12", "xlsm" },
+	{ "application/vnd.ms-excel.template.macroenabled.12", "xltm" },
+	{ "application/vnd.ms-fontobject", "eot" },
+	{ "application/vnd.ms-htmlhelp", "chm" },
+	{ "application/vnd.ms-ims", "ims" },
+	{ "application/vnd.ms-lrm", "lrm" },
+	{ "application/vnd.ms-officetheme", "thmx" },
+	{ "application/vnd.ms-pki.seccat", "cat" },
+	{ "application/vnd.ms-pki.stl", "stl" },
+	{ "application/vnd.ms-powerpoint", "ppt" },
+	{ "application/vnd.ms-powerpoint.addin.macroenabled.12", "ppam" },
+	{ "application/vnd.ms-powerpoint.presentation.macroenabled.12", "pptm" },
+	{ "application/vnd.ms-powerpoint.slide.macroenabled.12", "sldm" },
+	{ "application/vnd.ms-powerpoint.slideshow.macroenabled.12", "ppsm" },
+	{ "application/vnd.ms-powerpoint.template.macroenabled.12", "potm" },
+	{ "application/vnd.ms-project", "mpp" },
+	{ "application/vnd.ms-word.document.macroenabled.12", "docm" },
+	{ "application/vnd.ms-word.template.macroenabled.12", "dotm" },
+	{ "application/vnd.ms-works", "wps" },
+	{ "application/vnd.ms-wpl", "wpl" },
+	{ "application/vnd.ms-xpsdocument", "xps" },
+	{ "application/vnd.mseq", "mseq" },
+	{ "application/vnd.musician", "mus" },
+	{ "application/vnd.muvee.style", "msty" },
+	{ "application/vnd.mynfc", "taglet" },
+	{ "application/vnd.neurolanguage.nlu", "nlu" },
+	{ "application/vnd.nitf", "ntf" },
+	{ "application/vnd.noblenet-directory", "nnd" },
+	{ "application/vnd.noblenet-sealer", "nns" },
+	{ "application/vnd.noblenet-web", "nnw" },
+	{ "application/vnd.nokia.n-gage.data", "ngdat" },
+	{ "application/vnd.nokia.n-gage.symbian.install", "n-gage" },
+	{ "application/vnd.nokia.radio-preset", "rpst" },
+	{ "application/vnd.nokia.radio-presets", "rpss" },
+	{ "application/vnd.novadigm.edm", "edm" },
+	{ "application/vnd.novadigm.edx", "edx" },
+	{ "application/vnd.novadigm.ext", "ext" },
+	{ "application/vnd.oasis.opendocument.chart", "odc" },
+	{ "application/vnd.oasis.opendocument.chart-template", "otc" },
+	{ "application/vnd.oasis.opendocument.database", "odb" },
+	{ "application/vnd.oasis.opendocument.formula", "odf" },
+	{ "application/vnd.oasis.opendocument.formula-template", "odft" },
+	{ "application/vnd.oasis.opendocument.graphics", "odg" },
+	{ "application/vnd.oasis.opendocument.graphics-template", "otg" },
+	{ "application/vnd.oasis.opendocument.image", "odi" },
+	{ "application/vnd.oasis.opendocument.image-template", "oti" },
+	{ "application/vnd.oasis.opendocument.presentation", "odp" },
+	{ "application/vnd.oasis.opendocument.presentation-template", "otp" },
+	{ "application/vnd.oasis.opendocument.spreadsheet", "ods" },
+	{ "application/vnd.oasis.opendocument.spreadsheet-template", "ots" },
+	{ "application/vnd.oasis.opendocument.text", "odt" },
+	{ "application/vnd.oasis.opendocument.text-master", "odm" },
+	{ "application/vnd.oasis.opendocument.text-template", "ott" },
+	{ "application/vnd.oasis.opendocument.text-web", "oth" },
+	{ "application/vnd.olpc-sugar", "xo" },
+	{ "application/vnd.oma.dd2+xml", "dd2" },
+	{ "application/vnd.openofficeorg.extension", "oxt" },
+	{ "application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx" },
+	{ "application/vnd.openxmlformats-officedocument.presentationml.slide", "sldx" },
+	{ "application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx" },
+	{ "application/vnd.openxmlformats-officedocument.presentationml.template", "potx" },
+	{ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx" },
+	{ "application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx" },
+	{ "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx" },
+	{ "application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx" },
+	{ "application/vnd.osgeo.mapguide.package", "mgp" },
+	{ "application/vnd.osgi.dp", "dp" },
+	{ "application/vnd.osgi.subsystem", "esa" },
+	{ "application/vnd.palm", "pdb" },
+	{ "application/vnd.pawaafile", "paw" },
+	{ "application/vnd.pg.format", "str" },
+	{ "application/vnd.pg.osasli", "ei6" },
+	{ "application/vnd.picsel", "efif" },
+	{ "application/vnd.pmi.widget", "wg" },
+	{ "application/vnd.pocketlearn", "plf" },
+	{ "application/vnd.powerbuilder6", "pbd" },
+	{ "application/vnd.previewsystems.box", "box" },
+	{ "application/vnd.proteus.magazine", "mgz" },
+	{ "application/vnd.publishare-delta-tree", "qps" },
+	{ "application/vnd.pvi.ptid1", "ptid" },
+	{ "application/vnd.quark.quarkxpress", "qxd" },
+	{ "application/vnd.realvnc.bed", "bed" },
+	{ "application/vnd.recordare.musicxml", "mxl" },
+	{ "application/vnd.recordare.musicxml+xml", "musicxml" },
+	{ "application/vnd.rig.cryptonote", "cryptonote" },
+	{ "application/vnd.rim.cod", "cod" },
+	{ "application/vnd.rn-realmedia", "rm" },
+	{ "application/vnd.rn-realmedia-vbr", "rmvb" },
+	{ "application/vnd.route66.link66+xml", "link66" },
+	{ "application/vnd.sailingtracker.track", "st" },
+	{ "application/vnd.seemail", "see" },
+	{ "application/vnd.sema", "sema" },
+	{ "application/vnd.semd", "semd" },
+	{ "application/vnd.semf", "semf" },
+	{ "application/vnd.shana.informed.formdata", "ifm" },
+	{ "application/vnd.shana.informed.formtemplate", "itp" },
+	{ "application/vnd.shana.informed.interchange", "iif" },
+	{ "application/vnd.shana.informed.package", "ipk" },
+	{ "application/vnd.simtech-mindmapper", "twd" },
+	{ "application/vnd.smaf", "mmf" },
+	{ "application/vnd.smart.teacher", "teacher" },
+	{ "application/vnd.solent.sdkm+xml", "sdkm" },
+	{ "application/vnd.spotfire.dxp", "dxp" },
+	{ "application/vnd.spotfire.sfs", "sfs" },
+	{ "application/vnd.stardivision.calc", "sdc" },
+	{ "application/vnd.stardivision.draw", "sda" },
+	{ "application/vnd.stardivision.impress", "sdd" },
+	{ "application/vnd.stardivision.math", "smf" },
+	{ "application/vnd.stardivision.writer", "sdw" },
+	{ "application/vnd.stardivision.writer-global", "sgl" },
+	{ "application/vnd.stepmania.package", "smzip" },
+	{ "application/vnd.stepmania.stepchart", "sm" },
+	{ "application/vnd.sun.xml.calc", "sxc" },
+	{ "application/vnd.sun.xml.calc.template", "stc" },
+	{ "application/vnd.sun.xml.draw", "sxd" },
+	{ "application/vnd.sun.xml.draw.template", "std" },
+	{ "application/vnd.sun.xml.impress", "sxi" },
+	{ "application/vnd.sun.xml.impress.template", "sti" },
+	{ "application/vnd.sun.xml.math", "sxm" },
+	{ "application/vnd.sun.xml.writer", "sxw" },
+	{ "application/vnd.sun.xml.writer.global", "sxg" },
+	{ "application/vnd.sun.xml.writer.template", "stw" },
+	{ "application/vnd.sus-calendar", "sus" },
+	{ "application/vnd.svd", "svd" },
+	{ "application/vnd.symbian.install", "sis" },
+	{ "application/vnd.syncml+xml", "xsm" },
+	{ "application/vnd.syncml.dm+wbxml", "bdm" },
+	{ "application/vnd.syncml.dm+xml", "xdm" },
+	{ "application/vnd.tao.intent-module-archive", "tao" },
+	{ "application/vnd.tcpdump.pcap", "pcap" },
+	{ "application/vnd.tmobile-livetv", "tmo" },
+	{ "application/vnd.trid.tpt", "tpt" },
+	{ "application/vnd.triscape.mxs", "mxs" },
+	{ "application/vnd.trueapp", "tra" },
+	{ "application/vnd.ufdl", "ufd" },
+	{ "application/vnd.uiq.theme", "utz" },
+	{ "application/vnd.umajin", "umj" },
+	{ "application/vnd.unity", "unityweb" },
+	{ "application/vnd.uoml+xml", "uoml" },
+	{ "application/vnd.vcx", "vcx" },
+	{ "application/vnd.visio", "vsd" },
+	{ "application/vnd.visionary", "vis" },
+	{ "application/vnd.vsf", "vsf" },
+	{ "application/vnd.wap.wbxml", "wbxml" },
+	{ "application/vnd.wap.wmlc", "wmlc" },
+	{ "application/vnd.wap.wmlscriptc", "wmlsc" },
+	{ "application/vnd.webturbo", "wtb" },
+	{ "application/vnd.wolfram.player", "nbp" },
+	{ "application/vnd.wordperfect", "wpd" },
+	{ "application/vnd.wqd", "wqd" },
+	{ "application/vnd.wt.stf", "stf" },
+	{ "application/vnd.xara", "xar" },
+	{ "application/vnd.xfdl", "xfdl" },
+	{ "application/vnd.yamaha.hv-dic", "hvd" },
+	{ "application/vnd.yamaha.hv-script", "hvs" },
+	{ "application/vnd.yamaha.hv-voice", "hvp" },
+	{ "application/vnd.yamaha.openscoreformat", "osf" },
+	{ "application/vnd.yamaha.openscoreformat.osfpvg+xml", "osfpvg" },
+	{ "application/vnd.yamaha.smaf-audio", "saf" },
+	{ "application/vnd.yamaha.smaf-phrase", "spf" },
+	{ "application/vnd.yellowriver-custom-menu", "cmp" },
+	{ "application/vnd.zul", "zir" },
+	{ "application/vnd.zzazz.deck+xml", "zaz" },
+	{ "application/voicexml+xml", "vxml" },
+	{ "application/widget", "wgt" },
+	{ "application/winhlp", "hlp" },
+	{ "application/wsdl+xml", "wsdl" },
+	{ "application/wspolicy+xml", "wspolicy" },
+	{ "application/x-7z-compressed", "7z" },
+	{ "application/x-abiword", "abw" },
+	{ "application/x-ace-compressed", "ace" },
+	{ "application/x-apple-diskimage", "dmg" },
+	{ "application/x-authorware-bin", "aab" },
+	{ "application/x-authorware-map", "aam" },
+	{ "application/x-authorware-seg", "aas" },
+	{ "application/x-bcpio", "bcpio" },
+	{ "application/x-bittorrent", "torrent" },
+	{ "application/x-blorb", "blb" },
+	{ "application/x-bzip", "bz" },
+	{ "application/x-bzip2", "bz2" },
+	{ "application/x-cbr", "cbr" },
+	{ "application/x-cdlink", "vcd" },
+	{ "application/x-cfs-compressed", "cfs" },
+	{ "application/x-chat", "chat" },
+	{ "application/x-chess-pgn", "pgn" },
+	{ "application/x-conference", "nsc" },
+	{ "application/x-cpio", "cpio" },
+	{ "application/x-csh", "csh" },
+	{ "application/x-debian-package", "deb" },
+	{ "application/x-dgc-compressed", "dgc" },
+	{ "application/x-director", "dir" },
+	{ "application/x-doom", "wad" },
+	{ "application/x-dtbncx+xml", "ncx" },
+	{ "application/x-dtbook+xml", "dtb" },
+	{ "application/x-dtbresource+xml", "res" },
+	{ "application/x-dvi", "dvi" },
+	{ "application/x-envoy", "evy" },
+	{ "application/x-eva", "eva" },
+	{ "application/x-font-bdf", "bdf" },
+	{ "application/x-font-ghostscript", "gsf" },
+	{ "application/x-font-linux-psf", "psf" },
+	{ "application/x-font-otf", "otf" },
+	{ "application/x-font-pcf", "pcf" },
+	{ "application/x-font-snf", "snf" },
+	{ "application/x-font-ttf", "ttf" },
+	{ "application/x-font-type1", "pfa" },
+	{ "application/font-woff", "woff" },
+	{ "application/x-freearc", "arc" },
+	{ "application/x-futuresplash", "spl" },
+	{ "application/x-gca-compressed", "gca" },
+	{ "application/x-glulx", "ulx" },
+	{ "application/x-gnumeric", "gnumeric" },
+	{ "application/x-gramps-xml", "gramps" },
+	{ "application/x-gtar", "gtar" },
+	{ "application/x-hdf", "hdf" },
+	{ "application/x-install-instructions", "install" },
+	{ "application/x-iso9660-image", "iso" },
+	{ "application/x-java-jnlp-file", "jnlp" },
+	{ "application/x-latex", "latex" },
+	{ "application/x-lzh-compressed", "lzh" },
+	{ "application/x-mie", "mie" },
+	{ "application/x-mobipocket-ebook", "prc" },
+	{ "application/x-ms-application", "application" },
+	{ "application/x-ms-shortcut", "lnk" },
+	{ "application/x-ms-wmd", "wmd" },
+	{ "application/x-ms-wmz", "wmz" },
+	{ "application/x-ms-xbap", "xbap" },
+	{ "application/x-msaccess", "mdb" },
+	{ "application/x-msbinder", "obd" },
+	{ "application/x-mscardfile", "crd" },
+	{ "application/x-msclip", "clp" },
+	{ "application/x-msdownload", "exe" },
+	{ "application/x-msmediaview", "mvb" },
+	{ "application/x-msmetafile", "wmf" },
+	{ "application/x-msmoney", "mny" },
+	{ "application/x-mspublisher", "pub" },
+	{ "application/x-msschedule", "scd" },
+	{ "application/x-msterminal", "trm" },
+	{ "application/x-mswrite", "wri" },
+	{ "application/x-netcdf", "nc" },
+	{ "application/x-nzb", "nzb" },
+	{ "application/x-pkcs12", "p12" },
+	{ "application/x-pkcs7-certificates", "p7b" },
+	{ "application/x-pkcs7-certreqresp", "p7r" },
+	{ "application/x-rar-compressed", "rar" },
+	{ "application/x-research-info-systems", "ris" },
+	{ "application/x-sh", "sh" },
+	{ "application/x-shar", "shar" },
+	{ "application/x-shockwave-flash", "swf" },
+	{ "application/x-silverlight-app", "xap" },
+	{ "application/x-sql", "sql" },
+	{ "application/x-stuffit", "sit" },
+	{ "application/x-stuffitx", "sitx" },
+	{ "application/x-subrip", "srt" },
+	{ "application/x-sv4cpio", "sv4cpio" },
+	{ "application/x-sv4crc", "sv4crc" },
+	{ "application/x-t3vm-image", "t3" },
+	{ "application/x-tads", "gam" },
+	{ "application/x-tar", "tar" },
+	{ "application/x-tcl", "tcl" },
+	{ "application/x-tex", "tex" },
+	{ "application/x-tex-tfm", "tfm" },
+	{ "application/x-texinfo", "texinfo" },
+	{ "application/x-tgif", "obj" },
+	{ "application/x-ustar", "ustar" },
+	{ "application/x-wais-source", "src" },
+	{ "application/x-x509-ca-cert", "der" },
+	{ "application/x-xfig", "fig" },
+	{ "application/x-xliff+xml", "xlf" },
+	{ "application/x-xpinstall", "xpi" },
+	{ "application/x-xz", "xz" },
+	{ "application/x-zmachine", "z1" },
+	{ "application/xaml+xml", "xaml" },
+	{ "application/xcap-diff+xml", "xdf" },
+	{ "application/xenc+xml", "xenc" },
+	{ "application/xhtml+xml", "xhtml" },
+	{ "application/xml", "xml" },
+	{ "application/xml-dtd", "dtd" },
+	{ "application/xop+xml", "xop" },
+	{ "application/xproc+xml", "xpl" },
+	{ "application/xslt+xml", "xslt" },
+	{ "application/xspf+xml", "xspf" },
+	{ "application/xv+xml", "mxml" },
+	{ "application/yang", "yang" },
+	{ "application/yin+xml", "yin" },
+	{ "application/zip", "zip" },
+	{ "audio/adpcm", "adp" },
+	{ "audio/basic", "au" },
+	{ "audio/midi", "mid" },
+	{ "audio/mp4", "mp4a" },
+	{ "audio/mpeg", "mpga" },
+	{ "audio/ogg", "oga" },
+	{ "audio/s3m", "s3m" },
+	{ "audio/silk", "sil" },
+	{ "audio/vnd.dece.audio", "uva" },
+	{ "audio/vnd.digital-winds", "eol" },
+	{ "audio/vnd.dra", "dra" },
+	{ "audio/vnd.dts", "dts" },
+	{ "audio/vnd.dts.hd", "dtshd" },
+	{ "audio/vnd.lucent.voice", "lvp" },
+	{ "audio/vnd.ms-playready.media.pya", "pya" },
+	{ "audio/vnd.nuera.ecelp4800", "ecelp4800" },
+	{ "audio/vnd.nuera.ecelp7470", "ecelp7470" },
+	{ "audio/vnd.nuera.ecelp9600", "ecelp9600" },
+	{ "audio/vnd.rip", "rip" },
+	{ "audio/webm", "weba" },
+	{ "audio/x-aac", "aac" },
+	{ "audio/x-aiff", "aif" },
+	{ "audio/x-caf", "caf" },
+	{ "audio/x-flac", "flac" },
+	{ "audio/x-matroska", "mka" },
+	{ "audio/x-mpegurl", "m3u" },
+	{ "audio/x-ms-wax", "wax" },
+	{ "audio/x-ms-wma", "wma" },
+	{ "audio/x-pn-realaudio", "ram" },
+	{ "audio/x-pn-realaudio-plugin", "rmp" },
+	{ "audio/x-wav", "wav" },
+	{ "audio/xm", "xm" },
+	{ "chemical/x-cdx", "cdx" },
+	{ "chemical/x-cif", "cif" },
+	{ "chemical/x-cmdf", "cmdf" },
+	{ "chemical/x-cml", "cml" },
+	{ "chemical/x-csml", "csml" },
+	{ "chemical/x-xyz", "xyz" },
+	{ "image/bmp", "bmp" },
+	{ "image/cgm", "cgm" },
+	{ "image/g3fax", "g3" },
+	{ "image/gif", "gif" },
+	{ "image/ief", "ief" },
+	{ "image/jpg", "jpg" },
+	{ "image/jpeg", "jpeg" },
+	{ "image/ktx", "ktx" },
+	{ "image/png", "png" },
+	{ "image/prs.btif", "btif" },
+	{ "image/sgi", "sgi" },
+	{ "image/svg+xml", "svg" },
+	{ "image/tiff", "tiff" },
+	{ "image/vnd.adobe.photoshop", "psd" },
+	{ "image/vnd.dece.graphic", "uvi" },
+	{ "image/vnd.dvb.subtitle", "sub" },
+	{ "image/vnd.djvu", "djvu" },
+	{ "image/vnd.dwg", "dwg" },
+	{ "image/vnd.dxf", "dxf" },
+	{ "image/vnd.fastbidsheet", "fbs" },
+	{ "image/vnd.fpx", "fpx" },
+	{ "image/vnd.fst", "fst" },
+	{ "image/vnd.fujixerox.edmics-mmr", "mmr" },
+	{ "image/vnd.fujixerox.edmics-rlc", "rlc" },
+	{ "image/vnd.ms-modi", "mdi" },
+	{ "image/vnd.ms-photo", "wdp" },
+	{ "image/vnd.net-fpx", "npx" },
+	{ "image/vnd.wap.wbmp", "wbmp" },
+	{ "image/vnd.xiff", "xif" },
+	{ "image/webp", "webp" },
+	{ "image/x-3ds", "3ds" },
+	{ "image/x-cmu-raster", "ras" },
+	{ "image/x-cmx", "cmx" },
+	{ "image/x-freehand", "fh" },
+	{ "image/x-icon", "ico" },
+	{ "image/x-mrsid-image", "sid" },
+	{ "image/x-pcx", "pcx" },
+	{ "image/x-pict", "pic" },
+	{ "image/x-portable-anymap", "pnm" },
+	{ "image/x-portable-bitmap", "pbm" },
+	{ "image/x-portable-graymap", "pgm" },
+	{ "image/x-portable-pixmap", "ppm" },
+	{ "image/x-rgb", "rgb" },
+	{ "image/x-tga", "tga" },
+	{ "image/x-xbitmap", "xbm" },
+	{ "image/x-xpixmap", "xpm" },
+	{ "image/x-xwindowdump", "xwd" },
+	{ "message/rfc822", "eml" },
+	{ "model/iges", "igs" },
+	{ "model/mesh", "msh" },
+	{ "model/vnd.collada+xml", "dae" },
+	{ "model/vnd.dwf", "dwf" },
+	{ "model/vnd.gdl", "gdl" },
+	{ "model/vnd.gtw", "gtw" },
+	{ "model/vnd.mts", "mts" },
+	{ "model/vnd.vtu", "vtu" },
+	{ "model/vrml", "wrl" },
+	{ "model/x3d+binary", "x3db" },
+	{ "model/x3d+vrml", "x3dv" },
+	{ "model/x3d+xml", "x3d" },
+	{ "text/cache-manifest", "appcache" },
+	{ "text/calendar", "ics" },
+	{ "text/css", "css" },
+	{ "text/csv", "csv" },
+	{ "text/html", "html" },
+	{ "text/n3", "n3" },
+	{ "text/plain", "txt" },
+	{ "text/prs.lines.tag", "dsc" },
+	{ "text/richtext", "rtx" },
+	{ "text/sgml", "sgml" },
+	{ "text/tab-separated-values", "tsv" },
+	{ "text/troff", "t" },
+	{ "text/turtle", "ttl" },
+	{ "text/uri-list", "uri" },
+	{ "text/vcard", "vcard" },
+	{ "text/vnd.curl", "curl" },
+	{ "text/vnd.curl.dcurl", "dcurl" },
+	{ "text/vnd.curl.scurl", "scurl" },
+	{ "text/vnd.curl.mcurl", "mcurl" },
+	{ "text/vnd.dvb.subtitle", "sub" },
+	{ "text/vnd.fly", "fly" },
+	{ "text/vnd.fmi.flexstor", "flx" },
+	{ "text/vnd.graphviz", "gv" },
+	{ "text/vnd.in3d.3dml", "3dml" },
+	{ "text/vnd.in3d.spot", "spot" },
+	{ "text/vnd.sun.j2me.app-descriptor", "jad" },
+	{ "text/vnd.wap.wml", "wml" },
+	{ "text/vnd.wap.wmlscript", "wmls" },
+	{ "text/x-asm", "s" },
+	{ "text/x-c", "c" },
+	{ "text/x-fortran", "f" },
+	{ "text/x-java-source", "java" },
+	{ "text/x-opml", "opml" },
+	{ "text/x-pascal", "p" },
+	{ "text/x-nfo", "nfo" },
+	{ "text/x-setext", "etx" },
+	{ "text/x-sfv", "sfv" },
+	{ "text/x-uuencode", "uu" },
+	{ "text/x-vcalendar", "vcs" },
+	{ "text/x-vcard", "vcf" },
+	{ "text/xml", "xml" },
+	{ "video/3gpp", "3gp" },
+	{ "video/3gpp2", "3g2" },
+	{ "video/h261", "h261" },
+	{ "video/h263", "h263" },
+	{ "video/h264", "h264" },
+	{ "video/jpeg", "jpgv" },
+	{ "video/jpm", "jpm" },
+	{ "video/mj2", "mj2" },
+	{ "video/mp4", "mp4" },
+	{ "video/mpeg", "mpeg" },
+	{ "video/ogg", "ogv" },
+	{ "video/quicktime", "qt" },
+	{ "video/vnd.dece.hd", "uvh" },
+	{ "video/vnd.dece.mobile", "uvm" },
+	{ "video/vnd.dece.pd", "uvp" },
+	{ "video/vnd.dece.sd", "uvs" },
+	{ "video/vnd.dece.video", "uvv" },
+	{ "video/vnd.dvb.file", "dvb" },
+	{ "video/vnd.fvt", "fvt" },
+	{ "video/vnd.mpegurl", "mxu" },
+	{ "video/vnd.ms-playready.media.pyv", "pyv" },
+	{ "video/vnd.uvvu.mp4", "uvu" },
+	{ "video/vnd.vivo", "viv" },
+	{ "video/webm", "webm" },
+	{ "video/x-f4v", "f4v" },
+	{ "video/x-fli", "fli" },
+	{ "video/x-flv", "flv" },
+	{ "video/x-m4v", "m4v" },
+	{ "video/x-matroska", "mkv" },
+	{ "video/x-mng", "mng" },
+	{ "video/x-ms-asf", "asf" },
+	{ "video/x-ms-vob", "vob" },
+	{ "video/x-ms-wm", "wm" },
+	{ "video/x-ms-wmv", "wmv" },
+	{ "video/x-ms-wmx", "wmx" },
+	{ "video/x-ms-wvx", "wvx" },
+	{ "video/x-msvideo", "avi" },
+	{ "video/x-sgi-movie", "movie" },
+	{ "video/x-smv", "smv" },
+	{ "x-conference/x-cooltalk", "ice" }
+};
+
+/**
+* Obtain default file extension for a give MIME type
+*
+* @param mimeType a MIME type (lowercase string), e.g. "image/png"
+* @param extension a buffer in which to store the file extension; the default value is "txt" if no extension is found
+* @param length the size of the buffer extension
+* @return true if a file extension is found for the given MIME type, otherwise false
+*/
+static bool getFileExtension(const char* mimeType, char* extension, size_t length) {
+
+	bool hasExt = false;
+	strncpy(extension, "txt", length);
+	
+	if (mimeType != NULL) { 	
+		for (int i = 0; i < NUM_MIME_TYPES; i++) {					
+			if 	(strncmp(mimeType, MIME[i][M_Type], strlen(MIME[i][M_Type])) == 0) {
+				strncpy(extension, MIME[i][M_Extension], length);
+				hasExt = true;
+				break;				
+			}		
+		}
+		if (hasExt == false && strncmp(mimeType, "image/", 6) == 0) {
+			strncpy(extension, strstr(mimeType, "/") + 1, length);
+		}	
+	}	
+	return hasExt;
+}
+
+/**
+* Obtain default file extension for a give MIME type
+*
+* @param mimeType a MIME type (lowercase string), e.g. "image/png"
+* @param hasExt the value of this pointer is set to true if a default file extension is found, otherwise false
+* @return a map with name "extension" and value set to file extension, e.g. "png"; if not found the default value is "txt" 
+*/
+static map* getFileExtensionMap(const char* mimeType, bool* hasExt) {
+
+	map* ext = createMap("extension", "txt");
+	*hasExt = false;
+	
+	if (mimeType != NULL) { 	
+		for (int i = 0; i < NUM_MIME_TYPES; i++) {			
+			if 	(strncmp(mimeType, MIME[i][M_Type], strlen(MIME[i][M_Type])) == 0) {
+				ext->value = zStrdup(MIME[i][M_Extension]);
+				*hasExt = true;
+				break;				
+			}		
+		}
+		if (*hasExt == false && strncmp(mimeType, "image/", 6) == 0) {
+			ext->value = zStrdup(strstr(mimeType, "/") + 1);
+		}			
+	}	
+	return ext;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/nmake.opt
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/nmake.opt	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/nmake.opt	(revision 672)
@@ -0,0 +1,69 @@
+PROGRAMNAME=zoo_loader.cgi
+
+CC=cl $(CFLAGS)
+CPP=cl /TP $(CFLAGS)
+
+!IF DEFINED(MS_DIR)
+MS_BASE=$(MS_DIR)
+!INCLUDE $(MS_DIR)\nmake.opt
+!ENDIF
+
+!IFDEF JS_DIR
+JS_CFLAGS=-DXP_WIN -DUSE_JS -I$(JS_DIR)
+JS_LDFLAGS=$(JS_DIR)/mozjs185-1.0.lib
+JS_FILE=service_internal_js.obj
+!ENDIF
+
+!IFDEF MS_DIR
+MS_CFLAGS=-DUSE_MS -I$(MS_DIR)
+MS_LDFLAGS=$(MS_DIR)/mapserver_i.lib
+MS_FILE=service_internal_ms.obj
+!ENDIF
+
+!IFDEF JDK_DIR
+JAVA_CFLAGS=-DJAVA7 -DUSE_JAVA -I"$(JDK_DIR)\include" -I"$(JDK_DIR)\include\win32"
+JAVA_LDFLAGS="$(JDK_DIR)/lib/jvm.lib"
+JAVA_FILE=service_internal_java.obj
+!ENDIF
+
+!IFDEF PY_DIR
+PY_CFLAGS=-DUSE_PYTHON -I$(PY_DIR)\Include -I$(PY_DIR)\PC
+PY_LDFLAGS=$(PY_LIBRARY) 
+PY_FILE=service_internal_python.obj
+!ENDIF
+
+!IFDEF RUBY_DIR
+#################################################################
+#RUBY 1.8.7
+ZRUBY_VERSION=1
+RUBY_CFLAGS=-DZRUBY_VERSION=1 -DUSE_RUBY -I$(RUBY_DIR) 
+RUBY_LDFLAGS="$(RUBY_DIR)/msvcr100-ruby18.lib"
+#################################################################
+#RUBY 1.9.3
+#ZRUBY_VERSION=2
+#RUBY_CFLAGS=-DZRUBY_VERSION=2 -DUSE_RUBY -I$(RUBY_DIR)/include/ruby-1.9.1/ -I$(RUBY_DIR)/include/ruby-1.9.1/i386-mswin32_100
+#RUBY_LDFLAGS="$(RUBY_DIR)/lib/msvcr100-ruby191.lib"
+#RUBY 2.1.0
+#ZRUBY_VERSION=2
+#RUBY_CFLAGS=-DZRUBY_VERSION=2 -DUSE_RUBY -I$(RUBY_DIR)/include/ruby-2.1.0/ -I$(RUBY_DIR)/include/ruby-2.1.0/i386-mswin32_100
+#RUBY_LDFLAGS="$(RUBY_DIR)/lib/msvcr100-ruby210.lib"
+#################################################################
+RUBY_FILE=service_internal_ruby.obj
+!IFDEF MS_DIR
+RUBY_CFLAGS=$(RUBY_CFLAGS) -DHAVE_ROUND
+!ENDIF
+!ENDIF
+
+!IFNDEF ZOOK_DIR
+ZOOK_DIR=.
+!ENDIF
+
+TROOT=$(ZOOK_DIR)
+TPATH=$(ZOOK_DIR)\..\..\..\tools
+LIBINTL_CPATH=$(ZOOK_DIR)\..\..\..\
+PYTHON_CPATH=$(PY_DIR)
+
+CFLAGS= $(MS_DEFS) $(INCLUDES) $(CFLAGS1) /nologo /MD /W3 /EHsc /Ox /D_CRT_SECURE_NO_WARNINGS /DWIN32 /DPROGRAMNAME=\"$(PROGRAMNAME)\" $(CJFLAGS) -I$(ZOOK_DIR) $(RUBY_CFLAGS) -I./ $(JAVA_CFLAGS) $(MS_CFLAGS) -I$(TROOT)\..\..\thirds\dirent-win32 -I$(INTL_DIR) -I$(CURL_DIR)\include -I$(XML2_DIR)\include -I$(GDAL_DIR)\port $(JS_CFLAGS) -I$(GDAL_DIR)\ogr -I$(GDAL_DIR)\gcore -I$(GD_DIR) -I$(ICONV_DIR) -I$(TROOT)\..\..\thirds\include -I$(TROOT)\..\..\thirds\cgic206 -I$(PYTHON_CPATH)\include -I$(SSL_DIR)/inc32 -I$(FCGI_DIR)\include $(PY_CFLAGS) -DLINUX_FREE_ISSUE #-DDEBUG #-DDEBUG_SERVICE_CONF
+
+LDFLAGSCGI=$(TROOT)/../../thirds/cgic206/libcgic.lib 
+LDFLAGS=$(FCGI_DIR)/libfcgi/Release/libfcgi.lib $(CURL_LIBRARY) $(PY_LDFLAGS) $(XML2_LIBRARY) $(SSL_DIR)/out32dll/libeay32.lib $(JAVA_LDFLAGS) $(SSL_DIR)/out32dll/ssleay32.lib $(MS_LDFLAGS) $(INTL_DIR)/intl.lib $(XML2_DIR)/win32/bin.msvc/libxml2.lib $(GDAL_DIR)/gdal_i.lib $(CURL_DIR)/lib/libcurl.lib $(JS_LDFLAGS) $(RUBY_LDFLAGS) /machine:i386
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.cxx
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.cxx	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.cxx	(revision 672)
@@ -0,0 +1,70 @@
+/*=========================================================================
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Some parts of this code are derived from ITK. See ITKCopyright.txt
+  for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+  See Ref: http://hg.orfeo-toolbox.org/OTB/ Copyright
+
+=========================================================================*/
+#include "otbZooWatcher.h"
+#include "service_internal.h"
+
+ZooWatcher
+::ZooWatcher()
+{
+}
+
+ZooWatcher
+::ZooWatcher(itk::ProcessObject* process,
+	     const char *comment)
+  : otb::FilterWatcherBase(process, comment)
+{
+}
+
+ZooWatcher
+::ZooWatcher(itk::ProcessObject* process,
+	     const std::string& comment)
+  : otb::FilterWatcherBase(process, comment.c_str())
+{
+}
+
+void
+ZooWatcher
+::ShowProgress()
+{
+  if (m_Process)
+    {
+      int progressPercent = static_cast<int>(m_Process->GetProgress() * 100);
+      updateStatus(m_Conf,progressPercent,m_Comment.c_str());
+    }
+}
+
+void
+ZooWatcher
+::StartFilter()
+{
+  m_TimeProbe.Start();
+}
+
+void
+ZooWatcher
+::EndFilter()
+{
+  m_TimeProbe.Stop();
+  std::ostringstream elapsedTime;
+  elapsedTime.precision(1);
+  elapsedTime << m_TimeProbe.GetMean();
+
+  std::cerr << " (OTB Execution: "
+            << elapsedTime.str()
+            << " seconds)"
+            << std::endl;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/otbZooWatcher.h	(revision 672)
@@ -0,0 +1,91 @@
+/*=========================================================================
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Some parts of this code are derived from ITK. See ITKCopyright.txt
+  for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+  See Ref: http://hg.orfeo-toolbox.org/OTB/ Copyright
+
+=========================================================================*/
+#ifndef __zooOtbWatcher_h
+#define __zooOtbWatcher_h
+
+#include "otbFilterWatcherBase.h"
+#include "service.h"
+
+/**
+ * Observer used to access the ongoing status of a running OTB Application
+ */
+class /*ITK_EXPORT*/ ZooWatcher : public otb::FilterWatcherBase
+{
+public:
+
+  /**
+   * Constructor
+   * @param process the itk::ProcessObject to monitor
+   * @param comment comment string that is prepended to each event message
+   */
+  ZooWatcher(itk::ProcessObject* process,
+                        const char *comment = "");
+
+  /**
+   * Constructor
+   * @param process the itk::ProcessObject to monitor
+   * @param comment comment string that is prepended to each event message
+   */
+  ZooWatcher(itk::ProcessObject* process,
+                        const std::string& comment = "");
+
+  /** Default constructor */
+  ZooWatcher();
+
+  /** 
+   * Copy the original conf in the m_Conf property
+   *
+   * @param conf the maps pointer to copy
+   */
+  void SetConf(maps **conf)
+  {
+    m_Conf=dupMaps(conf);
+  }
+  /**  
+   * Get Configuration maps (m_Conf)
+   * @return the m_Conf property
+   */
+  const maps& GetConf() const
+  {
+    return *m_Conf;
+  }
+  /**  
+   * Free Configuration maps (m_Conf)
+   */
+  void FreeConf(){
+    freeMaps(&m_Conf);
+    free(m_Conf);
+  }
+protected:
+
+  /** Callback method to show the ProgressEvent */
+  virtual void ShowProgress();
+
+  /** Callback method to show the StartEvent */
+  virtual void StartFilter();
+
+  /** Callback method to show the EndEvent */
+  virtual void EndFilter();
+
+private:
+
+  /** Main conf maps */
+  maps* m_Conf;
+
+};
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.c	(revision 672)
@@ -0,0 +1,1764 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "request_parser.h"
+#include "service_internal.h"
+#include "server_internal.h"
+#include "response_print.h"
+#include "caching.h"
+
+/**
+ * Apply XPath Expression on XML document.
+ *
+ * @param doc the XML Document
+ * @param search the XPath expression
+ * @return xmlXPathObjectPtr containing the resulting nodes set
+ */
+xmlXPathObjectPtr
+extractFromDoc (xmlDocPtr doc, const char *search)
+{
+  xmlXPathContextPtr xpathCtx;
+  xmlXPathObjectPtr xpathObj;
+  xpathCtx = xmlXPathNewContext (doc);
+  xpathObj = xmlXPathEvalExpression (BAD_CAST search, xpathCtx);
+  xmlXPathFreeContext (xpathCtx);
+  return xpathObj;
+}
+
+/**
+ * Create (or append to) an array valued maps value = "["",""]"
+ *
+ * @param m the conf maps containing the main.cfg settings
+ * @param mo the map to update
+ * @param mi the map to append
+ * @param elem the elements containing default definitions
+ * @return 0 on success, -1 on failure
+ */
+int appendMapsToMaps (maps * m, maps * mo, maps * mi, elements * elem){
+  maps *tmpMaps = getMaps (mo, mi->name);
+  map *tmap = getMapType (tmpMaps->content);
+  elements *el = getElements (elem, mi->name);
+  int hasEl = 1;
+  if (el == NULL)
+    hasEl = -1;
+  if (tmap == NULL)
+    {
+      if (hasEl > 0)
+	tmap = getMapType (el->defaults->content);
+    }
+  
+  map *testMap = NULL;
+  if (hasEl > 0)
+    {
+      testMap = getMap (el->content, "maxOccurs");
+    }
+  else
+    {
+      testMap = createMap ("maxOccurs", "unbounded");
+    }
+    
+  if (testMap != NULL)
+    {
+      if (strncasecmp (testMap->value, "unbounded", 9) != 0
+	  && atoi (testMap->value) > 1)
+	{
+	  addMapsArrayToMaps (&mo, mi, tmap->name);
+	  map* nb=getMapFromMaps(mo,mi->name,"length");
+	  if (nb!=NULL && atoi(nb->value)>atoi(testMap->value))
+	    {
+	      char emsg[1024];
+	      sprintf (emsg,
+		       _("The maximum allowed occurrences for <%s> (%i) was exceeded."),
+		       mi->name, atoi (testMap->value));
+	      errorException (m, emsg, "InternalError", NULL);
+	      return -1;
+	    }
+	}
+      else
+	{
+	  if (strncasecmp (testMap->value, "unbounded", 9) == 0)
+	    {
+	      if (hasEl < 0)
+		{
+		  freeMap (&testMap);
+		  free (testMap);
+		}
+	      if (addMapsArrayToMaps (&mo, mi, tmap->name) < 0)
+		{
+		  char emsg[1024];
+		  map *tmpMap = getMap (mi->content, "length");
+		  sprintf (emsg,
+			   _
+			   ("ZOO-Kernel was unable to load your data for %s position %s."),
+			   mi->name, tmpMap->value);
+		  errorException (m, emsg, "InternalError", NULL);
+		  return -1;
+		}
+	    }
+	  else
+	    {
+	      char emsg[1024];
+	      sprintf (emsg,
+		       _
+		       ("The maximum allowed occurrences for <%s> is one."),
+		       mi->name);
+	      errorException (m, emsg, "InternalError", NULL);
+	      return -1;
+	    }
+	}
+    }
+  return 0;
+}
+
+/**
+ * Make sure that each value encoded in base64 in a maps is decoded.
+ *
+ * @param in the maps containing the values
+ * @see readBase64
+ */
+void ensureDecodedBase64(maps **in){
+  maps* cursor=*in;
+  while(cursor!=NULL){
+    map *tmp=getMap(cursor->content,"encoding");
+    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
+      tmp=getMap(cursor->content,"value");
+      readBase64(&tmp);
+      addToMap(cursor->content,"base64_value",tmp->value);
+      int size=0;
+      char *s=strdup(tmp->value);
+      free(tmp->value);
+      tmp->value=base64d(s,strlen(s),&size);
+      free(s);
+      char sizes[1024];
+      sprintf(sizes,"%d",size);
+      addToMap(cursor->content,"size",sizes);
+    }
+    map* length=getMap(cursor->content,"length");
+    if(length!=NULL){
+      int len=atoi(length->value);
+      for(int i=1;i<len;i++){
+	tmp=getMapArray(cursor->content,"encoding",i);
+	if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
+	  char key[17];
+	  sprintf(key,"base64_value_%d",i);
+	  tmp=getMapArray(cursor->content,"value",i);
+	  readBase64(&tmp);
+	  addToMap(cursor->content,key,tmp->value);
+	  int size=0;
+	  char *s=strdup(tmp->value);
+	  free(tmp->value);
+	  tmp->value=base64d(s,strlen(s),&size);
+	  free(s);
+	  char sizes[1024];
+	  sprintf(sizes,"%d",size);
+	  sprintf(key,"size_%d",i);
+	  addToMap(cursor->content,key,sizes);
+	}
+      }
+    }
+    cursor=cursor->next;
+  }
+}
+
+/**
+ * Parse inputs provided as KVP and store them in a maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param s the service
+ * @param request_inputs the map storing KVP raw value 
+ * @param request_output the maps to store the KVP pairs 
+ * @param hInternet the HINTERNET queue to add potential requests
+ * @return 0 on success, -1 on failure
+ */
+int kvpParseInputs(maps** main_conf,service* s,map *request_inputs,maps** request_output,HINTERNET* hInternet){
+  // Parsing inputs provided as KVP
+  maps *tmpmaps = *request_output;
+  map* r_inputs = getMap (request_inputs, "DataInputs");
+  char* cursor_input;
+  if (r_inputs != NULL){
+    //snprintf (cursor_input, 40960, "%s", r_inputs->value);
+    if(strstr(r_inputs->value,"=")==NULL)
+      cursor_input = url_decode (r_inputs->value);
+    else
+      cursor_input = zStrdup (r_inputs->value);
+    int j = 0;
+
+    // Put each DataInputs into the inputs_as_text array
+    char *pToken;
+    pToken = strtok (cursor_input, ";");
+    char **inputs_as_text = (char **) malloc (100 * sizeof (char *));
+    if (inputs_as_text == NULL)
+      {
+	free(cursor_input);
+	return errorException (*main_conf, _("Unable to allocate memory."),
+			       "InternalError", NULL);
+      }
+    int i = 0;
+    while (pToken != NULL)
+      {
+	inputs_as_text[i] =
+	  (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
+	if (inputs_as_text[i] == NULL)
+	  {
+	    free(cursor_input);
+	    return errorException (*main_conf, _("Unable to allocate memory."),
+				   "InternalError", NULL);
+	  }
+	snprintf (inputs_as_text[i], strlen (pToken) + 1, "%s", pToken);
+	pToken = strtok (NULL, ";");
+	i++;
+      }
+	
+    for (j = 0; j < i; j++)
+      {
+	char *tmp = zStrdup (inputs_as_text[j]);
+	free (inputs_as_text[j]);
+	char *tmpc;
+	tmpc = strtok (tmp, "@");
+	while (tmpc != NULL)
+	  {
+	    char *tmpv = strstr (tmpc, "=");
+	    char tmpn[256];
+	    memset (tmpn, 0, 256);
+	    if (tmpv != NULL)
+	      {
+		strncpy (tmpn, tmpc,
+			 (strlen (tmpc) - strlen (tmpv)) * sizeof (char));
+		tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
+	      }
+	    else
+	      {
+		strncpy (tmpn, tmpc, strlen (tmpc) * sizeof (char));
+		tmpn[strlen (tmpc)] = 0;
+	      }
+	    if (tmpmaps == NULL)
+	      {
+		tmpmaps = (maps *) malloc (MAPS_SIZE);
+		if (tmpmaps == NULL)
+		  {
+		    free(cursor_input);
+		    return errorException (*main_conf,
+					   _("Unable to allocate memory."),
+					   "InternalError", NULL);
+		  }
+		tmpmaps->name = zStrdup (tmpn);
+		if (tmpv != NULL)
+		  {
+		    char *tmpvf = url_decode (tmpv + 1);
+		    tmpmaps->content = createMap ("value", tmpvf);
+		    free (tmpvf);
+		  }
+		else
+		  tmpmaps->content = createMap ("value", "Reference");
+		tmpmaps->next = NULL;
+	      }
+	    tmpc = strtok (NULL, "@");
+	    while (tmpc != NULL)
+	      {
+		char *tmpv1 = strstr (tmpc, "=");
+		char tmpn1[1024];
+		memset (tmpn1, 0, 1024);
+		if (tmpv1 != NULL)
+		  {
+		    strncpy (tmpn1, tmpc, strlen (tmpc) - strlen (tmpv1));
+		    tmpn1[strlen (tmpc) - strlen (tmpv1)] = 0;
+		    addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
+		  }
+		else
+		  {
+		    strncpy (tmpn1, tmpc, strlen (tmpc));
+		    tmpn1[strlen (tmpc)] = 0;
+		    map *lmap = getLastMap (tmpmaps->content);
+		    char *tmpValue =
+		      (char *) malloc ((strlen (tmpv) + strlen (tmpc) + 1) *
+				       sizeof (char));
+		    sprintf (tmpValue, "%s@%s", tmpv + 1, tmpc);
+		    free (lmap->value);
+		    lmap->value = zStrdup (tmpValue);
+		    free (tmpValue);
+		    tmpc = strtok (NULL, "@");
+		    continue;
+		  }
+		if (strcmp (tmpn1, "xlink:href") != 0)
+		  addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
+		else if (tmpv1 != NULL)
+		  {
+		    char *tmpx2 = url_decode (tmpv1 + 1);
+		    if (strncasecmp (tmpx2, "http://", 7) != 0 &&
+			strncasecmp (tmpx2, "ftp://", 6) != 0 &&
+			strncasecmp (tmpx2, "https://", 8) != 0)
+		      {
+			char emsg[1024];
+			sprintf (emsg,
+				 _
+				 ("Unable to find a valid protocol to download the remote file %s"),
+				 tmpv1 + 1);
+			free(cursor_input);
+			return errorException (*main_conf, emsg, "InternalError", NULL);
+		      }
+		    addToMap (tmpmaps->content, tmpn1, tmpx2);
+		    {
+		      if (loadRemoteFile
+			  (&*main_conf, &tmpmaps->content, hInternet, tmpx2) < 0)
+			{
+			  free(cursor_input);
+			  return errorException (*main_conf, "Unable to fetch any ressource", "InternalError", NULL);
+			}
+		      }
+		    free (tmpx2);
+		    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
+		    addToMap (tmpmaps->content, "Reference", tmpv1 + 1);
+		  }
+		tmpc = strtok (NULL, "@");
+	      }
+	    if (*request_output == NULL)
+	      *request_output = dupMaps (&tmpmaps);
+	    else
+	      {
+		maps *testPresence =
+		  getMaps (*request_output, tmpmaps->name);
+		if (testPresence != NULL)
+		  {
+		    elements *elem =
+		      getElements (s->inputs, tmpmaps->name);
+		    if (elem != NULL)
+		      {
+			if (appendMapsToMaps
+			    (*main_conf, *request_output, tmpmaps,
+			     elem) < 0)
+			  {
+			    free(cursor_input);
+			    return errorException (*main_conf, "Unable to append maps", "InternalError", NULL);
+			  }
+		      }
+		  }
+		else
+		  addMapsToMaps (request_output, tmpmaps);
+	      }
+	    freeMaps (&tmpmaps);
+	    free (tmpmaps);
+	    tmpmaps = NULL;
+	    free (tmp);
+	  }
+      }
+    free (inputs_as_text);
+    free(cursor_input);
+  }
+  return 1;
+}
+
+/**
+ * Parse outputs provided as KVP and store them in a maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request_inputs the map storing KVP raw value 
+ * @param request_output the maps to store the KVP pairs 
+ * @return 0 on success, -1 on failure
+ */
+int kvpParseOutputs(maps** main_conf,map *request_inputs,maps** request_output){
+  /**
+   * Parsing outputs provided as KVP
+   */
+  map *r_inputs = NULL;
+  r_inputs = getMap (request_inputs, "ResponseDocument");
+  if (r_inputs == NULL)
+    r_inputs = getMap (request_inputs, "RawDataOutput");
+
+  if (r_inputs != NULL)
+    {
+      char *cursor_output = zStrdup (r_inputs->value);
+      int j = 0;
+
+      /**
+       * Put each Output into the outputs_as_text array
+       */
+      char *pToken;
+      maps *tmp_output = NULL;
+      pToken = strtok (cursor_output, ";");
+      char **outputs_as_text = (char **) malloc (128 * sizeof (char *));
+      if (outputs_as_text == NULL)
+	{
+	  free(cursor_output);
+	  return errorException (*main_conf, _("Unable to allocate memory"),
+				 "InternalError", NULL);
+	}
+      int i = 0;
+      while (pToken != NULL)
+	{
+	  outputs_as_text[i] =
+	    (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
+	  if (outputs_as_text[i] == NULL)
+	    {
+	      free(cursor_output);
+	      return errorException (*main_conf, _("Unable to allocate memory"),
+				     "InternalError", NULL);
+	    }
+	  snprintf (outputs_as_text[i], strlen (pToken) + 1, "%s",
+		    pToken);
+	  pToken = strtok (NULL, ";");
+	  i++;
+	}
+      for (j = 0; j < i; j++)
+	{
+	  char *tmp = zStrdup (outputs_as_text[j]);
+	  free (outputs_as_text[j]);
+	  char *tmpc;
+	  tmpc = strtok (tmp, "@");
+	  int k = 0;
+	  while (tmpc != NULL)
+	    {
+	      if (k == 0)
+		{
+		  if (tmp_output == NULL)
+		    {
+		      tmp_output = (maps *) malloc (MAPS_SIZE);
+		      if (tmp_output == NULL)
+			{
+			  free(cursor_output);
+			  return errorException (*main_conf,
+						 _
+						 ("Unable to allocate memory."),
+						 "InternalError", NULL);
+			}
+		      tmp_output->name = zStrdup (tmpc);
+		      tmp_output->content = NULL;
+		      tmp_output->next = NULL;
+		    }
+		}
+	      else
+		{
+		  char *tmpv = strstr (tmpc, "=");
+		  char tmpn[256];
+		  memset (tmpn, 0, 256);
+		  strncpy (tmpn, tmpc,
+			   (strlen (tmpc) -
+			    strlen (tmpv)) * sizeof (char));
+		  tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
+		  if (tmp_output->content == NULL)
+		    {
+		      tmp_output->content = createMap (tmpn, tmpv + 1);
+		      tmp_output->content->next = NULL;
+		    }
+		  else
+		    addToMap (tmp_output->content, tmpn, tmpv + 1);
+		}
+	      k++;
+	      tmpc = strtok (NULL, "@");
+	    }
+	  if (*request_output == NULL)
+	    *request_output = dupMaps (&tmp_output);
+	  else
+	    addMapsToMaps (request_output, tmp_output);
+	  freeMaps (&tmp_output);
+	  free (tmp_output);
+	  tmp_output = NULL;
+	  free (tmp);
+	}
+      free (outputs_as_text);
+      free(cursor_output);
+    }
+  return 1;
+}
+
+/**
+ * Parse inputs from XML nodes and store them in a maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param s the service
+ * @param request_output the maps to store the KVP pairs 
+ * @param doc the xmlDocPtr containing the original request
+ * @param nodes the input nodes array
+ * @param hInternet the HINTERNET queue to add potential requests
+ * @return 0 on success, -1 on failure
+ */
+int xmlParseInputs(maps** main_conf,service* s,maps** request_output,xmlDocPtr doc,xmlNodeSet* nodes,HINTERNET* hInternet){
+  int k = 0;
+  int l = 0;
+  map* version=getMapFromMaps(*main_conf,"main","rversion");
+  int vid=getVersionId(version->value);
+  for (k=0; k < nodes->nodeNr; k++)
+    {
+      maps *tmpmaps = NULL;
+      xmlNodePtr cur = nodes->nodeTab[k];
+
+      if (nodes->nodeTab[k]->type == XML_ELEMENT_NODE)
+	{
+	  // A specific Input node.
+	  if(vid==1){
+	    tmpmaps = (maps *) malloc (MAPS_SIZE);
+	    xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
+	    tmpmaps->name = zStrdup ((char *) val);
+	    tmpmaps->content = NULL;
+	    tmpmaps->next = NULL;
+	  }
+
+	  xmlNodePtr cur2 = cur->children;
+	  while (cur2 != NULL)
+	    {
+	      while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
+		cur2 = cur2->next;
+	      if (cur2 == NULL)
+		break;
+	      // Indentifier
+	      if (xmlStrncasecmp
+		  (cur2->name, BAD_CAST "Identifier",
+		   xmlStrlen (cur2->name)) == 0)
+		{
+		  xmlChar *val =
+		    xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
+		  if (tmpmaps == NULL)
+		    {
+		      tmpmaps = (maps *) malloc (MAPS_SIZE);
+		      if (tmpmaps == NULL)
+			{
+			  return errorException (*main_conf,
+						 _
+						 ("Unable to allocate memory."),
+						 "InternalError", NULL);
+			}
+		      tmpmaps->name = zStrdup ((char *) val);
+		      tmpmaps->content = NULL;
+		      tmpmaps->next = NULL;
+		    }
+		  xmlFree (val);
+		}
+	      // Title, Asbtract
+	      if (xmlStrncasecmp
+		  (cur2->name, BAD_CAST "Title",
+		   xmlStrlen (cur2->name)) == 0
+		  || xmlStrncasecmp (cur2->name, BAD_CAST "Abstract",
+				     xmlStrlen (cur2->name)) == 0)
+		{
+		  xmlChar *val =
+		    xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
+		  if (tmpmaps == NULL)
+		    {
+		      tmpmaps = (maps *) malloc (MAPS_SIZE);
+		      if (tmpmaps == NULL)
+			{
+			  return errorException (*main_conf,
+						 _
+						 ("Unable to allocate memory."),
+						 "InternalError", NULL);
+			}
+		      tmpmaps->name = zStrdup ("missingIndetifier");
+		      tmpmaps->content =
+			createMap ((char *) cur2->name, (char *) val);
+		      tmpmaps->next = NULL;
+		    }
+		  else
+		    {
+		      if (tmpmaps->content != NULL)
+			addToMap (tmpmaps->content,
+				  (char *) cur2->name, (char *) val);
+		      else
+			tmpmaps->content =
+			  createMap ((char *) cur2->name, (char *) val);
+		    }
+		  xmlFree (val);
+		}
+	      // InputDataFormChoice (Reference or Data ?) 
+	      if (xmlStrcasecmp (cur2->name, BAD_CAST "Reference") == 0)
+		{
+		  // Get every attribute from a Reference node
+		  // mimeType, encoding, schema, href, method
+		  // Header and Body gesture should be added here
+		  const char *refs[5] =
+		    { "mimeType", "encoding", "schema", "method",
+		      "href"
+		    };
+		  for (l = 0; l < 5; l++)
+		    {
+		      xmlChar *val = xmlGetProp (cur2, BAD_CAST refs[l]);
+		      if (val != NULL && xmlStrlen (val) > 0)
+			{
+			  if (tmpmaps->content != NULL)
+			    addToMap (tmpmaps->content, refs[l],
+				      (char *) val);
+			  else
+			    tmpmaps->content =
+			      createMap (refs[l], (char *) val);
+
+			  map *ltmp = getMap (tmpmaps->content, "method");
+			  if (l == 4 )
+			    {
+			      if ((ltmp==NULL || strncmp (ltmp->value, "POST",4) != 0))
+				{
+				  if (loadRemoteFile
+				      (main_conf, &tmpmaps->content, hInternet,
+				       (char *) val) != 0)
+				    {
+				      return errorException (*main_conf,
+							     _("Unable to add a request in the queue."),
+							     "InternalError",
+							     NULL);
+				    }
+				  addIntToMap (tmpmaps->content, "Order", hInternet->nb);
+				}
+			      addToMap (tmpmaps->content, "Reference", (char*) val);
+			    }
+			}
+		      xmlFree (val);
+		    }
+		  // Parse Header and Body from Reference
+		  xmlNodePtr cur3 = cur2->children;
+		  while (cur3 != NULL)
+		    {
+		      while (cur3 != NULL
+			     && cur3->type != XML_ELEMENT_NODE)
+			cur3 = cur3->next;
+		      if (cur3 == NULL)
+			break;
+		      if (xmlStrcasecmp (cur3->name, BAD_CAST "Header") ==
+			  0)
+			{
+			  const char *ha[2];
+			  ha[0] = "key";
+			  ha[1] = "value";
+			  int hai;
+			  char *has;
+			  char *key;
+			  for (hai = 0; hai < 2; hai++)
+			    {
+			      xmlChar *val =
+				xmlGetProp (cur3, BAD_CAST ha[hai]);
+#ifdef POST_DEBUG
+			      fprintf (stderr, "%s = %s\n", ha[hai],
+				       (char *) val);
+#endif
+			      if (hai == 0)
+				{
+				  key = zStrdup ((char *) val);
+				}
+			      else
+				{
+				  has =
+				    (char *)
+				    malloc ((4 + xmlStrlen (val) +
+					     strlen (key)) *
+					    sizeof (char));
+				  if (has == NULL)
+				    {
+				      return errorException (*main_conf,
+							     _
+							     ("Unable to allocate memory."),
+							     "InternalError",
+							     NULL);
+				    }
+				  snprintf (has,
+					    (3 + xmlStrlen (val) +
+					     strlen (key)), "%s: %s", key,
+					    (char *) val);
+				  free (key);
+				}
+			      xmlFree (val);
+			    }
+			  hInternet->ihandle[hInternet->nb].header = NULL;
+			  hInternet->ihandle[hInternet->nb].header =
+			    curl_slist_append (hInternet->ihandle
+					       [hInternet->nb].header,
+					       has);
+			  if (has != NULL)
+			    free (has);
+			}
+		      else
+			{
+#ifdef POST_DEBUG
+			  fprintf (stderr,
+				   "Try to fetch the body part of the request ...\n");
+#endif
+			  if (xmlStrcasecmp (cur3->name, BAD_CAST "Body")
+			      == 0)
+			    {
+#ifdef POST_DEBUG
+			      fprintf (stderr, "Body part found (%s) !!!\n",
+				       (char *) cur3->content);
+#endif
+			      char *tmp = NULL;
+			      xmlNodePtr cur4 = cur3->children;
+			      while (cur4 != NULL)
+				{
+				  while (cur4 && cur4 != NULL && cur4->type && cur4->type != XML_ELEMENT_NODE){
+				    if(cur4->next)
+				      cur4 = cur4->next;
+				    else
+				      cur4 = NULL;
+				  }
+				  if(cur4 != NULL) {
+				    xmlDocPtr bdoc =
+				      xmlNewDoc (BAD_CAST "1.0");
+				    bdoc->encoding =
+				      xmlCharStrdup ("UTF-8");
+				    xmlDocSetRootElement (bdoc, cur4);
+				    xmlChar *btmps;
+				    int bsize;
+				    // TODO : check for encoding defined in the input
+				    xmlDocDumpFormatMemoryEnc(bdoc, &btmps, &bsize, "UTF-8", 0);
+				    if (btmps != NULL){
+				      tmp = (char *) malloc ((bsize + 1) * sizeof (char));
+
+				      sprintf (tmp, "%s", (char*) btmps);
+					  
+				      xmlFreeDoc (bdoc);
+					  
+				      map *btmp =
+					getMap (tmpmaps->content, "Reference");
+				      if (btmp != NULL)
+					{
+					  addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
+					  InternetOpenUrl (hInternet,
+							   btmp->value,
+							   tmp,
+							   xmlStrlen(btmps),
+							   INTERNET_FLAG_NO_CACHE_WRITE,
+							   0);
+					  addIntToMap (tmpmaps->content, "Order", hInternet->nb);
+					}
+				      xmlFree (btmps);
+				      free (tmp);
+				      break;
+				    }
+				  }
+				  cur4 = cur4->next;
+				}
+			    }
+			  else
+			    if (xmlStrcasecmp
+				(cur3->name,
+				 BAD_CAST "BodyReference") == 0)
+			      {
+				xmlChar *val =
+				  xmlGetProp (cur3, BAD_CAST "href");
+				HINTERNET bInternet, res1, res;
+				bInternet = InternetOpen (
+#ifndef WIN32
+							  (LPCTSTR)
+#endif
+							  "ZooWPSClient\0",
+							  INTERNET_OPEN_TYPE_PRECONFIG,
+							  NULL, NULL, 0);
+				if (!CHECK_INET_HANDLE (bInternet))
+				  fprintf (stderr,
+					   "WARNING : bInternet handle failed to initialize");
+				bInternet.waitingRequests[0] =
+				  strdup ((char *) val);
+				res1 =
+				  InternetOpenUrl (&bInternet,
+						   bInternet.waitingRequests
+						   [0], NULL, 0,
+						   INTERNET_FLAG_NO_CACHE_WRITE,
+						   0);
+				processDownloads (&bInternet);
+				char *tmp =
+				  (char *)
+				  malloc ((bInternet.ihandle[0].nDataLen +
+					   1) * sizeof (char));
+				if (tmp == NULL)
+				  {
+				    return errorException (*main_conf,
+							   _
+							   ("Unable to allocate memory."),
+							   "InternalError",
+							   NULL);
+				  }
+				size_t bRead;
+				InternetReadFile (bInternet.ihandle[0],
+						  (LPVOID) tmp,
+						  bInternet.
+						  ihandle[0].nDataLen,
+						  &bRead);
+				tmp[bInternet.ihandle[0].nDataLen] = 0;
+				InternetCloseHandle (&bInternet);
+				map *btmp =
+				  getMap (tmpmaps->content, "href");
+				if (btmp != NULL)
+				  {
+				    addRequestToQueue(main_conf,hInternet,(char *) btmp->value,false);
+
+				    res =
+				      InternetOpenUrl (hInternet,
+						       btmp->value,
+						       tmp,
+						       strlen(tmp),
+						       INTERNET_FLAG_NO_CACHE_WRITE,
+						       0);
+				    addIntToMap (tmpmaps->content, "Order", hInternet->nb);
+				  }
+				free (tmp);
+			      }
+			}
+		      cur3 = cur3->next;
+		    }
+		}
+	      else if (xmlStrcasecmp (cur2->name, BAD_CAST "Data") == 0)
+		{
+		  xmlNodePtr cur4 = cur2->children;
+		  if(vid==1){
+		    // Get every dataEncodingAttributes from a Data node:
+		    // mimeType, encoding, schema
+		    const char *coms[3] =
+		      { "mimeType", "encoding", "schema" };
+		    for (l = 0; l < 3; l++){
+		      xmlChar *val =
+			  xmlGetProp (cur4, BAD_CAST coms[l]);
+			if (val != NULL && strlen ((char *) val) > 0){
+			  if (tmpmaps->content != NULL)
+			    addToMap (tmpmaps->content,coms[l],(char *) val);
+			  else
+			    tmpmaps->content =
+			      createMap (coms[l],(char *) val);
+			}
+			xmlFree (val);
+		    }
+		    while (cur4 != NULL){
+		      while(cur4 != NULL && 
+			    cur4->type != XML_CDATA_SECTION_NODE &&
+			    cur4->type != XML_TEXT_NODE)
+			cur4=cur4->next;
+		      if(cur4!=NULL){
+			if(cur4->content!=NULL)
+			  if (tmpmaps->content != NULL)
+			    addToMap (tmpmaps->content, "value",
+				      (char *) cur4->content);
+			  else
+			    tmpmaps->content =
+			      createMap ("value", (char *) cur4->content);
+			cur4=cur4->next;
+		      }
+		    }
+		  }
+
+
+		  while (cur4 != NULL)
+		    {
+		      while (cur4 != NULL
+			     && cur4->type != XML_ELEMENT_NODE)
+			cur4 = cur4->next;
+		      if (cur4 == NULL)
+			break;
+		      if (xmlStrcasecmp
+			  (cur4->name, BAD_CAST "LiteralData") == 0)
+			{
+			  // Get every attribute from a LiteralData node
+			  // dataType , uom
+			  char *list[2];
+			  list[0] = zStrdup ("dataType");
+			  list[1] = zStrdup ("uom");
+			  for (l = 0; l < 2; l++)
+			    {
+			      xmlChar *val =
+				xmlGetProp (cur4, BAD_CAST list[l]);
+			      if (val != NULL
+				  && strlen ((char *) val) > 0)
+				{
+				  if (tmpmaps->content != NULL)
+				    addToMap (tmpmaps->content, list[l],
+					      (char *) val);
+				  else
+				    tmpmaps->content =
+				      createMap (list[l], (char *) val);
+				}
+			      xmlFree (val);
+			      free (list[l]);
+			    }
+			}
+		      else
+			if (xmlStrcasecmp
+			    (cur4->name, BAD_CAST "ComplexData") == 0)
+			  {
+			    // Get every attribute from a Reference node
+			    // mimeType, encoding, schema
+			    const char *coms[3] =
+			      { "mimeType", "encoding", "schema" };
+			    for (l = 0; l < 3; l++)
+			      {
+				xmlChar *val =
+				  xmlGetProp (cur4, BAD_CAST coms[l]);
+				if (val != NULL
+				    && strlen ((char *) val) > 0)
+				  {
+				    if (tmpmaps->content != NULL)
+				      addToMap (tmpmaps->content, coms[l],
+						(char *) val);
+				    else
+				      tmpmaps->content =
+					createMap (coms[l], (char *) val);
+				  }
+				xmlFree (val);
+			      }
+			  }
+
+		      map *test = getMap (tmpmaps->content, "encoding");
+
+		      if (test == NULL)
+			{ 
+			  if (tmpmaps->content != NULL)
+			    addToMap (tmpmaps->content, "encoding",
+				      "utf-8");
+			  else
+			    tmpmaps->content =
+			      createMap ("encoding", "utf-8");
+			  test = getMap (tmpmaps->content, "encoding");
+			}
+
+		      if (strcasecmp (test->value, "base64") != 0)
+			{ 
+			  xmlChar *mv = xmlNodeListGetString (doc,
+							      cur4->xmlChildrenNode,
+							      1);
+			  map *ltmp =
+			    getMap (tmpmaps->content, "mimeType");
+			  if (mv == NULL
+			      ||
+			      (xmlStrcasecmp
+			       (cur4->name, BAD_CAST "ComplexData") == 0
+			       && (ltmp == NULL
+				   || strncasecmp (ltmp->value,
+						   "text/xml", 8) == 0)))
+			    {
+			      xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
+			      int buffersize;
+			      xmlNodePtr cur5 = cur4->children;
+			      while (cur5 != NULL
+				     && cur5->type != XML_ELEMENT_NODE
+				     && cur5->type != XML_CDATA_SECTION_NODE)
+				cur5 = cur5->next;
+			      if (cur5 != NULL
+				  && cur5->type != XML_CDATA_SECTION_NODE)
+				{
+				  xmlDocSetRootElement (doc1, cur5);
+				  xmlDocDumpFormatMemoryEnc (doc1, &mv,
+							     &buffersize,
+							     "utf-8", 1);
+				  char size[1024];
+				  sprintf (size, "%d", buffersize);
+				  addToMap (tmpmaps->content, "size",
+					    size);
+				  xmlFreeDoc (doc1);
+				}
+			      else
+				{
+				  if (cur5 != NULL
+				      && cur5->type == XML_CDATA_SECTION_NODE){
+				    xmlDocPtr doc2 = xmlParseMemory((const char*)cur5->content,xmlStrlen(cur5->content));
+				    xmlDocSetRootElement (doc1,xmlDocGetRootElement(doc2));
+				    xmlDocDumpFormatMemoryEnc (doc1, &mv,
+							       &buffersize,
+							       "utf-8", 1);
+				    char size[1024];
+				    sprintf (size, "%d", buffersize);
+				    addToMap (tmpmaps->content, "size",
+					      size);
+				    xmlFreeDoc (doc2);
+				    xmlFreeDoc (doc1);
+				  }
+				}
+			    }else{
+			    xmlNodePtr cur5 = cur4->children;
+			    while (cur5 != NULL
+				   && cur5->type != XML_CDATA_SECTION_NODE)
+			      cur5 = cur5->next;
+			    if (cur5 != NULL
+				&& cur5->type == XML_CDATA_SECTION_NODE){
+			      xmlFree(mv);
+			      mv=xmlStrdup(cur5->content);
+			    }
+			  }
+			  if (mv != NULL)
+			    {
+			      addToMap (tmpmaps->content, "value",
+					(char *) mv);
+			      xmlFree (mv);
+			    }
+			}
+		      else
+			{
+			  xmlChar *tmp = xmlNodeListGetRawString (doc,
+								  cur4->xmlChildrenNode,
+								  0);
+			  addToMap (tmpmaps->content, "value",
+				    (char *) tmp);
+			  xmlFree (tmp);
+			}
+		      cur4 = cur4->next;
+		    }
+		}
+	      cur2 = cur2->next;
+	      while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE){
+		cur2 = cur2->next;
+	      }
+	    }
+	  {
+	    maps *testPresence =
+	      getMaps (*request_output, tmpmaps->name);
+	    if (testPresence != NULL)
+	      {
+		elements *elem = getElements (s->inputs, tmpmaps->name);
+		if (elem != NULL)
+		  {
+		    if (appendMapsToMaps
+			(*main_conf, *request_output, tmpmaps, elem) < 0)
+		      {
+			return errorException (*main_conf,
+					       _("Unable to append maps to maps."),
+					       "InternalError",
+					       NULL);
+		      }
+		  }
+	      }
+	    else
+	      addMapsToMaps (request_output, tmpmaps);
+	  }
+	  freeMaps (&tmpmaps);
+	  free (tmpmaps);
+	  tmpmaps = NULL;
+	}
+    }
+  return 1;
+}
+
+/**
+ * Parse outputs from XML nodes and store them in a maps (WPS version 2.0.0).
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request_inputs the map storing KVP raw value 
+ * @param request_output the maps to store the KVP pairs 
+ * @param doc the xmlDocPtr containing the original request
+ * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
+ * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
+ * @return 0 on success, -1 on failure
+ */
+int xmlParseOutputs2(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodeSet* nodes){
+  int k = 0;
+  int l = 0;
+  for (k=0; k < nodes->nodeNr; k++){
+    maps *tmpmaps = NULL;
+    xmlNodePtr cur = nodes->nodeTab[k];
+    if (cur->type == XML_ELEMENT_NODE){
+      maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
+      xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
+      if(val!=NULL)
+	tmpmaps->name = zStrdup ((char*)val);
+      else
+	tmpmaps->name = zStrdup ("unknownIdentifier");
+      tmpmaps->content = NULL;
+      tmpmaps->next = NULL;
+      const char ress[4][13] =
+	{ "mimeType", "encoding", "schema", "transmission" };
+      for (l = 0; l < 4; l++){
+	val = xmlGetProp (cur, BAD_CAST ress[l]);
+	if (val != NULL && strlen ((char *) val) > 0)
+	  {
+	    if (tmpmaps->content != NULL)
+	      addToMap (tmpmaps->content, ress[l],
+			(char *) val);
+	    else
+	      tmpmaps->content =
+		createMap (ress[l], (char *) val);
+	    if(l==3 && strncasecmp((char*)val,"reference",xmlStrlen(val))==0)
+	      addToMap (tmpmaps->content,"asReference","true");
+	  }
+	xmlFree (val);
+      }
+      if (*request_output == NULL)
+	*request_output = dupMaps(&tmpmaps);
+      else
+	addMapsToMaps(request_output,tmpmaps);
+    }
+  }
+}
+
+/**
+ * Parse outputs from XML nodes and store them in a maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request_inputs the map storing KVP raw value 
+ * @param request_output the maps to store the KVP pairs 
+ * @param doc the xmlDocPtr containing the original request
+ * @param cur the xmlNodePtr corresponding to the ResponseDocument or RawDataOutput XML node
+ * @param raw true if the node is RawDataOutput, false in case of ResponseDocument
+ * @return 0 on success, -1 on failure
+ */
+int xmlParseOutputs(maps** main_conf,map** request_inputs,maps** request_output,xmlDocPtr doc,xmlNodePtr cur,bool raw){
+  int l=0;
+  if( raw == true)
+    {
+      addToMap (*request_inputs, "RawDataOutput", "");
+      if (cur->type == XML_ELEMENT_NODE)
+	{
+
+	  maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
+	  if (tmpmaps == NULL)
+	    {
+	      return errorException (*main_conf, _("Unable to allocate memory."),
+				     "InternalError", NULL);
+	    }
+	  tmpmaps->name = zStrdup ("unknownIdentifier");
+	  tmpmaps->content = NULL;
+	  tmpmaps->next = NULL;
+
+	  // Get every attribute from a RawDataOutput node
+	  // mimeType, encoding, schema, uom
+	  const char *outs[4] =
+	    { "mimeType", "encoding", "schema", "uom" };
+	  for (l = 0; l < 4; l++)
+	    {
+	      xmlChar *val = xmlGetProp (cur, BAD_CAST outs[l]);
+	      if (val != NULL)
+		{
+		  if (strlen ((char *) val) > 0)
+		    {
+		      if (tmpmaps->content != NULL)
+			addToMap (tmpmaps->content, outs[l],
+				  (char *) val);
+		      else
+			tmpmaps->content =
+			  createMap (outs[l], (char *) val);
+		    }
+		  xmlFree (val);
+		}
+	    }
+	  xmlNodePtr cur2 = cur->children;
+	  while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
+	    cur2 = cur2->next;
+	  while (cur2 != NULL)
+	    {
+	      if (xmlStrncasecmp
+		  (cur2->name, BAD_CAST "Identifier",
+		   xmlStrlen (cur2->name)) == 0)
+		{
+		  xmlChar *val =
+		    xmlNodeListGetString (NULL, cur2->xmlChildrenNode, 1);
+		  free (tmpmaps->name);
+		  tmpmaps->name = zStrdup ((char *) val);
+		  xmlFree (val);
+		}
+	      cur2 = cur2->next;
+	      while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
+		cur2 = cur2->next;
+	    }
+	  if (*request_output == NULL)
+	    *request_output = dupMaps (&tmpmaps);
+	  else
+	    addMapsToMaps (request_output, tmpmaps);
+	  if (tmpmaps != NULL)
+	    {
+	      freeMaps (&tmpmaps);
+	      free (tmpmaps);
+	      tmpmaps = NULL;
+	    }
+	}
+    }
+  else
+    {
+      addToMap (*request_inputs, "ResponseDocument", "");
+
+      if (cur->type == XML_ELEMENT_NODE) {
+	// Get every attribute: storeExecuteResponse, lineage, status
+	const char *ress[3] =
+	  { "storeExecuteResponse", "lineage", "status" };
+	xmlChar *val;
+	for (l = 0; l < 3; l++)
+	  {
+	    val = xmlGetProp (cur, BAD_CAST ress[l]);
+	    if (val != NULL && strlen ((char *) val) > 0)
+	      {
+		addToMap (*request_inputs, ress[l], (char *) val);
+	      }
+	    xmlFree (val);
+	  }
+			
+	xmlNodePtr cur1 = cur->children;		
+	while (cur1 != NULL) // iterate over Output nodes
+	  {
+	    if (cur1->type != XML_ELEMENT_NODE || 
+		xmlStrncasecmp(cur1->name, BAD_CAST "Output", 
+			       xmlStrlen (cur1->name)) != 0) {
+	      cur1 = cur1->next;
+	      continue;
+	    }
+				
+	    maps *tmpmaps = (maps *) malloc (MAPS_SIZE); // one per Output node
+	    if (tmpmaps == NULL) {
+	      return errorException (*main_conf,
+				     _
+				     ("Unable to allocate memory."),
+				     "InternalError", NULL);
+	    }
+	    tmpmaps->name = zStrdup ("unknownIdentifier");
+	    tmpmaps->content = NULL;
+	    tmpmaps->next = NULL;
+				
+	    xmlNodePtr elems = cur1->children;
+				
+	    while (elems != NULL) {
+
+	      // Identifier
+	      if (xmlStrncasecmp
+		  (elems->name, BAD_CAST "Identifier",
+		   xmlStrlen (elems->name)) == 0)
+		{
+		  xmlChar *val =
+		    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
+		
+		  free(tmpmaps->name);
+		  tmpmaps->name = zStrdup ((char *) val);
+		  if (tmpmaps->content == NULL) {
+		    tmpmaps->content = createMap("Identifier", zStrdup ((char *) val));
+		  }
+		  else {
+		    addToMap(tmpmaps->content, "Identifier", zStrdup ((char *) val));
+		  }
+
+		  map* tt = getMap (*request_inputs, "ResponseDocument");
+		  if (strlen(tt->value) == 0) {
+		    addToMap (*request_inputs, "ResponseDocument",
+			      (char *) val);
+		  }
+		  else {
+		    char* tmp = (char*) malloc((strlen(tt->value) + 1 
+						+ strlen((char*) val) + 1) * sizeof(char));
+		    sprintf (tmp, "%s;%s", tt->value, (char *) val);
+		    free(tt->value);
+		    tt->value = tmp;
+		  }
+		  xmlFree (val);
+		}
+	      
+	      // Title, Abstract
+	      else if (xmlStrncasecmp(elems->name, BAD_CAST "Title",
+				      xmlStrlen (elems->name)) == 0
+		       || xmlStrncasecmp(elems->name, BAD_CAST "Abstract",
+					 xmlStrlen (elems->name)) == 0)
+		{
+		  xmlChar *val =
+		    xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
+							
+		  if (tmpmaps->content == NULL) {
+		    tmpmaps->content = createMap((char*) elems->name, zStrdup ((char *) val));
+		  }
+		  else {
+		    addToMap(tmpmaps->content, (char*) elems->name, zStrdup ((char *) val));
+		  }
+		  xmlFree (val);
+		}
+	      elems = elems->next;
+	    }
+				
+	    // Get every attribute from an Output node:
+	    // mimeType, encoding, schema, uom, asReference
+	    const char *outs[5] =
+	      { "mimeType", "encoding", "schema", "uom", "asReference" };
+					  
+	    for (l = 0; l < 5; l++) {
+	      xmlChar *val = xmlGetProp (cur1, BAD_CAST outs[l]);				
+	      if (val != NULL && xmlStrlen(val) > 0) {
+		if (tmpmaps->content != NULL) {
+		  addToMap (tmpmaps->content, outs[l], (char *) val);
+		}			  
+		else {
+		  tmpmaps->content = createMap (outs[l], (char *) val);
+		}	
+	      }
+	      xmlFree (val);
+	    }
+				
+	    if (*request_output == NULL) {
+	      *request_output = tmpmaps;
+	    }	
+	    else if (getMaps(*request_output, tmpmaps->name) != NULL) {
+	      return errorException (*main_conf,
+				     _
+				     ("Duplicate <Output> elements in WPS Execute request"),
+				     "InternalError", NULL);
+	    }
+	    else {
+	      maps* mptr = *request_output;
+	      while (mptr->next != NULL) {
+		mptr = mptr->next;
+	      }
+	      mptr->next = tmpmaps;	
+	    }					
+	    cur1 = cur1->next;
+	  }			 
+      }
+    }
+  return 1;
+}
+
+/**
+ * Parse XML request and store informations in maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param post the string containing the XML request
+ * @param request_inputs the map storing KVP raw value 
+ * @param s the service
+ * @param inputs the maps to store the KVP pairs 
+ * @param outputs the maps to store the KVP pairs 
+ * @param hInternet the HINTERNET queue to add potential requests
+ * @return 0 on success, -1 on failure
+ */
+int xmlParseRequest(maps** main_conf,const char* post,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
+
+  map* version=getMapFromMaps(*main_conf,"main","rversion");
+  int vid=getVersionId(version->value);
+
+  xmlInitParser ();
+  xmlDocPtr doc = xmlParseMemory (post, cgiContentLength);
+
+  /**
+   * Extract Input nodes from the XML Request.
+   */
+  xmlXPathObjectPtr tmpsptr =
+    extractFromDoc (doc, (vid==0?"/*/*/*[local-name()='Input']":"/*/*[local-name()='Input']"));
+  xmlNodeSet *tmps = tmpsptr->nodesetval;
+  if(tmps==NULL || xmlParseInputs(main_conf,s,inputs,doc,tmps,hInternet)<0){
+    xmlXPathFreeObject (tmpsptr);
+    xmlFreeDoc (doc);
+    xmlCleanupParser ();
+    return -1;
+  }
+  xmlXPathFreeObject (tmpsptr);
+
+  if(vid==1){
+    tmpsptr =
+      extractFromDoc (doc, "/*[local-name()='Execute']");
+    bool asRaw = false;
+    tmps = tmpsptr->nodesetval;
+    if(tmps->nodeNr > 0){
+      int k = 0;
+      for (k=0; k < tmps->nodeNr; k++){
+	maps *tmpmaps = NULL;
+	xmlNodePtr cur = tmps->nodeTab[k];
+	if (cur->type == XML_ELEMENT_NODE){
+	  xmlChar *val = xmlGetProp (cur, BAD_CAST "mode");
+	  if(val!=NULL)
+	    addToMap(*request_inputs,"mode",(char*)val);
+	  else
+	    addToMap(*request_inputs,"mode","auto");
+	  val = xmlGetProp (cur, BAD_CAST "response");
+	  if(val!=NULL){
+	    addToMap(*request_inputs,"response",(char*)val);
+	    if(strncasecmp((char*)val,"raw",xmlStrlen(val))==0)
+	      addToMap(*request_inputs,"RawDataOutput","");
+	    else
+	      addToMap(*request_inputs,"ResponseDocument","");
+	  }
+	  else{
+	    addToMap(*request_inputs,"response","document");
+	    addToMap(*request_inputs,"ResponseDocument","");
+	  }
+	}
+      }
+    }
+    xmlXPathFreeObject (tmpsptr);
+    tmpsptr =
+      extractFromDoc (doc, "/*/*[local-name()='Output']");
+    tmps = tmpsptr->nodesetval;
+    if(tmps->nodeNr > 0){
+      if(xmlParseOutputs2(main_conf,request_inputs,outputs,doc,tmps)<0){
+	xmlXPathFreeObject (tmpsptr);
+	xmlFreeDoc (doc);
+	xmlCleanupParser ();
+	return -1;
+      }
+    }
+  }
+  else{
+    // Extract ResponseDocument / RawDataOutput from the XML Request 
+    tmpsptr =
+      extractFromDoc (doc, "/*/*/*[local-name()='ResponseDocument']");
+    bool asRaw = false;
+    tmps = tmpsptr->nodesetval;
+    if (tmps->nodeNr == 0)
+      {
+	xmlXPathFreeObject (tmpsptr);
+	tmpsptr =
+	  extractFromDoc (doc, "/*/*/*[local-name()='RawDataOutput']");
+	tmps = tmpsptr->nodesetval;
+	asRaw = true;
+      }
+    if(tmps->nodeNr != 0){
+      if(xmlParseOutputs(main_conf,request_inputs,outputs,doc,tmps->nodeTab[0],asRaw)<0){
+	xmlXPathFreeObject (tmpsptr);
+	xmlFreeDoc (doc);
+	xmlCleanupParser ();
+	return -1;
+      }
+    }
+  }
+  xmlXPathFreeObject (tmpsptr);
+  xmlFreeDoc (doc);
+  xmlCleanupParser ();
+  return 1;
+}
+
+/**
+ * Parse request and store informations in maps.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param post the string containing the XML request
+ * @param request_inputs the map storing KVP raw value 
+ * @param s the service
+ * @param inputs the maps to store the KVP pairs 
+ * @param outputs the maps to store the KVP pairs 
+ * @param hInternet the HINTERNET queue to add potential requests
+ * @return 0 on success, -1 on failure
+ * @see kvpParseOutputs,kvpParseInputs,xmlParseRequest
+ */
+int parseRequest(maps** main_conf,map** request_inputs,service* s,maps** inputs,maps** outputs,HINTERNET* hInternet){
+  map *postRequest = NULL;
+  postRequest = getMap (*request_inputs, "xrequest");
+  if (postRequest == NULLMAP)
+    {
+      if(kvpParseOutputs(main_conf,*request_inputs,outputs)<0){
+	return -1;
+      }
+      if(kvpParseInputs(main_conf,s,*request_inputs,inputs,hInternet)<0){
+	return -1;
+      }
+    }
+  else
+    {
+      //Parse XML request
+      if(xmlParseRequest(main_conf,postRequest->value,request_inputs,s,inputs,outputs,hInternet)<0){
+	return -1;
+      }
+    }
+  return 1;
+}
+
+/**
+ * Ensure that each requested arguments are present in the request
+ * DataInputs and ResponseDocument / RawDataOutput. Potentially run
+ * http requests from the queue in parallel.
+ * For optional inputs add default values defined in the ZCFG file.
+ * 
+ * @param main_conf
+ * @param s 
+ * @param original_request
+ * @param request_inputs
+ * @param request_outputs
+ * @param hInternet 
+ * 
+ * @see runHttpRequests
+ */
+int validateRequest(maps** main_conf,service* s,map* original_request, maps** request_inputs,maps** request_outputs,HINTERNET* hInternet){
+
+  runHttpRequests (main_conf, request_inputs, hInternet);
+  InternetCloseHandle (hInternet);
+
+  map* errI=NULL;
+  char *dfv = addDefaultValues (request_inputs, s->inputs, *main_conf, 0,&errI);
+
+  maps *ptr = *request_inputs;
+  while (ptr != NULL)
+    {
+      map *tmp0 = getMap (ptr->content, "size");
+      map *tmp1 = getMap (ptr->content, "maximumMegabytes");
+      if (tmp1 != NULL && tmp0 != NULL)
+        {
+          float i = atof (tmp0->value) / 1048576.0;
+          if (i >= atoi (tmp1->value))
+            {
+              char tmps[1024];
+              map *tmpe = createMap ("code", "FileSizeExceeded");
+              snprintf (tmps, 1024,
+                        _
+                        ("The <%s> parameter has a size limit (%s MB) defined in the ZOO ServicesProvider configuration file, but the reference you provided exceeds this limit (%f MB)."),
+                        ptr->name, tmp1->value, i);
+              addToMap (tmpe, "locator", ptr->name);
+              addToMap (tmpe, "text", tmps);
+              printExceptionReportResponse (*main_conf, tmpe);
+              freeMap (&tmpe);
+              free (tmpe);
+	      return -1;
+            }
+        }
+      ptr = ptr->next;
+    }
+
+  map* errO=NULL;
+  char *dfv1 =
+    addDefaultValues (request_outputs, s->outputs, *main_conf, 1,&errO);
+  if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
+    {
+      char tmps[1024];
+      map *tmpe = NULL;
+      if (strcmp (dfv, "") != 0)
+        {
+	  tmpe = createMap ("code", "MissingParameterValue");
+	  int nb=0;
+	  int length=1;
+	  map* len=getMap(errI,"length");
+	  if(len!=NULL)
+	    length=atoi(len->value);
+	  for(nb=0;nb<length;nb++){
+	    map* errp=getMapArray(errI,"value",nb);
+	    snprintf (tmps, 1024,
+		      _
+		      ("The <%s> argument was not specified in DataInputs but is required according to the ZOO ServicesProvider configuration file."),
+		      errp->value);
+	    setMapArray (tmpe, "locator", nb , errp->value);
+	    setMapArray (tmpe, "text", nb , tmps);
+	    setMapArray (tmpe, "code", nb , "MissingParameterValue");
+	  }
+	}
+      if (strcmp (dfv1, "") != 0)
+        {
+	  int ilength=0;
+	  if(tmpe==NULL)
+	    tmpe = createMap ("code", "InvalidParameterValue");
+	  else{
+	    map* len=getMap(tmpe,"length");
+	    if(len!=NULL)
+	      ilength=atoi(len->value);
+	  }
+	  int nb=0;
+	  int length=1;
+	  map* len=getMap(errO,"length");
+	  if(len!=NULL)
+	    length=atoi(len->value);
+	  for(nb=0;nb<length;nb++){
+	    map* errp=getMapArray(errO,"value",nb);
+	    snprintf (tmps, 1024,
+		      _
+		      ("The <%s> argument specified as %s identifier was not recognized (not defined in the ZOO Configuration File)."),
+		      errp->value,
+		      ((getMap(original_request,"RawDataOutput")!=NULL)?"RawDataOutput":"ResponseDocument"));
+	    setMapArray (tmpe, "locator", nb+ilength , errp->value);
+	    setMapArray (tmpe, "text", nb+ilength , tmps);
+	    setMapArray (tmpe, "code", nb+ilength , "InvalidParameterValue");
+	  }
+	}
+      printExceptionReportResponse (*main_conf, tmpe);
+      if(errI!=NULL){
+	freeMap(&errI);
+	free(errI);
+      }
+      if(errO!=NULL){
+	freeMap(&errO);
+	free(errO);
+      }
+      freeMap (&tmpe);
+      free (tmpe);
+      return -1;
+    }
+  maps *tmpReqI = *request_inputs;
+  while (tmpReqI != NULL)
+    {
+      char name[1024];
+      if (getMap (tmpReqI->content, "isFile") != NULL)
+        {
+          if (cgiFormFileName (tmpReqI->name, name, sizeof (name)) ==
+              cgiFormSuccess)
+            {
+              int BufferLen = 1024;
+              cgiFilePtr file;
+              int targetFile;
+              char storageNameOnServer[2048];
+              char fileNameOnServer[64];
+              char contentType[1024];
+              char buffer[1024];
+              char *tmpStr = NULL;
+              int size;
+              int got, t;
+              map *path = getMapFromMaps (*main_conf, "main", "tmpPath");
+              cgiFormFileSize (tmpReqI->name, &size);
+              cgiFormFileContentType (tmpReqI->name, contentType,
+                                      sizeof (contentType));
+              if (cgiFormFileOpen (tmpReqI->name, &file) == cgiFormSuccess)
+                {
+                  t = -1;
+                  while (1)
+                    {
+                      tmpStr = strstr (name + t + 1, "\\");
+                      if (NULL == tmpStr)
+                        tmpStr = strstr (name + t + 1, "/");
+                      if (NULL != tmpStr)
+                        t = (int) (tmpStr - name);
+                      else
+                        break;
+                    }
+                  strcpy (fileNameOnServer, name + t + 1);
+
+                  sprintf (storageNameOnServer, "%s/%s", path->value,
+                           fileNameOnServer);
+#ifdef DEBUG
+                  fprintf (stderr, "Name on server %s\n",
+                           storageNameOnServer);
+                  fprintf (stderr, "fileNameOnServer: %s\n",
+                           fileNameOnServer);
+#endif
+                  targetFile =
+                    open (storageNameOnServer, O_RDWR | O_CREAT | O_TRUNC,
+                          S_IRWXU | S_IRGRP | S_IROTH);
+                  if (targetFile < 0)
+                    {
+#ifdef DEBUG
+                      fprintf (stderr, "could not create the new file,%s\n",
+                               fileNameOnServer);
+#endif
+                    }
+                  else
+                    {
+                      while (cgiFormFileRead (file, buffer, BufferLen, &got)
+                             == cgiFormSuccess)
+                        {
+                          if (got > 0)
+                            write (targetFile, buffer, got);
+                        }
+                    }
+                  addToMap (tmpReqI->content, "lref", storageNameOnServer);
+                  cgiFormFileClose (file);
+                  close (targetFile);
+#ifdef DEBUG
+                  fprintf (stderr, "File \"%s\" has been uploaded",
+                           fileNameOnServer);
+#endif
+                }
+            }
+        }
+      tmpReqI = tmpReqI->next;
+    }
+
+  ensureDecodedBase64 (request_inputs);
+  return 1;
+}
+
+
+/**
+ * Verify if a parameter value is valid.
+ * 
+ * @param request the request map
+ * @param res the error map potentially generated
+ * @param toCheck the parameter to use
+ * @param avalues the acceptable values (or null if testing only for presence)
+ * @param mandatory verify the presence of the parameter if mandatory > 0 
+ */
+void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
+  map* lres=*res;
+  map* r_inputs = getMap (request,toCheck);
+  if (r_inputs == NULL){
+    if(mandatory>0){
+      char *replace=_("Mandatory parameter <%s> was not specified");
+      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
+      sprintf(message,replace,toCheck);
+      if(lres==NULL){
+	lres=createMap("code","MissingParameterValue");
+	addToMap(lres,"text",message);
+	addToMap(lres,"locator",toCheck);       
+      }else{
+	int length=1;
+	map* len=getMap(lres,"length");
+	if(len!=NULL){
+	  length=atoi(len->value);
+	}
+	setMapArray(lres,"text",length,message);
+	setMapArray(lres,"locator",length,toCheck);
+	setMapArray(lres,"code",length,"MissingParameter");
+      }
+      free(message);
+    }
+  }else{
+    if(avalues==NULL)
+      return;
+    int nb=0;
+    int hasValidValue=-1;
+    if(strncasecmp(toCheck,"Accept",6)==0){
+      char *tmp=zStrdup(r_inputs->value);
+      char *pToken,*saveptr;
+      pToken=strtok_r(tmp,",",&saveptr);
+      while(pToken!=NULL){
+	while(avalues[nb]!=NULL){
+	  if(strcasecmp(avalues[nb],pToken)==0){
+	    hasValidValue=1;
+	    break;
+	  }
+	  nb++;
+	}
+	pToken=strtok_r(NULL,",",&saveptr);
+      }
+      free(tmp);
+    }else{
+      while(avalues[nb]!=NULL){
+	if(strcasecmp(avalues[nb],r_inputs->value)==0){
+	  hasValidValue=1;
+	  break;
+	}
+	nb++;
+      }
+    }
+    if(hasValidValue<0){
+      char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
+      nb=0;
+      char *vvalues=NULL;
+      char* num=_("is");
+      while(avalues[nb]!=NULL){
+	char *tvalues;
+	if(vvalues==NULL){
+	  vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
+	  sprintf(vvalues,"%s",avalues[nb]);
+	}
+	else{
+	  tvalues=zStrdup(vvalues);
+	  vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
+	  sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
+	  free(tvalues);
+	  num=_("are");
+	}
+	nb++;
+      }
+      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
+      sprintf(message,replace,toCheck,vvalues,num);
+      const char *code="VersionNegotiationFailed";
+      code="InvalidParameterValue";
+      const char *locator=toCheck;
+      if( strncasecmp(toCheck,"version",7)==0 ||
+	  strncasecmp(toCheck,"AcceptVersions",14)==0 )
+	code="VersionNegotiationFailed";
+      if( strncasecmp(toCheck,"request",7)==0){
+	code="OperationNotSupported";
+	locator=r_inputs->value;
+      }
+      if(lres==NULL){
+	lres=createMap("code","InvalidParameterValue");
+	addToMap(lres,"text",message);
+	addToMap(lres,"locator",locator);       
+      }else{
+	int length=1;
+	map* len=getMap(lres,"length");
+	if(len!=NULL){
+	  length=atoi(len->value);
+	}
+	setMapArray(lres,"text",length,message);
+	setMapArray(lres,"locator",length,locator);
+	setMapArray(lres,"code",length,"InvalidParameterValue");
+      }
+    }
+  }
+  if(lres!=NULL){
+    *res=lres;
+  }
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/request_parser.h	(revision 672)
@@ -0,0 +1,55 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_REQUEST_PARSER_H
+#define ZOO_REQUEST_PARSER_H 1
+
+#pragma once 
+
+#include "service.h"
+#include "ulinet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+  xmlXPathObjectPtr extractFromDoc (xmlDocPtr, const char *);
+  int appendMapsToMaps (maps*, maps*, maps*, elements*);
+  void ensureDecodedBase64(maps**);
+  int kvpParseInputs(maps**,service*,map*,maps**,HINTERNET*);
+  int kvpParseOutputs(maps**,map *,maps**);
+  int xmlParseInputs(maps**,service*,maps**,xmlDocPtr,xmlNodeSet*,HINTERNET*);
+  int xmlParseOutputs(maps**,map**,maps**,xmlDocPtr,xmlNodePtr,bool);
+  int xmlParseRequest(maps**,const char*,map**,service*,maps**,maps**,HINTERNET*);
+  int parseRequest(maps**,map**,service*,maps**,maps**,HINTERNET*);
+  void checkValidValue(map*,map**,const char*,const char**,int);
+  int validateRequest(maps**,service*,map*,maps**,maps**,HINTERNET*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.c	(revision 672)
@@ -0,0 +1,2774 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "response_print.h"
+#include "request_parser.h"
+#include "server_internal.h"
+#include "service_internal.h"
+#ifdef USE_MS
+#include "service_internal_ms.h"
+#else
+#include "cpl_vsi.h"
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE -1
+#endif
+
+#ifndef WIN32
+#include <dlfcn.h>
+#endif
+
+#define ERROR_MSG_MAX_LENGTH 1024
+
+#include "mimetypes.h"
+
+
+/**
+ * Add prefix to the service name.
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param level the map containing the level information
+ * @param serv the service structure created from the zcfg file
+ */
+void addPrefix(maps* conf,map* level,service* serv){
+  if(level!=NULL){
+    char key[25];
+    char* prefix=NULL;
+    int clevel=atoi(level->value);
+    int cl=0;
+    for(cl=0;cl<clevel;cl++){
+      sprintf(key,"sprefix_%d",cl);
+      map* tmp2=getMapFromMaps(conf,"lenv",key);
+      if(tmp2!=NULL){
+	if(prefix==NULL)
+	  prefix=zStrdup(tmp2->value);
+	else{
+	  int plen=strlen(prefix);
+	  prefix=(char*)realloc(prefix,(plen+strlen(tmp2->value)+2)*sizeof(char));
+	  memcpy(prefix+plen,tmp2->value,strlen(tmp2->value)*sizeof(char));
+	  prefix[plen+strlen(tmp2->value)]=0;
+	}
+      }
+    }
+    if(prefix!=NULL){
+      char* tmp0=strdup(serv->name);
+      free(serv->name);
+      serv->name=(char*)malloc((strlen(prefix)+strlen(tmp0)+1)*sizeof(char));
+      sprintf(serv->name,"%s%s",prefix,tmp0);
+      free(tmp0);
+      free(prefix);
+      prefix=NULL;
+    }
+  }
+}
+
+/**
+ * Print the HTTP headers based on a map.
+ * 
+ * @param m the map containing the headers informations
+ */
+void printHeaders(maps* m){
+  maps *_tmp=getMaps(m,"headers");
+  if(_tmp!=NULL){
+    map* _tmp1=_tmp->content;
+    while(_tmp1!=NULL){
+      printf("%s: %s\r\n",_tmp1->name,_tmp1->value);
+      _tmp1=_tmp1->next;
+    }
+  }
+}
+
+/**
+ * Add a land attribute to a XML node
+ *
+ * @param n the XML node to add the attribute
+ * @param m the map containing the language key to add as xml:lang
+ */
+void addLangAttr(xmlNodePtr n,maps *m){
+  map *tmpLmap=getMapFromMaps(m,"main","language");
+  if(tmpLmap!=NULL)
+    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
+  else
+    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
+}
+
+/**
+ * Replace the first letter by its upper case version in a new char array
+ *
+ * @param tmp the char*
+ * @return a new char* with first letter in upper case
+ * @warning be sure to free() the returned string after use
+ */
+char *zCapitalize1(char *tmp){
+  char *res=zStrdup(tmp);
+  if(res[0]>=97 && res[0]<=122)
+    res[0]-=32;
+  return res;
+}
+
+/**
+ * Replace all letters by their upper case version in a new char array
+ *
+ * @param tmp the char*
+ * @return a new char* with first letter in upper case
+ * @warning be sure to free() the returned string after use
+ */
+char *zCapitalize(char *tmp){
+  int i=0;
+  char *res=zStrdup(tmp);
+  for(i=0;i<strlen(res);i++)
+    if(res[i]>=97 && res[i]<=122)
+      res[i]-=32;
+  return res;
+}
+
+/**
+ * Search for an existing XML namespace in usedNS.
+ * 
+ * @param name the name of the XML namespace to search
+ * @return the index of the XML namespace found or -1 if not found.
+ */
+int zooXmlSearchForNs(const char* name){
+  int i;
+  int res=-1;
+  for(i=0;i<nbNs;i++)
+    if(strncasecmp(name,nsName[i],strlen(nsName[i]))==0){
+      res=i;
+      break;
+    }
+  return res;
+}
+
+/**
+ * Add an XML namespace to the usedNS if it was not already used.
+ * 
+ * @param nr the xmlNodePtr to attach the XML namspace (can be NULL)
+ * @param url the url of the XML namespace to add
+ * @param name the name of the XML namespace to add
+ * @return the index of the XML namespace added.
+ */
+int zooXmlAddNs(xmlNodePtr nr,const char* url,const char* name){
+#ifdef DEBUG
+  fprintf(stderr,"zooXmlAddNs %d %s \n",nbNs,name);
+#endif
+  int currId=-1;
+  if(nbNs==0){
+    nbNs++;
+    currId=0;
+    nsName[currId]=strdup(name);
+    usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
+  }else{
+    currId=zooXmlSearchForNs(name);
+    if(currId<0){
+      nbNs++;
+      currId=nbNs-1;
+      nsName[currId]=strdup(name);
+      usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
+    }
+  }
+  return currId;
+}
+
+/**
+ * Free allocated memory to store used XML namespace.
+ */
+void zooXmlCleanupNs(){
+  int j;
+#ifdef DEBUG
+  fprintf(stderr,"zooXmlCleanup %d\n",nbNs);
+#endif
+  for(j=nbNs-1;j>=0;j--){
+#ifdef DEBUG
+    fprintf(stderr,"zooXmlCleanup %d\n",j);
+#endif
+    if(j==0)
+      xmlFreeNs(usedNs[j]);
+    free(nsName[j]);
+    nbNs--;
+  }
+  nbNs=0;
+}
+
+/**
+ * Add a XML document to the iDocs.
+ * 
+ * @param value the string containing the XML document
+ * @return the index of the XML document added.
+ */
+int zooXmlAddDoc(const char* value){
+  int currId=0;
+  nbDocs++;
+  currId=nbDocs-1;
+  iDocs[currId]=xmlParseMemory(value,strlen(value));
+  return currId;
+}
+
+/**
+ * Free allocated memort to store XML documents
+ */
+void zooXmlCleanupDocs(){
+  int j;
+  for(j=nbDocs-1;j>=0;j--){
+    xmlFreeDoc(iDocs[j]);
+  }
+  nbDocs=0;
+}
+
+/**
+ * Generate a SOAP Envelope node when required (if the isSoap key of the [main]
+ * section is set to true).
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param n the node used as children of the generated soap:Envelope
+ * @return the generated soap:Envelope (if isSoap=true) or the input node n 
+ *  (when isSoap=false)
+ */
+xmlNodePtr soapEnvelope(maps* conf,xmlNodePtr n){
+  map* soap=getMapFromMaps(conf,"main","isSoap");
+  if(soap!=NULL && strcasecmp(soap->value,"true")==0){
+    int lNbNs=nbNs;
+    nsName[lNbNs]=strdup("soap");
+    usedNs[lNbNs]=xmlNewNs(NULL,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
+    nbNs++;
+    xmlNodePtr nr = xmlNewNode(usedNs[lNbNs], BAD_CAST "Envelope");
+    nsName[nbNs]=strdup("soap");
+    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
+    nbNs++;
+    nsName[nbNs]=strdup("xsi");
+    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
+    nbNs++;
+    xmlNsPtr ns_xsi=usedNs[nbNs-1];
+    xmlNewNsProp(nr,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope");
+    xmlNodePtr nr1 = xmlNewNode(usedNs[lNbNs], BAD_CAST "Body");
+    xmlAddChild(nr1,n);
+    xmlAddChild(nr,nr1);
+    return nr;
+  }else
+    return n;
+}
+
+/**
+ * Generate a WPS header.
+ * 
+ * @param doc the document to add the header
+ * @param m the conf maps containing the main.cfg settings
+ * @param req the request type (GetCapabilities,DescribeProcess,Execute)
+ * @param rname the root node name
+ * @return the generated wps:rname xmlNodePtr (can be wps: Capabilities, 
+ *  wps:ProcessDescriptions,wps:ExecuteResponse)
+ */
+xmlNodePtr printWPSHeader(xmlDocPtr doc,maps* m,const char* req,const char* rname,const char* version,int reqId){
+
+  xmlNsPtr ns,ns_xsi;
+  xmlNodePtr n;
+
+  int vid=getVersionId(version);
+
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][2],"wps");
+  ns=usedNs[wpsId];
+  n = xmlNewNode(ns, BAD_CAST rname);
+  zooXmlAddNs(n,schemas[vid][1],"ows");
+  xmlNewNs(n,BAD_CAST schemas[vid][2],BAD_CAST "wps");
+  zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
+  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
+  ns_xsi=usedNs[xsiId];
+  char *tmp=(char*) malloc((86+strlen(req)+1)*sizeof(char));
+  sprintf(tmp,schemas[vid][4],schemas[vid][2],schemas[vid][3],req);
+  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST tmp);
+  free(tmp);
+  if(vid==0 || reqId==0){
+    xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
+    xmlNewProp(n,BAD_CAST "version",BAD_CAST schemas[vid][0]);
+  }
+  if(vid==0)
+    addLangAttr(n,m);
+  xmlNodePtr fn=soapEnvelope(m,n);
+  xmlDocSetRootElement(doc, fn);
+  return n;
+}
+
+void addLanguageNodes(maps* conf,xmlNodePtr n,xmlNsPtr ns,xmlNsPtr ns_ows){
+  xmlNodePtr nc1,nc2,nc3,nc4;
+  map* version=getMapFromMaps(conf,"main","rversion");
+  int vid=getVersionId(version->value);
+  if(vid==1)
+    nc1 = xmlNewNode(ns_ows, BAD_CAST "Languages");
+  else{
+    nc1 = xmlNewNode(ns, BAD_CAST "Languages");
+    nc2 = xmlNewNode(ns, BAD_CAST "Default");
+    nc3 = xmlNewNode(ns, BAD_CAST "Supported");
+  }
+
+  maps* tmp=getMaps(conf,"main");
+  if(tmp!=NULL){
+    map* tmp1=getMap(tmp->content,"lang");
+    char *toto=tmp1->value;
+    char buff[256];
+    int i=0;
+    int j=0;
+    int dcount=0;
+    while(toto[i]){
+      if(toto[i]!=',' && toto[i]!=0){
+	buff[j]=toto[i];
+	buff[j+1]=0;
+	j++;
+      }
+      else{
+	nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
+	xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
+	if(dcount==0){
+	  if(vid==0){
+	    xmlAddChild(nc2,nc4);
+	    xmlAddChild(nc1,nc2);
+	  }
+	  dcount++;
+	}
+	nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
+	xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
+	if(vid==0)
+	  xmlAddChild(nc3,nc4);
+	else
+	  xmlAddChild(nc1,nc4);
+	j=0;
+	buff[j]=0;
+      }
+      i++;
+    }
+    if(strlen(buff)>0){
+      nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
+      xmlAddChild(nc4,xmlNewText(BAD_CAST buff));	      
+	if(vid==0)
+	  xmlAddChild(nc3,nc4);
+	else
+	  xmlAddChild(nc1,nc4);
+    }
+  }
+  if(vid==0)
+    xmlAddChild(nc1,nc3);
+  xmlAddChild(n,nc1);
+}
+
+/**
+ * Generate a Capabilities header.
+ * 
+ * @param doc the document to add the header
+ * @param m the conf maps containing the main.cfg settings
+ * @return the generated wps:ProcessOfferings xmlNodePtr 
+ */
+xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr doc,maps* m,const char* version="1.0.0"){
+
+  xmlNsPtr ns,ns_ows,ns_xlink;
+  xmlNodePtr n,nc,nc1,nc2,nc3,nc4,nc5,nc6;
+  n = printWPSHeader(doc,m,"GetCapabilities","Capabilities",version,0);
+  maps* toto1=getMaps(m,"main");
+  char tmp[256];
+  map* v=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(v->value);
+
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][2],"wps");
+  ns=usedNs[wpsId];
+  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
+  ns_xlink=usedNs[xlinkId];
+  int owsId=zooXmlAddNs(NULL,schemas[vid][1],"ows");
+  ns_ows=usedNs[owsId];
+
+  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceIdentification");
+  maps* tmp4=getMaps(m,"identification");
+  if(tmp4!=NULL){
+    map* tmp2=tmp4->content;
+    const char *orderedFields[5];
+    orderedFields[0]="Title";
+    orderedFields[1]="Abstract";
+    orderedFields[2]="Keywords";
+    orderedFields[3]="Fees";
+    orderedFields[4]="AccessConstraints";
+    int oI=0;
+    for(oI=0;oI<5;oI++)
+      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
+	if(strcasecmp(tmp2->name,"abstract")==0 ||
+	   strcasecmp(tmp2->name,"title")==0 ||
+	   strcasecmp(tmp2->name,"accessConstraints")==0 ||
+	   strcasecmp(tmp2->name,"fees")==0){
+	  tmp2->name[0]=toupper(tmp2->name[0]);
+	  nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
+	  xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
+	  xmlAddChild(nc,nc1);
+	}
+	else
+	  if(strcmp(tmp2->name,"keywords")==0){
+	    nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
+	    char *toto=tmp2->value;
+	    char buff[256];
+	    int i=0;
+	    int j=0;
+	    while(toto[i]){
+	      if(toto[i]!=',' && toto[i]!=0){
+		buff[j]=toto[i];
+		buff[j+1]=0;
+		j++;
+	      }
+	      else{
+		nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
+		xmlAddChild(nc2,xmlNewText(BAD_CAST buff));	      
+		xmlAddChild(nc1,nc2);
+		j=0;
+	      }
+	      i++;
+	    }
+	    if(strlen(buff)>0){
+	      nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
+	      xmlAddChild(nc2,xmlNewText(BAD_CAST buff));	      
+	      xmlAddChild(nc1,nc2);
+	    }
+	    xmlAddChild(nc,nc1);
+	    nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceType");
+	    xmlAddChild(nc2,xmlNewText(BAD_CAST "WPS"));
+	    xmlAddChild(nc,nc2);
+	    nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceTypeVersion");
+	    dumpMaps(m);
+	    map* tmpv=getMapFromMaps(m,"main","rversion");
+	    xmlAddChild(nc2,xmlNewText(BAD_CAST tmpv->value));
+	    xmlAddChild(nc,nc2);
+	  }
+	tmp2=tmp2->next;
+      }
+  }
+  else{
+    fprintf(stderr,"TMP4 NOT FOUND !!");
+    return NULL;
+  }
+  xmlAddChild(n,nc);
+
+  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceProvider");
+  nc3 = xmlNewNode(ns_ows, BAD_CAST "ServiceContact");
+  nc4 = xmlNewNode(ns_ows, BAD_CAST "ContactInfo");
+  nc5 = xmlNewNode(ns_ows, BAD_CAST "Phone");
+  nc6 = xmlNewNode(ns_ows, BAD_CAST "Address");
+  tmp4=getMaps(m,"provider");
+  if(tmp4!=NULL){
+    map* tmp2=tmp4->content;
+    const char *tmpAddress[6];
+    tmpAddress[0]="addressDeliveryPoint";
+    tmpAddress[1]="addressCity";
+    tmpAddress[2]="addressAdministrativeArea";
+    tmpAddress[3]="addressPostalCode";
+    tmpAddress[4]="addressCountry";
+    tmpAddress[5]="addressElectronicMailAddress";
+    const char *tmpPhone[2];
+    tmpPhone[0]="phoneVoice";
+    tmpPhone[1]="phoneFacsimile";
+    const char *orderedFields[12];
+    orderedFields[0]="providerName";
+    orderedFields[1]="providerSite";
+    orderedFields[2]="individualName";
+    orderedFields[3]="positionName";
+    orderedFields[4]=tmpPhone[0];
+    orderedFields[5]=tmpPhone[1];
+    orderedFields[6]=tmpAddress[0];
+    orderedFields[7]=tmpAddress[1];
+    orderedFields[8]=tmpAddress[2];
+    orderedFields[9]=tmpAddress[3];
+    orderedFields[10]=tmpAddress[4];
+    orderedFields[11]=tmpAddress[5];
+    int oI=0;
+    for(oI=0;oI<12;oI++)
+      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
+	if(strcmp(tmp2->name,"keywords")!=0 &&
+	   strcmp(tmp2->name,"serverAddress")!=0 &&
+	   strcmp(tmp2->name,"lang")!=0){
+	  tmp2->name[0]=toupper(tmp2->name[0]);
+	  if(strcmp(tmp2->name,"ProviderName")==0){
+	    nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
+	    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
+	    xmlAddChild(nc,nc1);
+	  }
+	  else{
+	    if(strcmp(tmp2->name,"ProviderSite")==0){
+	      nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
+	      xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST tmp2->value);
+	      xmlAddChild(nc,nc1);
+	    } 
+	    else  
+	      if(strcmp(tmp2->name,"IndividualName")==0 || 
+		 strcmp(tmp2->name,"PositionName")==0){
+		nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
+		xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
+		xmlAddChild(nc3,nc1);
+	      } 
+	      else 
+		if(strncmp(tmp2->name,"Phone",5)==0){
+		  int j;
+		  for(j=0;j<2;j++)
+		    if(strcasecmp(tmp2->name,tmpPhone[j])==0){
+		      char *tmp4=tmp2->name;
+		      nc1 = xmlNewNode(ns_ows, BAD_CAST tmp4+5);
+		      xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
+		      xmlAddChild(nc5,nc1);
+		    }
+		}
+		else 
+		  if(strncmp(tmp2->name,"Address",7)==0){
+		    int j;
+		    for(j=0;j<6;j++)
+		      if(strcasecmp(tmp2->name,tmpAddress[j])==0){
+			char *tmp4=tmp2->name;
+			nc1 = xmlNewNode(ns_ows, BAD_CAST tmp4+7);
+			xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
+			xmlAddChild(nc6,nc1);
+		      }
+		  }
+	  }
+	}
+	else
+	  if(strcmp(tmp2->name,"keywords")==0){
+	    nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
+	    char *toto=tmp2->value;
+	    char buff[256];
+	    int i=0;
+	    int j=0;
+	    while(toto[i]){
+	      if(toto[i]!=',' && toto[i]!=0){
+		buff[j]=toto[i];
+		buff[j+1]=0;
+		j++;
+	      }
+	      else{
+		nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
+		xmlAddChild(nc2,xmlNewText(BAD_CAST buff));	      
+		xmlAddChild(nc1,nc2);
+		j=0;
+	      }
+	      i++;
+	    }
+	    if(strlen(buff)>0){
+	      nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
+	      xmlAddChild(nc2,xmlNewText(BAD_CAST buff));	      
+	      xmlAddChild(nc1,nc2);
+	    }
+	    xmlAddChild(nc,nc1);
+	  }
+	tmp2=tmp2->next;
+      }
+  }
+  else{
+    fprintf(stderr,"TMP4 NOT FOUND !!");
+  }
+  xmlAddChild(nc4,nc5);
+  xmlAddChild(nc4,nc6);
+  xmlAddChild(nc3,nc4);
+  xmlAddChild(nc,nc3);
+  xmlAddChild(n,nc);
+
+
+  nc = xmlNewNode(ns_ows, BAD_CAST "OperationsMetadata");
+
+  int j=0;
+
+  if(toto1!=NULL){
+    map* tmp=getMap(toto1->content,"serverAddress");
+    if(tmp!=NULL){
+      SERVICE_URL = strdup(tmp->value);
+    }
+    else
+      SERVICE_URL = strdup("not_defined");
+  }
+  else
+    SERVICE_URL = strdup("not_defined");
+
+  for(j=0;j<nbSupportedRequests;j++){
+    if(requests[vid][j]==NULL)
+      break;
+    else{
+      nc1 = xmlNewNode(ns_ows, BAD_CAST "Operation");
+      xmlNewProp(nc1,BAD_CAST "name",BAD_CAST requests[vid][j]);
+      nc2 = xmlNewNode(ns_ows, BAD_CAST "DCP");
+      nc3 = xmlNewNode(ns_ows, BAD_CAST "HTTP");
+      if(vid!=1 || j!=2){
+	nc4 = xmlNewNode(ns_ows, BAD_CAST "Get");
+	xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST SERVICE_URL);
+	xmlAddChild(nc3,nc4);
+      }
+      nc4 = xmlNewNode(ns_ows, BAD_CAST "Post");
+      xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST SERVICE_URL);
+      xmlAddChild(nc3,nc4);
+      xmlAddChild(nc2,nc3);
+      xmlAddChild(nc1,nc2);
+      xmlAddChild(nc,nc1);
+    }
+  }
+  xmlAddChild(n,nc);
+
+  if(vid==1)
+    addLanguageNodes(m,n,ns,ns_ows);
+  free(SERVICE_URL);
+
+  nc = xmlNewNode(ns, BAD_CAST root_nodes[vid][0]);
+  xmlAddChild(n,nc);
+
+  if(vid==0)
+    addLanguageNodes(m,n,ns,ns_ows);
+
+  return nc;
+}
+
+/**
+ * Generate a wps:Process node for a servie and add it to a given node.
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param registry the profile registry if any
+ * @param nc the XML node to add the Process node
+ * @param serv the service structure created from the zcfg file
+ * @return the generated wps:ProcessOfferings xmlNodePtr 
+ */
+void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
+  xmlNsPtr ns,ns_ows,ns_xml,ns_xlink;
+  xmlNodePtr n=NULL,nc1,nc2;
+  map* version=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(version->value);
+  // Initialize or get existing namespaces
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][2],"wps");
+  ns=usedNs[wpsId];
+  int owsId=zooXmlAddNs(NULL,schemas[vid][1],"ows");
+  ns_ows=usedNs[owsId];
+  int xmlId=zooXmlAddNs(NULL,"http://www.w3.org/XML/1998/namespace","xml");
+  ns_xml=usedNs[xmlId];
+  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
+  ns_xlink=usedNs[xlinkId];
+  map* tmp1;
+  if(serv->content!=NULL){
+    nc1 = xmlNewNode(ns, BAD_CAST capabilities[vid][0]);
+    int i=1;
+    int limit=3;
+    if(vid==1){
+      ns=NULL;
+      limit=7;
+    }
+    for(;i<limit;i+=2){
+      if(capabilities[vid][i]==NULL)
+	break;
+      else{
+	tmp1=getMap(serv->content,capabilities[vid][i]);
+	if(tmp1!=NULL){
+	  if(vid==1 && i==1 && strlen(tmp1->value)<5){
+	    char *val=(char*)malloc((strlen(tmp1->value)+5)*sizeof(char));
+	    sprintf(val,"%s.0.0",tmp1->value);
+	    xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST val);
+	    free(val);
+	  }
+	  else
+	    xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value);
+	}
+	else
+	  xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]);
+      }
+    }
+    map* tmp3=getMapFromMaps(m,"lenv","level");
+    addPrefix(m,tmp3,serv);
+    printDescription(nc1,ns_ows,serv->name,serv->content,vid);
+    tmp1=serv->metadata;
+    while(tmp1!=NULL){
+      nc2 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
+      xmlNewNsProp(nc2,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
+      xmlAddChild(nc1,nc2);
+      tmp1=tmp1->next;
+    }
+
+    xmlAddChild(nc,nc1);
+  }
+}
+
+void attachAttributes(xmlNodePtr n,xmlNsPtr ns,map* content,int vid){
+  xmlNodePtr nc1;
+  int limit=(vid==1?7:3);
+  for(int i=1;i<limit;i+=2){
+    map* tmp1=getMap(content,capabilities[vid][i]);
+    if(tmp1!=NULL){
+      if(vid==1 && i==1 && strlen(tmp1->value)<5){
+	char *val=(char*)malloc((strlen(tmp1->value)+5)*sizeof(char));
+	sprintf(val,"%s.0.0",tmp1->value);
+	xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST val);
+	free(val);
+      }
+      else
+	xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value);
+    }
+    else
+      xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]);
+  }
+}
+
+/**
+ * Generate a ProcessDescription node for a servie and add it to a given node.
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param nc the XML node to add the Process node
+ * @param serv the servive structure created from the zcfg file
+ * @return the generated wps:ProcessOfferings xmlNodePtr 
+ */
+void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv){
+  xmlNsPtr ns,ns_ows,ns_xlink;
+  xmlNodePtr n,nc1,nc2;
+  map* version=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(version->value);
+
+  n=nc;
+  
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][3],"wps");
+  ns=usedNs[wpsId];
+  int owsId=zooXmlAddNs(NULL,schemas[vid][1],"ows");
+  ns_ows=usedNs[owsId];
+  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
+  ns_xlink=usedNs[xlinkId];
+  map* tmp1=NULL;
+
+  if(vid==0){
+    nc = xmlNewNode(NULL, BAD_CAST "ProcessDescription");
+    attachAttributes(nc,ns,serv->content,vid);
+  }
+  else{
+    nc2 = xmlNewNode(ns, BAD_CAST "ProcessOffering");
+    attachAttributes(nc2,NULL,serv->content,vid);
+    nc = xmlNewNode(ns, BAD_CAST "Process");
+  }
+  /*
+  const char *tmp4[3];
+  tmp4[0]="processVersion";
+  tmp4[1]="storeSupported";
+  tmp4[2]="statusSupported";
+  int j=0;
+  for(j=0;j<3;j++){
+    tmp1=getMap(serv->content,tmp4[j]);
+    if(tmp1!=NULL){
+      if(j==0)
+	xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);      
+      else
+	xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);      
+    }
+    else{
+      if(j>0)
+	xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "true");
+      else
+	xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST "1");
+    }
+  }
+  */
+  
+  tmp1=getMapFromMaps(m,"lenv","level");
+  addPrefix(m,tmp1,serv);
+  printDescription(nc,ns_ows,serv->name,serv->content,vid);
+
+  tmp1=serv->metadata;
+  while(tmp1!=NULL){
+    nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
+    xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
+    xmlAddChild(nc,nc1);
+    tmp1=tmp1->next;
+  }
+
+  tmp1=getMap(serv->content,"Profile");
+  if(tmp1!=NULL && vid==0){
+    nc1 = xmlNewNode(ns, BAD_CAST "Profile");
+    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
+    xmlAddChild(nc,nc1);
+  }
+
+  if(serv->inputs!=NULL){
+    elements* e=serv->inputs;
+    if(vid==0){
+      nc1 = xmlNewNode(NULL, BAD_CAST "DataInputs");
+      printFullDescription(1,e,"Input",ns,ns_ows,nc1,vid);
+      xmlAddChild(nc,nc1);
+    }
+    else{
+      printFullDescription(1,e,"wps:Input",ns,ns_ows,nc,vid);
+    }
+  }
+
+  elements* e=serv->outputs;
+  if(vid==0){
+    nc1 = xmlNewNode(NULL, BAD_CAST "ProcessOutputs");
+    printFullDescription(0,e,"Output",ns,ns_ows,nc1,vid);
+    xmlAddChild(nc,nc1);
+  }
+  else{
+    printFullDescription(0,e,"wps:Output",ns,ns_ows,nc,vid);
+  }
+  if(vid==0)
+    xmlAddChild(n,nc);
+  else{
+    xmlAddChild(nc2,nc);
+    xmlAddChild(n,nc2);
+  }
+
+}
+
+/**
+ * Generate the required XML tree for the detailled metadata informations of 
+ * inputs or outputs
+ *
+ * @param in 1 in case of inputs, 0 for outputs
+ * @param elem the elements structure containing the metadata informations
+ * @param type the name ("Input" or "Output") of the XML node to create
+ * @param ns_ows the ows XML namespace
+ * @param nc1 the XML node to use to add the created tree
+ */
+void printFullDescription(int in,elements *elem,const char* type,xmlNsPtr ns,xmlNsPtr ns_ows,xmlNodePtr nc1,int vid){
+  xmlNsPtr ns1=NULL;
+  if(vid==1)
+    ns1=ns;
+  const char *orderedFields[13];
+  orderedFields[0]="mimeType";
+  orderedFields[1]="encoding";
+  orderedFields[2]="schema";
+  orderedFields[3]="dataType";
+  orderedFields[4]="uom";
+  orderedFields[5]="CRS";
+  orderedFields[6]="value";
+  orderedFields[7]="AllowedValues";
+  orderedFields[8]="range";
+  orderedFields[9]="rangeMin";
+  orderedFields[10]="rangeMax";
+  orderedFields[11]="rangeClosure";
+  orderedFields[12]="rangeSpace";
+
+  xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8,nc9;
+  elements* e=elem;
+  nc9=NULL;
+  map* tmp1=NULL;
+  while(e!=NULL){
+    int default1=0;
+    int isAnyValue=1;
+    nc2 = xmlNewNode(NULL, BAD_CAST type);
+    if(strncmp(type,"Input",5)==0){
+      tmp1=getMap(e->content,"minOccurs");
+      if(tmp1!=NULL){
+	xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
+      }else
+	xmlNewProp(nc2,BAD_CAST "minOccurs",BAD_CAST "0");
+      tmp1=getMap(e->content,"maxOccurs");
+      if(tmp1!=NULL){
+	if(strcasecmp(tmp1->value,"unbounded")!=0)
+	  xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
+	else
+	  xmlNewProp(nc2,BAD_CAST "maxOccurs",BAD_CAST "1000");
+      }else
+	xmlNewProp(nc2,BAD_CAST "maxOccurs",BAD_CAST "1");
+      if((tmp1=getMap(e->content,"maximumMegabytes"))!=NULL){
+	xmlNewProp(nc2,BAD_CAST "maximumMegabytes",BAD_CAST tmp1->value);
+      }
+    }
+
+    printDescription(nc2,ns_ows,e->name,e->content,vid);
+
+    /**
+     * Build the (Literal/Complex/BoundingBox)Data node
+     */
+    if(strncmp(type,"Output",6)==0){
+      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
+	nc3 = xmlNewNode(ns1, BAD_CAST "LiteralOutput");
+      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
+	nc3 = xmlNewNode(ns1, BAD_CAST "ComplexOutput");
+      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
+	nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxOutput");
+      else
+	nc3 = xmlNewNode(ns1, BAD_CAST e->format);
+    }else{
+      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0 ||
+	 strncasecmp(e->format,"LITERALOUTPUT",strlen(e->format))==0){
+	nc3 = xmlNewNode(ns1, BAD_CAST "LiteralData");
+      }
+      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
+	nc3 = xmlNewNode(ns1, BAD_CAST "ComplexData");
+      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
+	nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxData");
+      else
+	nc3 = xmlNewNode(ns1, BAD_CAST e->format);
+    }
+
+    iotype* _tmp0=NULL;
+    iotype* _tmp=e->defaults;
+    int datatype=0;
+    bool hasUOM=false;
+    bool hasUOM1=false;
+    if(_tmp!=NULL){
+      if(strcmp(e->format,"LiteralOutput")==0 ||
+	 strcmp(e->format,"LiteralData")==0){
+     	datatype=1;
+	if(vid==1){
+	  nc4 = xmlNewNode(ns1, BAD_CAST "Format");
+	  xmlNewProp(nc4,BAD_CAST "mimeType",BAD_CAST "text/plain");
+	  xmlNewProp(nc4,BAD_CAST "default",BAD_CAST "true");
+	  xmlAddChild(nc3,nc4);
+	  nc5 = xmlNewNode(NULL, BAD_CAST "LiteralDataDomain");
+	  xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
+	}
+	else{
+	  nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
+	  nc5 = xmlNewNode(NULL, BAD_CAST "Default");
+	}
+      }
+      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
+	      strcmp(e->format,"BoundingBoxData")==0){
+	datatype=2;
+	nc5 = xmlNewNode(NULL, BAD_CAST "Default");
+      }
+      else{
+	if(vid==0)
+	  nc4 = xmlNewNode(NULL, BAD_CAST "Default");
+	nc5 = xmlNewNode(ns1, BAD_CAST "Format");
+	if(vid==1){
+	  xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
+	  int oI=0;
+	  for(oI=0;oI<3;oI++)
+	    if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+	      xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+	    }
+	}
+      }
+      
+      tmp1=_tmp->content;
+
+      if(vid==0)
+	if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
+	  nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
+	  xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
+	  char tmp[1024];
+	  sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
+	  xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
+	  if(vid==0)
+	    xmlAddChild(nc3,nc8);
+	  else
+	    xmlAddChild(nc5,nc8);
+	  datatype=1;
+	}
+
+      bool isInput=false;
+      if(strncmp(type,"Input",5)==0 || strncmp(type,"wps:Input",9)==0){
+	isInput=true;
+	if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){
+	  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
+	  char *token,*saveptr1;
+	  token=strtok_r(tmp1->value,",",&saveptr1);
+	  while(token!=NULL){
+	    nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	    char *tmps=strdup(token);
+	    tmps[strlen(tmps)]=0;
+	    xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
+	    free(tmps);
+	    xmlAddChild(nc6,nc7);
+	    token=strtok_r(NULL,",",&saveptr1);
+	  }
+	  if(getMap(_tmp->content,"range")!=NULL ||
+	     getMap(_tmp->content,"rangeMin")!=NULL ||
+	     getMap(_tmp->content,"rangeMax")!=NULL ||
+	     getMap(_tmp->content,"rangeClosure")!=NULL )
+	    goto doRange;
+	  if(vid==0)
+	    xmlAddChild(nc3,nc6);
+	  else
+	    xmlAddChild(nc5,nc6);
+	  isAnyValue=-1;
+	}
+
+        tmp1=getMap(_tmp->content,"range");
+	if(tmp1==NULL)
+	  tmp1=getMap(_tmp->content,"rangeMin");
+	if(tmp1==NULL)
+	  tmp1=getMap(_tmp->content,"rangeMax");
+	
+	if(tmp1!=NULL && isAnyValue==1){
+	  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
+	doRange:
+	  
+	  /**
+	   * Range: Table 46 OGC Web Services Common Standard
+	   */
+	  nc8 = xmlNewNode(ns_ows, BAD_CAST "Range");
+	  
+	  map* tmp0=getMap(tmp1,"range");
+	  if(tmp0!=NULL){
+	    char* pToken;
+	    char* orig=zStrdup(tmp0->value);
+	    /**
+	     * RangeClosure: Table 47 OGC Web Services Common Standard
+	     */
+	    const char *tmp="closed";
+	    if(orig[0]=='[' && orig[strlen(orig)-1]=='[')
+	      tmp="closed-open";
+	    else
+	      if(orig[0]==']' && orig[strlen(orig)-1]==']')
+		tmp="open-closed";
+	      else
+		if(orig[0]==']' && orig[strlen(orig)-1]=='[')
+		  tmp="open";
+	    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
+	    pToken=strtok(orig,",");
+	    int nci0=0;
+	    while(pToken!=NULL){
+	      char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char));
+	      if(nci0==0){
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+		strncpy( tmpStr, pToken+1, strlen(pToken)-1 );
+		tmpStr[strlen(pToken)-1] = '\0';
+	      }else{
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+		const char* bkt;
+		if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){
+		  strncpy( tmpStr, pToken, bkt - pToken );
+		  tmpStr[bkt - pToken] = '\0';
+		}
+	      }
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
+	      free(tmpStr);
+	      xmlAddChild(nc8,nc7);
+	      nci0++;
+	      pToken = strtok(NULL,",");
+	    }		    
+	    if(getMap(tmp1,"rangeSpacing")==NULL){
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST "1"));
+	      xmlAddChild(nc8,nc7);
+	    }
+	    free(orig);
+	  }else{
+	    
+	    tmp0=getMap(tmp1,"rangeMin");
+	    if(tmp0!=NULL){
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+	      xmlAddChild(nc8,nc7);
+	    }else{
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+	      xmlAddChild(nc8,nc7);
+	    }
+	    tmp0=getMap(tmp1,"rangeMax");
+	    if(tmp0!=NULL){
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+	      xmlAddChild(nc8,nc7);
+	    }else{
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+	      xmlAddChild(nc8,nc7);
+	    }
+	    tmp0=getMap(tmp1,"rangeSpacing");
+	    if(tmp0!=NULL){
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+	      xmlAddChild(nc8,nc7);
+	    }
+	    tmp0=getMap(tmp1,"rangeClosure");
+	    if(tmp0!=NULL){
+	      const char *tmp="closed";
+	      if(strcasecmp(tmp0->value,"co")==0)
+		tmp="closed-open";
+	      else
+		if(strcasecmp(tmp0->value,"oc")==0)
+		  tmp="open-closed";
+		else
+		  if(strcasecmp(tmp0->value,"o")==0)
+		    tmp="open";
+	      xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
+	    }else
+	      xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
+	  }
+	  if(_tmp0==NULL){
+	    xmlAddChild(nc6,nc8);
+	    _tmp0=e->supported;
+	    if(_tmp0!=NULL &&
+	       (getMap(_tmp0->content,"range")!=NULL ||
+		getMap(_tmp0->content,"rangeMin")!=NULL ||
+		getMap(_tmp0->content,"rangeMax")!=NULL ||
+		getMap(_tmp0->content,"rangeClosure")!=NULL )){
+	      tmp1=_tmp0->content;
+	      goto doRange;
+	    }
+	  }else{
+	    _tmp0=_tmp0->next;
+	    if(_tmp0!=NULL){
+	      xmlAddChild(nc6,nc8);
+	      if(getMap(_tmp0->content,"range")!=NULL ||
+		 getMap(_tmp0->content,"rangeMin")!=NULL ||
+		 getMap(_tmp0->content,"rangeMax")!=NULL ||
+		 getMap(_tmp0->content,"rangeClosure")!=NULL ){
+		tmp1=_tmp0->content;
+		goto doRange;
+	      }
+	    }
+	  }
+	  xmlAddChild(nc6,nc8);
+	  if(vid==0)
+	    xmlAddChild(nc3,nc6);
+	  else
+	    xmlAddChild(nc5,nc6);
+	  isAnyValue=-1;
+	}
+	
+      }
+      
+      int oI=0;
+      /*if(vid==0)*/ {
+	for(oI=0;oI<13;oI++)
+	  if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+#ifdef DEBUG
+	    printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
+#endif
+	    if(strcmp(tmp1->name,"asReference")!=0 &&
+	       strncasecmp(tmp1->name,"DataType",8)!=0 &&
+	       strcasecmp(tmp1->name,"extension")!=0 &&
+	       strcasecmp(tmp1->name,"value")!=0 &&
+	       strcasecmp(tmp1->name,"AllowedValues")!=0 &&
+	       strncasecmp(tmp1->name,"range",5)!=0){
+	      if(datatype!=1){
+		char *tmp2=zCapitalize1(tmp1->name);
+		nc9 = xmlNewNode(NULL, BAD_CAST tmp2);
+		free(tmp2);
+	      }
+	      else{
+		char *tmp2=zCapitalize(tmp1->name);
+		nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+		free(tmp2);
+	      }
+	      xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+	      if(vid==0 || oI>=3){
+		if(vid==0 || oI!=4)
+		  xmlAddChild(nc5,nc9);
+		if(oI==4 && vid==1){
+		  xmlNewProp(nc9,BAD_CAST "default",BAD_CAST "true");
+		}
+	      }
+	      else
+		xmlFree(nc9);
+	      if(strcasecmp(tmp1->name,"uom")==0)
+		hasUOM1=true;
+	      hasUOM=true;
+	    }else 	  
+	      tmp1=tmp1->next;
+	  }
+      }
+    
+      if(datatype!=2){
+	if(hasUOM==true){
+	  if(vid==0){
+	    xmlAddChild(nc4,nc5);
+	    xmlAddChild(nc3,nc4);
+	  }
+	  else{
+	    xmlAddChild(nc3,nc5);
+	  }
+	}else{
+	  if(hasUOM1==false && vid==0){
+	    xmlFreeNode(nc5);
+	    if(datatype==1)
+	      xmlFreeNode(nc4);
+	  }
+	  else
+	    xmlAddChild(nc3,nc5);
+	}
+      }else{
+	xmlAddChild(nc3,nc5);
+      }
+      
+      if(datatype!=1 && default1<0){
+	xmlFreeNode(nc5);
+	if(datatype!=2)
+	  xmlFreeNode(nc4);
+      }
+
+
+      if((isInput || vid==1) && datatype==1 &&
+	 getMap(_tmp->content,"AllowedValues")==NULL &&
+	 getMap(_tmp->content,"range")==NULL &&
+	 getMap(_tmp->content,"rangeMin")==NULL &&
+	 getMap(_tmp->content,"rangeMax")==NULL &&
+	 getMap(_tmp->content,"rangeClosure")==NULL ){
+	tmp1=getMap(_tmp->content,"dataType");
+	// We were tempted to define default value for boolean as {true,false}
+	if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){
+	  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
+	  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	  xmlAddChild(nc7,xmlNewText(BAD_CAST "true"));
+	  xmlAddChild(nc6,nc7);
+	  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	  xmlAddChild(nc7,xmlNewText(BAD_CAST "false"));
+	  xmlAddChild(nc6,nc7);
+	  if(vid==0)
+	    xmlAddChild(nc3,nc6);
+	  else
+	    xmlAddChild(nc5,nc6);
+	}
+	else
+	if(vid==0)
+	  xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
+	else
+	  xmlAddChild(nc5,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
+      }
+
+      if(vid==1){
+	if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
+	  nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
+	  xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
+	  char tmp[1024];
+	  sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
+	  xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
+	  if(vid==0)
+	    xmlAddChild(nc3,nc8);
+	  else
+	    xmlAddChild(nc5,nc8);
+	  datatype=1;
+	}
+	if(hasUOM==true){
+	  tmp1=getMap(_tmp->content,"uom");
+	  if(tmp1!=NULL){
+	    char *tmp2=zCapitalize(tmp1->name);
+	    nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+	    free(tmp2);
+	    //xmlNewProp(nc9, BAD_CAST "default", BAD_CAST "true");
+	    xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+	    xmlAddChild(nc5,nc9);
+	    /*struct iotype * _ltmp=e->supported;
+	    while(_ltmp!=NULL){
+	      tmp1=getMap(_ltmp->content,"uom");
+	      if(tmp1!=NULL){
+		char *tmp2=zCapitalize(tmp1->name);
+		nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+		free(tmp2);
+		xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+		xmlAddChild(nc5,nc9);
+	      }
+	      _ltmp=_ltmp->next;
+	      }*/
+	    
+	  }
+	}
+	if(e->defaults!=NULL && (tmp1=getMap(e->defaults->content,"value"))!=NULL){
+	  nc7 = xmlNewNode(ns_ows, BAD_CAST "DefaultValue");
+	  xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
+	  xmlAddChild(nc5,nc7);
+	}
+      }
+
+      map* metadata=e->metadata;
+      xmlNodePtr n=NULL;
+      int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
+      xmlNsPtr ns_xlink=usedNs[xlinkId];
+
+      while(metadata!=NULL){
+	nc6=xmlNewNode(ns_ows, BAD_CAST "Metadata");
+	xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value);
+	xmlAddChild(nc2,nc6);
+	metadata=metadata->next;
+      }
+
+    }
+
+    _tmp=e->supported;
+    if(_tmp==NULL && datatype!=1)
+      _tmp=e->defaults;
+
+    int hasSupported=-1;
+
+    while(_tmp!=NULL){
+      if(hasSupported<0){
+	if(datatype==0){
+	  if(vid==0)
+	    nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
+	  nc5 = xmlNewNode(ns1, BAD_CAST "Format");
+	  if(vid==1){
+	    int oI=0;
+	    for(oI=0;oI<3;oI++)
+	      if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+		xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+	      }
+	  }
+	}
+	else
+	  if(vid==0)
+	    nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
+	hasSupported=0;
+      }else
+	if(datatype==0){
+	  nc5 = xmlNewNode(ns1, BAD_CAST "Format");
+	  if(vid==1){
+	    int oI=0;
+	    for(oI=0;oI<3;oI++)
+	      if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+		xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+	      }
+	  }
+	}
+      tmp1=_tmp->content;
+      int oI=0;
+      for(oI=0;oI<6;oI++)
+	if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+#ifdef DEBUG
+	  printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
+#endif
+	  if(strcmp(tmp1->name,"asReference")!=0 && 
+	     strcmp(tmp1->name,"value")!=0 && 
+	     strcmp(tmp1->name,"DataType")!=0 &&
+	     strcasecmp(tmp1->name,"extension")!=0){
+	    if(datatype!=1){
+	      char *tmp2=zCapitalize1(tmp1->name);
+	      nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
+	      free(tmp2);
+	    }
+	    else{
+	      char *tmp2=zCapitalize(tmp1->name);
+	      nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+	      free(tmp2);
+	    }
+	    if(datatype==2){
+	      char *tmpv,*tmps;
+	      tmps=strtok_r(tmp1->value,",",&tmpv);
+	      while(tmps){
+		xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
+		tmps=strtok_r(NULL,",",&tmpv);
+		if(tmps){
+		  char *tmp2=zCapitalize1(tmp1->name);
+		  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
+		  free(tmp2);
+		}
+	      }
+	    }
+	    else{
+	      xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
+	    }
+	    if(vid==0 || oI>=3){
+	      if(vid==0 || oI!=4)
+		xmlAddChild(nc5,nc6);
+	      else
+		xmlFree(nc6);
+	    }
+	    else
+	      xmlFree(nc6);
+	  }
+	  tmp1=tmp1->next;
+	}
+      if(hasSupported<=0){
+	if(datatype==0){
+	  if(vid==0){
+	    xmlAddChild(nc4,nc5);
+	    xmlAddChild(nc3,nc4);
+	  }
+	  else{
+	    xmlAddChild(nc3,nc5);
+	  }
+
+	}else{
+	  if(datatype!=1)
+	    xmlAddChild(nc3,nc5);
+	}
+	hasSupported=1;
+      }
+      else
+	if(datatype==0){
+	  if(vid==0){
+	    xmlAddChild(nc4,nc5);
+	    xmlAddChild(nc3,nc4);
+	  }
+	  else{
+	    xmlAddChild(nc3,nc5);
+	  }
+	}
+	else
+	  if(datatype!=1)
+	    xmlAddChild(nc3,nc5);
+
+      _tmp=_tmp->next;
+    }
+
+    if(hasSupported==0){
+      if(datatype==0 && vid!=0)
+	xmlFreeNode(nc4);
+      xmlFreeNode(nc5);
+    }
+
+    _tmp=e->defaults;
+    if(datatype==1 && hasUOM1==true){
+      if(vid==0){
+	xmlAddChild(nc4,nc5);
+	xmlAddChild(nc3,nc4);
+      }
+      else{
+	xmlAddChild(nc3,nc5);
+      }
+    }
+
+    if(vid==0 && _tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){
+      nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
+      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
+      xmlAddChild(nc3,nc7);
+    }
+    
+    xmlAddChild(nc2,nc3);
+    
+    xmlAddChild(nc1,nc2);
+    
+    e=e->next;
+  }
+}
+
+/**
+ * Generate a wps:Execute XML document.
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param request the map representing the HTTP request
+ * @param pid the process identifier linked to a service
+ * @param serv the serv structure created from the zcfg file
+ * @param service the service name
+ * @param status the status returned by the service
+ * @param inputs the inputs provided
+ * @param outputs the outputs generated by the service
+ */
+void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
+  xmlNsPtr ns,ns_ows,ns_xlink;
+  xmlNodePtr nr,n,nc,nc1=NULL,nc3;
+  xmlDocPtr doc;
+  time_t time1;  
+  time(&time1);
+  nr=NULL;
+
+  doc = xmlNewDoc(BAD_CAST "1.0");
+  map* version=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(version->value);
+  n = printWPSHeader(doc,m,"Execute",root_nodes[vid][2],(version!=NULL?version->value:"1.0.0"),2);
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][2],"wps");
+  ns=usedNs[wpsId];
+  int owsId=zooXmlAddNs(NULL,schemas[vid][1],"ows");
+  ns_ows=usedNs[owsId];
+  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
+  ns_xlink=usedNs[xlinkId];
+  bool hasStoredExecuteResponse=false;
+  char stored_path[1024];
+  memset(stored_path,0,1024);
+    
+  if(vid==0){
+    char tmp[256];
+    char url[1024];
+    memset(tmp,0,256);
+    memset(url,0,1024);
+    maps* tmp_maps=getMaps(m,"main");
+    if(tmp_maps!=NULL){
+      map* tmpm1=getMap(tmp_maps->content,"serverAddress");
+      /**
+       * Check if the ZOO Service GetStatus is available in the local directory.
+       * If yes, then it uses a reference to an URL which the client can access
+       * to get information on the status of a running Service (using the 
+       * percentCompleted attribute). 
+       * Else fallback to the initial method using the xml file to write in ...
+       */
+      char ntmp[1024];
+#ifndef WIN32
+      getcwd(ntmp,1024);
+#else
+      _getcwd(ntmp,1024);
+#endif
+      struct stat myFileInfo;
+      int statRes;
+      char file_path[1024];
+      sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
+      statRes=stat(file_path,&myFileInfo);
+      if(statRes==0){
+	char currentSid[128];
+	map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
+	map *tmp_lenv=NULL;
+	tmp_lenv=getMapFromMaps(m,"lenv","usid");
+	if(tmp_lenv==NULL)
+	  sprintf(currentSid,"%i",pid);
+	else
+	  sprintf(currentSid,"%s",tmp_lenv->value);
+	if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
+	  sprintf(url,"%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
+	}else{
+	  if(strlen(tmpm->value)>0)
+	    if(strcasecmp(tmpm->value,"true")!=0)
+	      sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
+	    else
+	      sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
+	  else
+	    sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
+	}
+      }else{
+	int lpid;
+	map* tmpm2=getMapFromMaps(m,"lenv","usid");
+	map* tmpm3=getMap(tmp_maps->content,"tmpUrl");
+	if(tmpm1!=NULL && tmpm3!=NULL){
+	  if( strncasecmp( tmpm3->value, "http://", 7) == 0 ||
+	      strncasecmp( tmpm3->value, "https://", 8 ) == 0 ){
+	    sprintf(url,"%s/%s_%s.xml",tmpm3->value,service,tmpm2->value);
+	  }else
+	    sprintf(url,"%s/%s_%s.xml",tmpm1->value,service,tmpm2->value);
+	}
+      }
+      if(tmpm1!=NULL){
+	sprintf(tmp,"%s",tmpm1->value);
+      }
+      int lpid;
+      map* tmpm2=getMapFromMaps(m,"lenv","usid");
+      tmpm1=getMapFromMaps(m,"main","TmpPath");
+      sprintf(stored_path,"%s/%s_%s.xml",tmpm1->value,service,tmpm2->value);
+    }
+
+    xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
+    map* test=getMap(request,"storeExecuteResponse");
+    if(test!=NULL && strcasecmp(test->value,"true")==0){
+      xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
+      hasStoredExecuteResponse=true;
+    }
+
+    nc = xmlNewNode(ns, BAD_CAST "Process");
+    map* tmp2=getMap(serv->content,"processVersion");
+    if(tmp2!=NULL)
+      xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
+  
+    map* tmpI=getMapFromMaps(m,"lenv","oIdentifier");
+    printDescription(nc,ns_ows,tmpI->value,serv->content,0);
+
+    xmlAddChild(n,nc);
+
+    nc = xmlNewNode(ns, BAD_CAST "Status");
+    const struct tm *tm;
+    size_t len;
+    time_t now;
+    char *tmp1;
+    map *tmpStatus;
+  
+    now = time ( NULL );
+    tm = localtime ( &now );
+
+    tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
+
+    len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
+
+    xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
+
+    char sMsg[2048];
+    switch(status){
+    case SERVICE_SUCCEEDED:
+      nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
+      sprintf(sMsg,_("The service \"%s\" ran successfully."),serv->name);
+      nc3=xmlNewText(BAD_CAST sMsg);
+      xmlAddChild(nc1,nc3);
+      break;
+    case SERVICE_STARTED:
+      nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
+      tmpStatus=getMapFromMaps(m,"lenv","status");
+      xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
+      sprintf(sMsg,_("The ZOO service \"%s\" is currently running. Please reload this document to get the up-to-date status of the service."),serv->name);
+      nc3=xmlNewText(BAD_CAST sMsg);
+      xmlAddChild(nc1,nc3);
+      break;
+    case SERVICE_ACCEPTED:
+      nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
+      sprintf(sMsg,_("The service \"%s\" was accepted by the ZOO kernel and is running as a background task. Please access the URL in the statusLocation attribute provided in this document to get the up-to-date status and results."),serv->name);
+      nc3=xmlNewText(BAD_CAST sMsg);
+      xmlAddChild(nc1,nc3);
+      break;
+    case SERVICE_FAILED:
+      nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
+      map *errorMap;
+      map *te;
+      te=getMapFromMaps(m,"lenv","code");
+      if(te!=NULL)
+	errorMap=createMap("code",te->value);
+      else
+	errorMap=createMap("code","NoApplicableCode");
+      te=getMapFromMaps(m,"lenv","message");
+      if(te!=NULL)
+	addToMap(errorMap,"text",_ss(te->value));
+      else
+	addToMap(errorMap,"text",_("No more information available"));
+      nc3=createExceptionReportNode(m,errorMap,0);
+      freeMap(&errorMap);
+      free(errorMap);
+      xmlAddChild(nc1,nc3);
+      break;
+    default :
+      printf(_("error code not know : %i\n"),status);
+      //exit(1);
+      break;
+    }
+    xmlAddChild(nc,nc1);
+    xmlAddChild(n,nc);
+    free(tmp1);
+
+#ifdef DEBUG
+    fprintf(stderr,"printProcessResponse %d\n",__LINE__);
+#endif
+
+    map* lineage=getMap(request,"lineage");
+    if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
+      nc = xmlNewNode(ns, BAD_CAST "DataInputs");
+      maps* mcursor=inputs;
+      elements* scursor=NULL;
+      while(mcursor!=NULL /*&& scursor!=NULL*/){
+	scursor=getElements(serv->inputs,mcursor->name);
+	printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input",vid);
+	mcursor=mcursor->next;
+      }
+      xmlAddChild(n,nc);
+
+      nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
+      mcursor=outputs;
+      scursor=NULL;
+      while(mcursor!=NULL){
+	scursor=getElements(serv->outputs,mcursor->name);
+	printOutputDefinitions(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
+	mcursor=mcursor->next;
+      }
+      xmlAddChild(n,nc);
+    }
+  }
+
+  /**
+   * Display the process output only when requested !
+   */
+  if(status==SERVICE_SUCCEEDED){
+    if(vid==0){
+      nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
+    }
+    maps* mcursor=outputs;
+    elements* scursor=serv->outputs;
+    map* testResponse=getMap(request,"RawDataOutput");
+    if(testResponse==NULL)
+      testResponse=getMap(request,"ResponseDocument");
+    while(mcursor!=NULL){
+      map* tmp0=getMap(mcursor->content,"inRequest");
+      scursor=getElements(serv->outputs,mcursor->name);
+      if(scursor!=NULL){
+	if(testResponse==NULL || tmp0==NULL){
+	  if(vid==0)
+	    printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+	  else
+	    printIOType(doc,n,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+	}
+	else
+
+	  if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0){
+	    if(vid==0)
+	      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+	    else
+	      printIOType(doc,n,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+	  }
+      }else
+	/**
+	 * In case there was no definition found in the ZCFG file but 
+	 * present in the service code
+	 */
+	if(vid==0)
+	  printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+	else
+	  printIOType(doc,n,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
+      mcursor=mcursor->next;
+    }
+    if(vid==0)
+      xmlAddChild(n,nc);
+  }
+  
+  if(vid==0 && hasStoredExecuteResponse==true && status!=SERVICE_STARTED && status!=SERVICE_ACCEPTED){
+#ifndef RELY_ON_DB
+    semid lid=acquireLock(m);//,1);
+    if(lid<0){
+      /* If the lock failed */
+      errorException(m,_("Lock failed."),"InternalError",NULL);
+      xmlFreeDoc(doc);
+      xmlCleanupParser();
+      zooXmlCleanupNs();
+      return;
+    }
+    else{
+#endif
+      /* We need to write the ExecuteResponse Document somewhere */
+      FILE* output=fopen(stored_path,"w");
+      if(output==NULL){
+	/* If the file cannot be created return an ExceptionReport */
+	char tmpMsg[1024];
+	sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the ExecuteResponse."),stored_path);
+
+	errorException(m,tmpMsg,"InternalError",NULL);
+	xmlFreeDoc(doc);
+	xmlCleanupParser();
+	zooXmlCleanupNs();
+#ifndef RELY_ON_DB
+	unlockShm(lid);
+#endif
+	return;
+      }
+      xmlChar *xmlbuff;
+      int buffersize;
+      xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
+      fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
+      xmlFree(xmlbuff);
+      fclose(output);
+#ifndef RELY_ON_DB
+#ifdef DEBUG
+      fprintf(stderr,"UNLOCK %s %d !\n",__FILE__,__LINE__);
+#endif
+      unlockShm(lid);
+      map* v=getMapFromMaps(m,"lenv","sid");
+      // Remove the lock when running as a normal task
+      if(getpid()==atoi(v->value)){
+	removeShmLock (m, 1);
+      }
+    }
+#endif
+  }
+  printDocument(m,doc,pid);
+
+  xmlCleanupParser();
+  zooXmlCleanupNs();
+}
+
+/**
+ * Print a XML document.
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param doc the XML document
+ * @param pid the process identifier linked to a service
+ */
+void printDocument(maps* m, xmlDocPtr doc,int pid){
+  char *encoding=getEncoding(m);
+  if(pid==getpid()){
+    printHeaders(m);
+    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
+  }
+  fflush(stdout);
+  xmlChar *xmlbuff;
+  int buffersize;
+  /*
+   * Dump the document to a buffer and print it on stdout
+   * for demonstration purposes.
+   */
+  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
+  printf("%s",xmlbuff);
+  fflush(stdout);
+  /*
+   * Free associated memory.
+   */
+  xmlFree(xmlbuff);
+  xmlFreeDoc(doc);
+  xmlCleanupParser();
+  zooXmlCleanupNs();
+}
+
+/**
+ * Print a XML document.
+ * 
+ * @param doc the XML document (unused)
+ * @param nc the XML node to add the output definition
+ * @param ns_wps the wps XML namespace
+ * @param ns_ows the ows XML namespace
+ * @param e the output elements 
+ * @param m the conf maps containing the main.cfg settings
+ * @param type the type (unused)
+ */
+void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
+  xmlNodePtr nc1;
+  nc1=xmlNewNode(ns_wps, BAD_CAST type);
+  map *tmp=NULL;  
+  if(e!=NULL && e->defaults!=NULL)
+    tmp=e->defaults->content;
+  else{
+    /*
+    dumpElements(e);
+    */
+    return;
+  }
+  while(tmp!=NULL){
+    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
+       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
+       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
+       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
+    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
+    tmp=tmp->next;
+  }
+  tmp=getMap(e->defaults->content,"asReference");
+  if(tmp==NULL)
+    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
+
+  tmp=e->content;
+
+  printDescription(nc1,ns_ows,m->name,e->content,0);
+
+  xmlAddChild(nc,nc1);
+
+}
+
+/**
+ * Generate XML nodes describing inputs or outputs metadata.
+ * 
+ * @param doc the XML document 
+ * @param nc the XML node to add the definition
+ * @param ns_wps the wps namespace
+ * @param ns_ows the ows namespace
+ * @param ns_xlink the xlink namespace
+ * @param e the output elements 
+ * @param m the conf maps containing the main.cfg settings
+ * @param type the type
+ */
+void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type,int vid){
+
+  xmlNodePtr nc1,nc2,nc3;
+  nc1=xmlNewNode(ns_wps, BAD_CAST type);
+  map *tmp=NULL;
+  if(e!=NULL)
+    tmp=e->content;
+  else
+    tmp=m->content;
+
+  if(vid==0){
+    nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
+    if(e!=NULL)
+      nc3=xmlNewText(BAD_CAST e->name);
+    else
+      nc3=xmlNewText(BAD_CAST m->name);
+    
+    xmlAddChild(nc2,nc3);
+    xmlAddChild(nc1,nc2);
+  
+    xmlAddChild(nc,nc1);
+
+    if(e!=NULL)
+      tmp=getMap(e->content,"Title");
+    else
+      tmp=getMap(m->content,"Title");
+    
+    if(tmp!=NULL){
+      nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
+      nc3=xmlNewText(BAD_CAST _ss(tmp->value));
+      xmlAddChild(nc2,nc3);  
+      xmlAddChild(nc1,nc2);
+    }
+
+    if(e!=NULL)
+      tmp=getMap(e->content,"Abstract");
+    else
+      tmp=getMap(m->content,"Abstract");
+
+    if(tmp!=NULL){
+      nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
+      nc3=xmlNewText(BAD_CAST _ss(tmp->value));
+      xmlAddChild(nc2,nc3);  
+      xmlAddChild(nc1,nc2);
+      xmlAddChild(nc,nc1);
+    }
+  }else{
+    xmlNewProp(nc1,BAD_CAST "id",BAD_CAST (e!=NULL?e->name:m->name));
+  }
+
+  /**
+   * IO type Reference or full Data ?
+   */
+  map *tmpMap=getMap(m->content,"Reference");
+  if(tmpMap==NULL){
+    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
+    if(e!=NULL){
+      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
+	nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+      else
+        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
+	  nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
+	else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
+	  nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
+	else
+	  nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
+    }
+    else {
+      map* tmpV=getMapFromMaps(m,"format","value");
+      if(tmpV!=NULL)
+	nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
+      else
+	nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+    } 
+    tmp=m->content;
+
+    while(tmp!=NULL){
+      if(strcasecmp(tmp->name,"mimeType")==0 ||
+	 strcasecmp(tmp->name,"encoding")==0 ||
+	 strcasecmp(tmp->name,"schema")==0 ||
+	 strcasecmp(tmp->name,"datatype")==0 ||
+	 strcasecmp(tmp->name,"uom")==0) {
+
+	xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
+      }
+      tmp=tmp->next;
+      xmlAddChild(nc2,nc3);
+    }
+    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0) {
+      map* bb=getMap(m->content,"value");
+      if(bb!=NULL) {
+	map* tmpRes=parseBoundingBox(bb->value);
+	printBoundingBox(ns_ows,nc3,tmpRes);
+	freeMap(&tmpRes);
+	free(tmpRes);
+      }
+    }
+    else {
+      if(e!=NULL)
+	tmp=getMap(e->defaults->content,"mimeType");
+      else
+	tmp=NULL;
+	
+      map* tmp1=getMap(m->content,"encoding");
+      map* tmp2=getMap(m->content,"mimeType");
+      map* tmp3=getMap(m->content,"value");
+      int hasValue=1;
+      if(tmp3==NULL){
+	tmp3=createMap("value","");
+	hasValue=-1;
+      }
+
+      if( ( tmp1 != NULL && strncmp(tmp1->value,"base64",6) == 0 )     // if encoding is base64
+	  || 	                                                       // or if 
+	  ( tmp2 != NULL && ( strstr(tmp2->value,"text") == NULL       //  mime type is not text 
+			      &&                                       //  nor 
+			      strstr(tmp2->value,"xml") == NULL        //  xml
+			      &&                                       // nor
+			      strstr(tmp2->value,"javascript") == NULL // javascript
+			      &&
+			      strstr(tmp2->value,"json") == NULL
+			      &&
+			      strstr(tmp2->value,"ecmascript") == NULL
+			      &&
+			      // include for backwards compatibility,
+			      // although correct mime type is ...kml+xml:
+			      strstr(tmp2->value,"google-earth.kml") == NULL							)
+	    )
+	  ) { 	                                                 // then	
+	map* rs=getMap(m->content,"size");                       // obtain size
+	bool isSized=true;
+	if(rs==NULL){
+	  char tmp1[1024];
+	  sprintf(tmp1,"%ld",strlen(tmp3->value));
+	  rs=createMap("size",tmp1);
+	  isSized=false;
+	}
+	 
+	xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));  // base 64 encode in XML
+		
+	if(tmp1==NULL || (tmp1!=NULL && strncmp(tmp1->value,"base64",6)!=0)) {
+	  xmlAttrPtr ap = xmlHasProp(nc3, BAD_CAST "encoding");
+	  if (ap != NULL) {
+	    xmlRemoveProp(ap);
+	  }			
+	  xmlNewProp(nc3,BAD_CAST "encoding",BAD_CAST "base64");
+	}
+		
+	if(!isSized){
+	  freeMap(&rs);
+	  free(rs);
+	}
+      }
+      else if (tmp2!=NULL) {                                 // else (text-based format) 
+	if(strstr(tmp2->value, "javascript") != NULL ||      //    if javascript put code in CDATA block 
+	   strstr(tmp2->value, "json") != NULL ||            //    (will not be parsed by XML reader) 
+	   strstr(tmp2->value, "ecmascript") != NULL
+	   ) {
+	  xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
+	}   
+	else {                                                     // else
+	  if (strstr(tmp2->value, "xml") != NULL ||                 // if XML-based format
+	      // include for backwards compatibility,
+	      // although correct mime type is ...kml+xml:		   
+	      strstr(tmp2->value, "google-earth.kml") != NULL
+	      ) { 
+			  
+	    int li=zooXmlAddDoc(tmp3->value);
+	    xmlDocPtr doc = iDocs[li];
+	    xmlNodePtr ir = xmlDocGetRootElement(doc);
+	    xmlAddChild(nc3,ir);
+	  }
+	  else                                                     // else	
+	    xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));    //   add text node
+	}
+	xmlAddChild(nc2,nc3);
+      }
+      else {
+	xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
+      }
+	  
+      if(hasValue<0) {
+	freeMap(&tmp3);
+	free(tmp3);
+      }
+    }
+  }
+  else { // Reference
+    tmpMap=getMap(m->content,"Reference");
+    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
+    if(strcasecmp(type,"Output")==0)
+      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
+    else
+      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
+    
+    tmp=m->content;
+    while(tmp!=NULL) {
+      if(strcasecmp(tmp->name,"mimeType")==0 ||
+	 strcasecmp(tmp->name,"encoding")==0 ||
+	 strcasecmp(tmp->name,"schema")==0 ||
+	 strcasecmp(tmp->name,"datatype")==0 ||
+	 strcasecmp(tmp->name,"uom")==0){
+
+	if(strcasecmp(tmp->name,"datatype")==0)
+	  xmlNewProp(nc3,BAD_CAST "mimeType",BAD_CAST "text/plain");
+	else
+	  xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
+      }
+      tmp=tmp->next;
+      xmlAddChild(nc2,nc3);
+    }
+  }
+  xmlAddChild(nc1,nc2);
+  xmlAddChild(nc,nc1);
+}
+
+/**
+ * Create XML node with basic ows metadata informations (Identifier,Title,Abstract)
+ *
+ * @param root the root XML node to add the description
+ * @param ns_ows the ows XML namespace
+ * @param identifier the identifier to use
+ * @param amap the map containing the ows metadata informations 
+ */
+void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap,int vid=0){
+  xmlNodePtr nc2;
+  if(vid==0){
+    nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
+    xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
+    xmlAddChild(root,nc2);
+  }
+  map* tmp=amap;
+  const char *tmp2[2];
+  tmp2[0]="Title";
+  tmp2[1]="Abstract";
+  int j=0;
+  for(j=0;j<2;j++){
+    map* tmp1=getMap(tmp,tmp2[j]);
+    if(tmp1!=NULL){
+      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
+      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
+      xmlAddChild(root,nc2);
+    }
+  }
+  if(vid==1){
+    nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
+    xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
+    xmlAddChild(root,nc2);
+  }
+}
+
+/**
+ * Print an OWS ExceptionReport Document and HTTP headers (when required) 
+ * depending on the code.
+ * Set hasPrinted value to true in the [lenv] section.
+ * 
+ * @param m the maps containing the settings of the main.cfg file
+ * @param s the map containing the text,code,locator keys
+ */
+void printExceptionReportResponse(maps* m,map* s){
+  if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
+    return;
+  int buffersize;
+  xmlDocPtr doc;
+  xmlChar *xmlbuff;
+  xmlNodePtr n;
+
+  zooXmlCleanupNs();
+  doc = xmlNewDoc(BAD_CAST "1.0");
+  maps* tmpMap=getMaps(m,"main");
+  char *encoding=getEncoding(tmpMap);
+  const char *exceptionCode;
+  
+  map* tmp=getMap(s,"code");
+  if(tmp!=NULL){
+    if(strcmp(tmp->value,"OperationNotSupported")==0 ||
+       strcmp(tmp->value,"NoApplicableCode")==0)
+      exceptionCode="501 Not Implemented";
+    else
+      if(strcmp(tmp->value,"MissingParameterValue")==0 ||
+	 strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
+	 strcmp(tmp->value,"OptionNotSupported")==0 ||
+	 strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
+	 strcmp(tmp->value,"InvalidParameterValue")==0)
+	exceptionCode="400 Bad request";
+      else
+	exceptionCode="501 Internal Server Error";
+  }
+  else
+    exceptionCode="501 Internal Server Error";
+
+  if(m!=NULL){
+    map *tmpSid=getMapFromMaps(m,"lenv","sid");
+    if(tmpSid!=NULL){
+      if( getpid()==atoi(tmpSid->value) ){
+	printHeaders(m);
+	printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
+      }
+    }
+    else{
+      printHeaders(m);
+      printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
+    }
+  }else{
+    printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
+  }
+  n=createExceptionReportNode(m,s,1);
+  xmlDocSetRootElement(doc, n);
+  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
+  printf("%s",xmlbuff);
+  fflush(stdout);
+  xmlFreeDoc(doc);
+  xmlFree(xmlbuff);
+  xmlCleanupParser();
+  zooXmlCleanupNs();
+  if(m!=NULL)
+    setMapInMaps(m,"lenv","hasPrinted","true");
+}
+
+/**
+ * Create an OWS ExceptionReport Node.
+ * 
+ * @param m the conf maps
+ * @param s the map containing the text,code,locator keys
+ * @param use_ns (0/1) choose if you want to generate an ExceptionReport or 
+ *  ows:ExceptionReport node respectively
+ * @return the ExceptionReport/ows:ExceptionReport node
+ */
+xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
+  
+  xmlNsPtr ns,ns_xsi;
+  xmlNodePtr n,nc,nc1;
+
+  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows","ows");
+  ns=usedNs[nsid];
+  if(use_ns==0){
+    ns=NULL;
+  }
+  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
+  map* version=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(version->value);
+  if(vid<0)
+    vid=0;
+  if(use_ns==1){
+    xmlNewNs(n,BAD_CAST schemas[vid][1],BAD_CAST"ows");
+    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
+    ns_xsi=usedNs[xsiId];
+    char tmp[1024];
+    sprintf(tmp,"%s %s",schemas[vid][1],schemas[vid][5]);
+    xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST tmp);
+  }
+
+
+  addLangAttr(n,m);
+  xmlNewProp(n,BAD_CAST "version",BAD_CAST schemas[vid][6]);
+  
+  int length=1;
+  int cnt=0;
+  map* len=getMap(s,"length");
+  if(len!=NULL)
+    length=atoi(len->value);
+  for(cnt=0;cnt<length;cnt++){
+    nc = xmlNewNode(ns, BAD_CAST "Exception");
+    
+    map* tmp=getMapArray(s,"code",cnt);
+    if(tmp==NULL)
+      tmp=getMap(s,"code");
+    if(tmp!=NULL)
+      xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
+    else
+      xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
+    
+    tmp=getMapArray(s,"locator",cnt);
+    if(tmp==NULL)
+      tmp=getMap(s,"locator");
+    if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
+      xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
+
+    tmp=getMapArray(s,"text",cnt);
+    nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
+    if(tmp!=NULL){
+      xmlNodePtr txt=xmlNewText(BAD_CAST tmp->value);
+      xmlAddChild(nc1,txt);
+    }
+    else{
+      xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
+    }
+    xmlAddChild(nc,nc1);
+    xmlAddChild(n,nc);
+  }
+  return n;
+}
+
+/**
+ * Print an OWS ExceptionReport.
+ * 
+ * @param m the conf maps
+ * @param message the error message 
+ * @param errorcode the error code
+ * @param locator the potential locator
+ */
+int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
+{
+  map* errormap = createMap("text", message);
+  addToMap(errormap,"code", errorcode);
+  if(locator!=NULL)
+    addToMap(errormap,"locator", locator);
+  else
+    addToMap(errormap,"locator", "NULL");
+  printExceptionReportResponse(m,errormap);
+  freeMap(&errormap);
+  free(errormap);
+  return -1;
+}
+
+/**
+ * Generate the output response (RawDataOutput or ResponseDocument)
+ *
+ * @param s the service structure containing the metadata informations
+ * @param request_inputs the inputs provided to the service for execution
+ * @param request_outputs the outputs updated by the service execution
+ * @param request_inputs1 the map containing the HTTP request
+ * @param cpid the process identifier attached to a service execution
+ * @param m the conf maps containing the main.cfg settings
+ * @param res the value returned by the service execution
+ */
+void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
+		    map* request_inputs1,int cpid,maps* m,int res){
+#ifdef DEBUG
+  dumpMaps(request_inputs);
+  dumpMaps(request_outputs);
+  fprintf(stderr,"printProcessResponse\n");
+#endif
+  map* toto=getMap(request_inputs1,"RawDataOutput");
+  int asRaw=0;
+  if(toto!=NULL)
+    asRaw=1;
+  map* version=getMapFromMaps(m,"main","rversion");
+  int vid=getVersionId(version->value);
+  
+  maps* tmpSess=getMaps(m,"senv");
+  if(tmpSess!=NULL){
+    map *_tmp=getMapFromMaps(m,"lenv","cookie");
+    char* sessId=NULL;
+    if(_tmp!=NULL){
+      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
+      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
+      char session_file_path[100];
+      char *tmp1=strtok(_tmp->value,";");
+      if(tmp1!=NULL)
+	sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
+      else
+	sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
+      sessId=strdup(session_file_path);
+    }else{
+      maps* t=getMaps(m,"senv");
+      map*p=t->content;
+      while(p!=NULL){
+	if(strstr(p->name,"ID")!=NULL){
+	  sessId=strdup(p->value);
+	  break;
+	}
+	p=p->next;
+      }
+    }
+    char session_file_path[1024];
+    map *tmpPath=getMapFromMaps(m,"main","sessPath");
+    if(tmpPath==NULL)
+      tmpPath=getMapFromMaps(m,"main","tmpPath");
+    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
+    FILE* teste=fopen(session_file_path,"w");
+    if(teste==NULL){
+      char tmpMsg[1024];
+      sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the session maps."),session_file_path);
+      errorException(m,tmpMsg,"InternalError",NULL);
+
+      return;
+    }
+    else{
+      fclose(teste);
+      dumpMapsToFile(tmpSess,session_file_path);
+    }
+  }
+  
+  if(res==SERVICE_FAILED){
+    map *lenv;
+    lenv=getMapFromMaps(m,"lenv","message");
+    char *tmp0;
+    if(lenv!=NULL){
+      tmp0=(char*)malloc((strlen(lenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
+      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
+    }
+    else{
+      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
+      sprintf(tmp0,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
+    }
+    errorException(m,tmp0,"InternalError",NULL);
+    free(tmp0);
+    return;
+  }
+
+  if(res==SERVICE_ACCEPTED && vid==1){
+    map* statusInfo=createMap("Status","Accepted");
+    map *usid=getMapFromMaps(m,"lenv","usid");
+    addToMap(statusInfo,"JobID",usid->value);
+    printStatusInfo(m,statusInfo,"Execute");
+    freeMap(&statusInfo);
+    free(statusInfo);
+    return;
+  }
+
+  map *tmp1=getMapFromMaps(m,"main","tmpPath");
+  if(asRaw==0){
+#ifdef DEBUG
+    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
+    dumpMaps(request_outputs);
+#endif
+    maps* tmpI=request_outputs;
+    map* usid=getMapFromMaps(m,"lenv","usid");
+    int itn=0;
+    while(tmpI!=NULL){
+#ifdef USE_MS
+      map* testMap=getMap(tmpI->content,"useMapserver");	
+#endif
+      map *gfile=getMap(tmpI->content,"generated_file");
+      char *file_name;
+      if(gfile!=NULL){
+	gfile=getMap(tmpI->content,"expected_generated_file");
+	if(gfile==NULL){
+	  gfile=getMap(tmpI->content,"generated_file");
+	}
+	readGeneratedFile(m,tmpI->content,gfile->value);	    
+	file_name=(char*)malloc((strlen(gfile->value)+strlen(tmp1->value)+1)*sizeof(char));
+	for(int i=0;i<strlen(gfile->value);i++)
+	  file_name[i]=gfile->value[i+strlen(tmp1->value)];
+      }
+
+      toto=getMap(tmpI->content,"asReference");
+#ifdef USE_MS
+      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
+#else
+      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
+#endif
+	{
+	  elements* in=getElements(s->outputs,tmpI->name);
+	  char *format=NULL;
+	  if(in!=NULL){
+	    format=strdup(in->format);
+	  }else
+	    format=strdup("LiteralData");
+	  if(strcasecmp(format,"BoundingBoxData")==0){
+	    addToMap(tmpI->content,"extension","xml");
+	    addToMap(tmpI->content,"mimeType","text/xml");
+	    addToMap(tmpI->content,"encoding","UTF-8");
+	    addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
+	  }
+
+	  if(gfile==NULL) {
+	    map *ext=getMap(tmpI->content,"extension");
+	    char *file_path;
+	    char file_ext[32];
+
+	    if( ext != NULL && ext->value != NULL) {
+	      strncpy(file_ext, ext->value, 32);
+	    }
+	    else {
+	      // Obtain default file extension (see mimetypes.h).	      
+	      // If the MIME type is not recognized, txt is used as the default extension
+	      map* mtype=getMap(tmpI->content,"mimeType");
+	      getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
+	    }
+		
+	    file_name=(char*)malloc((strlen(s->name)+strlen(usid->value)+strlen(file_ext)+strlen(tmpI->name)+45)*sizeof(char));
+	    sprintf(file_name,"%s_%s_%s_%d.%s",s->name,tmpI->name,usid->value,itn,file_ext);
+	    itn++;
+	    file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
+	    sprintf(file_path,"%s/%s",tmp1->value,file_name);
+    
+	    FILE *ofile=fopen(file_path,"wb");
+	    if(ofile==NULL){
+	      char tmpMsg[1024];
+	      sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the %s final result."),file_name,tmpI->name);
+	      errorException(m,tmpMsg,"InternalError",NULL);
+	      free(file_name);
+	      free(file_path);
+	      return;
+	    }
+	    free(file_path);
+
+	    toto=getMap(tmpI->content,"value");
+	    if(strcasecmp(format,"BoundingBoxData")!=0){
+	      map* size=getMap(tmpI->content,"size");
+	      if(size!=NULL && toto!=NULL)
+		fwrite(toto->value,1,(atoi(size->value))*sizeof(char),ofile);
+	      else
+		if(toto!=NULL && toto->value!=NULL)
+		  fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
+	    }else{
+	      printBoundingBoxDocument(m,tmpI,ofile);
+	    }
+	    fclose(ofile);
+
+	  }
+	  map *tmp2=getMapFromMaps(m,"main","tmpUrl");
+	  map *tmp3=getMapFromMaps(m,"main","serverAddress");
+	  char *file_url;
+	  if(strncasecmp(tmp2->value,"http://",7)==0 ||
+	     strncasecmp(tmp2->value,"https://",8)==0){
+	    file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
+	    sprintf(file_url,"%s/%s",tmp2->value,file_name);
+	  }else{
+	    file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
+	    sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
+	  }
+	  addToMap(tmpI->content,"Reference",file_url);
+	  free(format);
+	  free(file_name);
+	  free(file_url);	
+	  
+	}
+#ifdef USE_MS
+      else{
+	if(testMap!=NULL){
+	  setReferenceUrl(m,tmpI);
+	}
+      }
+#endif
+      tmpI=tmpI->next;
+    }
+#ifdef DEBUG
+    fprintf(stderr,"SERVICE : %s\n",s->name);
+    dumpMaps(m);
+#endif
+    printProcessResponse(m,request_inputs1,cpid,
+			 s, s->name,res,  // replace serviceProvider with serviceName in stored response file name
+			 request_inputs,
+			 request_outputs);
+  }
+  else{
+    /**
+     * We get the requested output or fallback to the first one if the 
+     * requested one is not present in the resulting outputs maps.
+     */
+    maps* tmpI=NULL;
+    map* tmpIV=getMap(request_inputs1,"RawDataOutput");
+    if(tmpIV!=NULL){
+      tmpI=getMaps(request_outputs,tmpIV->value);
+    }
+    if(tmpI==NULL)
+      tmpI=request_outputs;
+    elements* e=getElements(s->outputs,tmpI->name);
+    if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
+      printBoundingBoxDocument(m,tmpI,NULL);
+    }else{
+      map *gfile=getMap(tmpI->content,"generated_file");
+      if(gfile!=NULL){
+	gfile=getMap(tmpI->content,"expected_generated_file");
+	if(gfile==NULL){
+	  gfile=getMap(tmpI->content,"generated_file");
+	}
+	readGeneratedFile(m,tmpI->content,gfile->value);
+      }
+      toto=getMap(tmpI->content,"value");
+      if(toto==NULL){
+	char tmpMsg[1024];
+	sprintf(tmpMsg,_("Wrong RawDataOutput parameter: unable to fetch any result for the given parameter name: \"%s\"."),tmpI->name);
+	errorException(m,tmpMsg,"InvalidParameterValue","RawDataOutput");
+	return;
+      }
+      map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
+      if(fname!=NULL)
+	printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
+      map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
+      if(rs!=NULL)
+	printf("Content-Length: %s\r\n",rs->value);
+      printHeaders(m);
+      char mime[1024];
+      map* mi=getMap(tmpI->content,"mimeType");
+#ifdef DEBUG
+      fprintf(stderr,"SERVICE OUTPUTS\n");
+      dumpMaps(request_outputs);
+      fprintf(stderr,"SERVICE OUTPUTS\n");
+#endif
+      map* en=getMap(tmpI->content,"encoding");
+      if(mi!=NULL && en!=NULL)
+	sprintf(mime,
+		"Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
+		mi->value,en->value);
+      else
+	if(mi!=NULL)
+	  sprintf(mime,
+		  "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
+		  mi->value);
+	else
+	  sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
+      printf("%s",mime);
+      if(rs!=NULL)
+	fwrite(toto->value,1,atoi(rs->value),stdout);
+      else
+	fwrite(toto->value,1,strlen(toto->value),stdout);
+#ifdef DEBUG
+      dumpMap(toto);
+#endif
+    }
+  }
+}
+
+/**
+ * Create required XML nodes for boundingbox and update the current XML node
+ *
+ * @param ns_ows the ows XML namespace
+ * @param n the XML node to update
+ * @param boundingbox the map containing the boundingbox definition
+ */
+void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
+
+  xmlNodePtr lw=NULL,uc=NULL;
+
+  map* tmp=getMap(boundingbox,"value");
+
+  tmp=getMap(boundingbox,"lowerCorner");
+  if(tmp!=NULL){
+    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
+    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
+  }
+
+  tmp=getMap(boundingbox,"upperCorner");
+  if(tmp!=NULL){
+    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
+    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
+  }
+
+  tmp=getMap(boundingbox,"crs");
+  if(tmp!=NULL)
+    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
+
+  tmp=getMap(boundingbox,"dimensions");
+  if(tmp!=NULL)
+    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
+
+  xmlAddChild(n,lw);
+  xmlAddChild(n,uc);
+
+}
+
+/**
+ * Parse a BoundingBox string
+ *
+ * [OGC 06-121r3](http://portal.opengeospatial.org/files/?artifact_id=20040):
+ *  10.2 Bounding box
+ * 
+ *
+ * Value is provided as : lowerCorner,upperCorner,crs,dimension
+ * Exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
+ *
+ * A map to store boundingbox informations should contain:
+ *  - lowerCorner : double,double (minimum within this bounding box)
+ *  - upperCorner : double,double (maximum within this bounding box)
+ *  - crs : URI (Reference to definition of the CRS)
+ *  - dimensions : int 
+ * 
+ * Note : support only 2D bounding box.
+ *
+ * @param value the char* containing the KVP bouding box
+ * @return a map containing all the bounding box keys
+ */
+map* parseBoundingBox(const char* value){
+  map *res=NULL;
+  if(value!=NULL){
+    char *cv,*cvp;
+    cv=strtok_r((char*) value,",",&cvp);
+    int cnt=0;
+    int icnt=0;
+    char *currentValue=NULL;
+    while(cv){
+      if(cnt<2)
+	if(currentValue!=NULL){
+	  char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
+	  sprintf(finalValue,"%s%s",currentValue,cv);
+	  switch(cnt){
+	  case 0:
+	    res=createMap("lowerCorner",finalValue);
+	    break;
+	  case 1:
+	    addToMap(res,"upperCorner",finalValue);
+	    icnt=-1;
+	    break;
+	  }
+	  cnt++;
+	  free(currentValue);
+	  currentValue=NULL;
+	  free(finalValue);
+	}
+	else{
+	  currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
+	  sprintf(currentValue,"%s ",cv);
+	}
+      else
+	if(cnt==2){
+	  addToMap(res,"crs",cv);
+	  cnt++;
+	}
+	else
+	  addToMap(res,"dimensions",cv);
+      icnt++;
+      cv=strtok_r(NULL,",",&cvp);
+    }
+  }
+  return res;
+}
+
+/**
+ * Print an ows:BoundingBox XML document
+ *
+ * @param m the maps containing the settings of the main.cfg file
+ * @param boundingbox the maps containing the boundingbox definition
+ * @param file the file to print the BoundingBox (if NULL then print on stdout)
+ * @see parseBoundingBox, printBoundingBox
+ */
+void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
+  if(file==NULL)
+    rewind(stdout);
+  xmlNodePtr n;
+  xmlDocPtr doc;
+  xmlNsPtr ns_ows,ns_xsi;
+  xmlChar *xmlbuff;
+  int buffersize;
+  char *encoding=getEncoding(m);
+  map *tmp;
+  if(file==NULL){
+    int pid=0;
+    tmp=getMapFromMaps(m,"lenv","sid");
+    if(tmp!=NULL)
+      pid=atoi(tmp->value);
+    if(pid==getpid()){
+      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
+    }
+    fflush(stdout);
+  }
+
+  doc = xmlNewDoc(BAD_CAST "1.0");
+  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
+  ns_ows=usedNs[owsId];
+  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
+  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
+  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
+  ns_xsi=usedNs[xsiId];
+  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
+  map *tmp1=getMap(boundingbox->content,"value");
+  tmp=parseBoundingBox(tmp1->value);
+  printBoundingBox(ns_ows,n,tmp);
+  xmlDocSetRootElement(doc, n);
+
+  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
+  if(file==NULL)
+    printf("%s",xmlbuff);
+  else{
+    fprintf(file,"%s",xmlbuff);
+  }
+
+  if(tmp!=NULL){
+    freeMap(&tmp);
+    free(tmp);
+  }
+  xmlFree(xmlbuff);
+  xmlFreeDoc(doc);
+  xmlCleanupParser();
+  zooXmlCleanupNs();
+  
+}
+
+/**
+ * Print a StatusInfo XML document.
+ * a statusInfo map should contain the following keys:
+ *  * JobID corresponding to usid key from the lenv section
+ *  * Status the current state (Succeeded,Failed,Accepted,Running)
+ *  * PercentCompleted (optional) the percent completed
+ *  * Message (optional) any messages the service may wish to share
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param statusInfo the map containing the statusInfo definition
+ * @param req the WPS requests (GetResult, GetStatus or Dismiss)
+ */
+void printStatusInfo(maps* conf,map* statusInfo,char* req){
+  rewind(stdout);
+  xmlNodePtr n,n1;
+  xmlDocPtr doc;
+  xmlNsPtr ns;
+  xmlChar *xmlbuff;
+  int buffersize;
+  char *encoding=getEncoding(conf);
+  map *tmp;
+  int pid=0;
+  printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
+
+  map* version=getMapFromMaps(conf,"main","rversion");
+  int vid=getVersionId(version->value);
+
+  doc = xmlNewDoc(BAD_CAST "1.0");
+  n1=printWPSHeader(doc,conf,req,"StatusInfo",version->value,1);
+
+  map* val=getMap(statusInfo,"JobID");
+  int wpsId=zooXmlAddNs(NULL,schemas[vid][2],"wps");
+  ns=usedNs[wpsId];
+  n = xmlNewNode(ns, BAD_CAST "JobID");
+  xmlAddChild(n,xmlNewText(BAD_CAST val->value));
+
+  xmlAddChild(n1,n);
+
+  val=getMap(statusInfo,"Status");
+  n = xmlNewNode(ns, BAD_CAST "Status");
+  xmlAddChild(n,xmlNewText(BAD_CAST val->value));
+
+  xmlAddChild(n1,n);
+
+  if(strncasecmp(val->value,"Failed",6)!=0 &&
+     strncasecmp(val->value,"Succeeded",9)!=0){
+    val=getMap(statusInfo,"PercentCompleted");
+    if(val!=NULL){
+      n = xmlNewNode(ns, BAD_CAST "PercentCompleted");
+      xmlAddChild(n,xmlNewText(BAD_CAST val->value));
+      xmlAddChild(n1,n);
+    }
+
+    val=getMap(statusInfo,"Message");
+    if(val!=NULL){    
+      xmlAddChild(n1,xmlNewComment(BAD_CAST val->value));
+    }
+  }
+  xmlDocSetRootElement(doc, n1);
+
+  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
+  printf("%s",xmlbuff);
+
+  xmlFree(xmlbuff);
+  xmlFreeDoc(doc);
+  xmlCleanupParser();
+  zooXmlCleanupNs();
+  
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/response_print.h	(revision 672)
@@ -0,0 +1,233 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2013 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_RESPONSE_PRINT_H
+#define ZOO_RESPONSE_PRINT_H 1
+
+#pragma once 
+
+/**
+ * The default service url (overriden by serverAddress)
+ */
+#define DEFAULT_SERVICE_URL "http://www.zoo-project.org/"
+/**
+ * The time size
+ */
+#define TIME_SIZE 40
+
+#include <libintl.h>
+#include <locale.h>
+/**
+ * ZOO-Kernel internal messages translation function
+ */
+#define _(String) dgettext ("zoo-kernel",String)
+/**
+ * ZOO-Services messages translation function
+ */
+#define _ss(String) dgettext ("zoo-services",String)
+
+/**
+ * ZOO-Kernel was unable to create a lock
+ */
+#define ZOO_LOCK_CREATE_FAILED -4
+/**
+ * ZOO-Kernel was unable to acquire a lock
+ */
+#define ZOO_LOCK_ACQUIRE_FAILED -5
+/**
+ * ZOO-Kernel was unable to release a lock
+ */
+#define ZOO_LOCK_RELEASE_FAILED -6
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "cgic.h"
+#ifndef WIN32
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#else
+#include <direct.h>
+#endif
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#ifdef WIN32
+#ifndef USE_RUBY
+#include <unistd.h>
+#endif
+#endif
+#ifndef WIN32
+#include <xlocale.h>
+#endif
+#include "ulinet.h"
+
+#include "service.h"
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+  /**
+   * Maximum number of XML namespaces
+   */
+#define ZOO_NS_MAX 10
+  /**
+   * Maximum number of XML docs
+   */
+#define ZOO_DOC_MAX 20
+
+  /**
+   * Global char* to store the serverAddress value of the [main] section
+   */
+  static char* SERVICE_URL;
+
+  /**
+   * Array of xmlNsPtr storing all used XML namespace
+   */
+  static xmlNsPtr usedNs[ZOO_NS_MAX];
+  /**
+   * Array storing names of the used XML namespace
+   */
+  static char* nsName[ZOO_NS_MAX];
+  /**
+   * Number of XML namespaces
+   */
+  static int nbNs=0;
+  /**
+   * Array of xmlDocPtr storing XML docs
+   */
+  static xmlDocPtr iDocs[ZOO_DOC_MAX];
+  /**
+   * Number of XML docs
+   */
+  static int nbDocs=0;
+
+  /**
+   * Definitions of acceptable final status
+   */
+  static char wpsStatus[2][11]={
+    "Succeeded",
+    "Failed"
+  };
+  /**
+   * Definitions of schemas depending on the WPS version
+   */
+  static const char* schemas[2][7]={
+    {"1.0.0","http://www.opengis.net/ows/1.1","http://www.opengis.net/wps/1.0.0","http://schemas.opengis.net/wps/1.0.0","%s %s/wps%s_response.xsd","http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd","1.1.0"},
+    {"2.0.0","http://www.opengis.net/ows/2.0","http://www.opengis.net/wps/2.0","http://schemas.opengis.net/wps/2.0","%s %s/wps%s.xsd","http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd","2.0.2"},
+  };
+  /**
+   * Definitions of support requests (depending on the WPS version)
+   */
+  static int nbSupportedRequests=7;
+  /**
+   * Definitions of requests depending on the WPS version
+   */
+  static const char* requests[2][7]={
+    {"GetCapabilities","DescribeProcess","Execute",NULL},
+    {"GetCapabilities","DescribeProcess","Execute","GetStatus","GetResult","Dismiss",NULL},
+  };
+  /**
+   * Definitions requests requiring identifier (depending on the WPS version)
+   */
+  static int nbReqIdentifier=2;
+  /**
+   * Definitions requests requiring jobid (only for WPS version 2.0.0)
+   */
+  static int nbReqJob=3;
+  /**
+   * Definitions of root node for response depending on the request and the WPS version
+   */
+  static const char root_nodes[2][4][20]={
+    {"ProcessOfferings","ProcessDescriptions","ExecuteResponse",NULL},
+    {"Contents","ProcessOfferings","Result",NULL}
+  };
+
+  /**
+   * Name and corresponding attributes depending on the WPS version
+   */
+  static const char* capabilities[2][7]={
+    {
+      "Process",
+      "processVersion","1",
+      "storeSupported","true",
+      "statusSupported","true"
+    },
+    {
+      "ProcessSummary",
+      "processVersion","1.0.0",
+      "jobControlOptions","sync-execute async-execute dismiss",
+      "outputTransmission","value reference"
+    }
+  };
+
+  void addLangAttr(xmlNodePtr,maps*);
+
+  void printHeaders(maps*);
+
+  int zooXmlSearchForNs(const char*);
+  int zooXmlAddNs(xmlNodePtr,const char*,const char*);
+  void zooXmlCleanupNs();
+
+  int zooXmlAddDoc(xmlNodePtr,const char*,const char*);
+  void zooXmlCleanupDocs();
+  
+  void printExceptionReportResponse(maps*,map*);
+  xmlNodePtr createExceptionReportNode(maps*,map*,int);
+  void printProcessResponse(maps*,map*,int,service*,const char*,int,maps*,maps*);
+  xmlNodePtr printWPSHeader(xmlDocPtr,maps*,const char*,const char*,const char*,int);
+  xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr,maps*,const char*);
+  void printGetCapabilitiesForProcess(maps*,xmlNodePtr,service*);
+  void printDescribeProcessForProcess(maps*,xmlNodePtr,service*);
+  void printFullDescription(int,elements*,const char*,xmlNsPtr,xmlNsPtr,xmlNodePtr,int);
+  void printDocument(maps*,xmlDocPtr,int);
+  void printDescription(xmlNodePtr,xmlNsPtr,const char*,map*,int);
+  void printIOType(xmlDocPtr,xmlNodePtr,xmlNsPtr,xmlNsPtr,xmlNsPtr,elements*,maps*,const char*,int);
+  map* parseBoundingBox(const char*);
+  void printBoundingBox(xmlNsPtr,xmlNodePtr,map*);
+  void printBoundingBoxDocument(maps*,maps*,FILE*);
+  void printOutputDefinitions(xmlDocPtr,xmlNodePtr,xmlNsPtr,xmlNsPtr,elements*,maps*,const char*);
+  void printStatusInfo(maps*,map*,char*);
+
+  void outputResponse(service*,maps*,maps*,map*,int,maps*,int);
+
+  int errorException(maps *, const char *, const char *, const char*);
+
+  xmlNodePtr soapEnvelope(maps*,xmlNodePtr);
+  int checkForSoapEnvelope(xmlDocPtr);
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.c	(revision 672)
@@ -0,0 +1,984 @@
+/*
+ * Author : Gérald Fenoy
+ *
+ *  Copyright 2008-2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "server_internal.h"
+#include "service_internal.h"
+#include "response_print.h"
+#include "mimetypes.h"
+#ifndef WIN32
+#include <dlfcn.h>
+#endif
+#include <uuid/uuid.h>
+#include <signal.h>
+
+/**
+ * Detect WPS version used (1.0.0 or 2.0.0).
+ *
+ * @param version number as char* (1.0.0 or 2.0.0)
+ * @return 0 in case of version 1.0.0, 1 for 2.0.0, -1 in other case
+ */
+int getVersionId(const char* version){
+  int schemaId=0;
+  for(;schemaId<2;schemaId++){
+    if(strncasecmp(version,schemas[schemaId][0],5)==0)
+      return schemaId;
+  }
+  return -1;
+}
+
+/**
+ * Generate a UUID.
+ * ref: https://www.ietf.org/rfc/rfc4122.txt / 4.2 
+ *
+ * @return a new char* containing the UUID, make sure to free the returned 
+ *  ressource once used.
+ */
+char *get_uuid(){
+  char *res=(char*)malloc(37*sizeof(char));
+  uuid_t uuid;
+  uuid_generate_time(uuid);
+  char rest[128];
+  uuid_unparse(uuid,rest);
+  sprintf(res,"%s", rest);
+  return res;
+}
+
+/**
+ * Extract the service identifier from the full service identifier
+ * ie: 
+ *  - Full service name: OTB.BandMath
+ *  - Service name: BandMath
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param conf_dir the full path to the ZOO-Kernel directory
+ * @param identifier the full service name (potentialy including a prefix, ie:
+ *  Prefix.MyService)
+ * @param buffer the resulting service identifier (without any prefix)
+ */
+void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
+  setMapInMaps(conf,"lenv","oIdentifier",identifier);
+  char *lid=zStrdup(identifier);
+  char *saveptr1;
+  char *tmps1=strtok_r(lid,".",&saveptr1);
+  int level=0;
+  char key[25];
+  char levels[18];
+  while(tmps1!=NULL){
+    char *test=zStrdup(tmps1);
+    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
+    sprintf(key,"sprefix_%d",level);
+    sprintf(tmps2,"%s.",test);
+    sprintf(levels,"%d",level);
+    setMapInMaps(conf,"lenv","level",levels);
+    setMapInMaps(conf,"lenv",key,tmps2);
+    free(tmps2);
+    free(test);
+    level++;
+    tmps1=strtok_r(NULL,".",&saveptr1);
+  }
+  int i=0;
+  sprintf(buffer,"%s",conf_dir);
+  for(i=0;i<level;i++){
+    char *tmp0=zStrdup(buffer);
+    sprintf(key,"sprefix_%d",i);
+    map* tmp00=getMapFromMaps(conf,"lenv",key);
+    if(tmp00!=NULL)
+      sprintf(buffer,"%s/%s",tmp0,tmp00->value);
+    free(tmp0);
+    buffer[strlen(buffer)-1]=0;
+    if(i+1<level){ 
+      #ifdef IGNORE_METAPATH
+        map* tmpMap = createMap("metapath", "");
+      #else  
+        map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
+      #endif	  
+      if(tmpMap==NULL || strlen(tmpMap->value)==0){
+	char *tmp01=zStrdup(tmp00->value);
+	tmp01[strlen(tmp01)-1]=0;
+	setMapInMaps(conf,"lenv","metapath",tmp01);
+	free(tmp01);
+	tmp01=NULL;
+      }
+      else{
+	if(tmp00!=NULL && tmpMap!=NULL){
+	  char *tmp00s=zStrdup(tmp00->value);
+	  tmp00s[strlen(tmp00s)-1]=0;
+	  char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
+	  sprintf(value,"%s/%s",tmpMap->value,tmp00s);
+	  setMapInMaps(conf,"lenv","metapath",value);
+	  free(value);
+	  free(tmp00s);
+	  value=NULL;
+	}
+      }
+    }else{
+      char *tmp01=zStrdup(tmp00->value);
+      tmp01[strlen(tmp01)-1]=0;
+      setMapInMaps(conf,"lenv","Identifier",tmp01);
+      free(tmp01);
+    }
+  }
+  char *tmp0=zStrdup(buffer);
+  sprintf(buffer,"%s.zcfg",tmp0);
+  free(tmp0);
+  free(lid);
+}
+
+/**
+ * Converts a hex character to its integer value 
+ *
+ * @param ch the char to convert
+ * @return the converted char 
+ */
+char from_hex(char ch) {
+  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
+}
+
+/**
+ * Converts an integer value to its hec character 
+ *
+ * @param code the char to convert
+ * @return the converted char 
+ */
+char to_hex(char code) {
+  static char hex[] = "0123456789abcdef";
+  return hex[code & 15];
+}
+
+/**
+ * URLEncode an url
+ *
+ * @param str the url to encode
+ * @return a url-encoded version of str
+ * @warning be sure to free() the returned string after use
+ */
+char *url_encode(char *str) {
+  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
+  while (*pstr) {
+    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
+      *pbuf++ = *pstr;
+    else if (*pstr == ' ') 
+      *pbuf++ = '+';
+    else 
+      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+    pstr++;
+  }
+  *pbuf = '\0';
+  return buf;
+}
+
+/**
+ * Decode an URLEncoded url
+ *
+ * @param str the URLEncoded url to decode
+ * @return a url-decoded version of str
+ * @warning be sure to free() the returned string after use
+ */
+char *url_decode(char *str) {
+  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
+  while (*pstr) {
+    if (*pstr == '%') {
+      if (pstr[1] && pstr[2]) {
+        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
+        pstr += 2;
+      }
+    } else if (*pstr == '+') { 
+      *pbuf++ = ' ';
+    } else {
+      *pbuf++ = *pstr;
+    }
+    pstr++;
+  }
+  *pbuf = '\0';
+  return buf;
+}
+
+/**
+ * Verify if a given language is listed in the lang list defined in the [main] 
+ * section of the main.cfg file.
+ * 
+ * @param conf the map containing the settings from the main.cfg file
+ * @param str the specific language
+ * @return 1 if the specific language is listed, -1 in other case.
+ */
+int isValidLang(maps* conf,const char *str){
+  map *tmpMap=getMapFromMaps(conf,"main","lang");
+  char *tmp=zStrdup(tmpMap->value);
+  char *pToken,*saveptr;
+  pToken=strtok_r(tmp,",",&saveptr);
+  int res=-1;
+  char *pToken1,*saveptr1;
+  pToken1=strtok_r(tmp,",",&saveptr1);
+  while(pToken1!=NULL){
+    while(pToken!=NULL){
+      if(strcasecmp(pToken1,pToken)==0){
+	res=1;
+	break;
+      }
+      pToken=strtok_r(NULL,",",&saveptr);
+    }
+    pToken1=strtok_r(NULL,",",&saveptr1);
+  }
+  free(tmp);
+  return res;
+}
+
+
+/**
+ * Access the value of the encoding key in a maps
+ *
+ * @param m the maps to search for the encoding key
+ * @return the value of the encoding key in a maps if encoding key exists,
+ *  "UTF-8" in other case.
+ */
+char* getEncoding(maps* m){
+  if(m!=NULL){
+    map* tmp=getMap(m->content,"encoding");
+    if(tmp!=NULL){
+      return tmp->value;
+    }
+    else
+      return (char*)"UTF-8";
+  }
+  else
+    return (char*)"UTF-8";  
+}
+
+/**
+ * Access the value of the version key in a maps
+ *
+ * @param m the maps to search for the version key
+ * @return the value of the version key in a maps if encoding key exists,
+ *  "1.0.0" in other case.
+ */
+char* getVersion(maps* m){
+  if(m!=NULL){
+    map* tmp=getMap(m->content,"version");
+    if(tmp!=NULL){
+      return tmp->value;
+    }
+    else
+      return (char*)"1.0.0";
+  }
+  else
+    return (char*)"1.0.0";
+}
+
+/**
+ * Read a file generated by a service.
+ * 
+ * @param m the conf maps
+ * @param content the output item
+ * @param filename the file to read
+ */
+void readGeneratedFile(maps* m,map* content,char* filename){
+  FILE * file=fopen(filename,"rb");
+  if(file==NULL){
+    fprintf(stderr,"Failed to open file %s for reading purpose.\n",filename);
+    setMapInMaps(m,"lenv","message","Unable to read produced file. Please try again later");
+    return ;
+  }
+  fseek(file, 0, SEEK_END);
+  long count = ftell(file);
+  rewind(file);
+  struct stat file_status; 
+  stat(filename, &file_status);
+  map* tmpMap1=getMap(content,"value");
+  if(tmpMap1==NULL){
+    addToMap(content,"value","");
+    tmpMap1=getMap(content,"value");
+  }
+  free(tmpMap1->value);
+  tmpMap1->value=(char*) malloc((count+1)*sizeof(char));  
+  fread(tmpMap1->value,1,count,file);
+  tmpMap1->value[count]=0;
+  fclose(file);
+  char rsize[1000];
+  sprintf(rsize,"%ld",count);
+  addToMap(content,"size",rsize);
+}
+
+
+/**
+ * Write a file from value and length
+ *
+ * @param fname the file name
+ * @param val the value
+ * @param length the value length
+ */
+int writeFile(char* fname,char* val,int length){
+  FILE* of=fopen(fname,"wb");
+  if(of==NULL){
+    return -1;
+  }
+  size_t ret=fwrite(val,sizeof(char),length,of);
+  if(ret<length){
+    fprintf(stderr,"Write error occured!\n");
+    fclose(of);
+    return -1;
+  }
+  fclose(of);
+  return 1;
+}
+
+/**
+ * Dump all values in a maps as files
+ *
+ * @param main_conf the maps containing the settings of the main.cfg file
+ * @param in the maps containing values to dump as files
+ */
+void dumpMapsValuesToFiles(maps** main_conf,maps** in){
+  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
+  map* tmpSid=getMapFromMaps(*main_conf,"lenv","usid");
+  maps* inputs=*in;
+  int length=0;
+  while(inputs!=NULL){
+    if(getMap(inputs->content,"mimeType")!=NULL &&
+       getMap(inputs->content,"cache_file")==NULL){
+      map* cMap=inputs->content;
+      if(getMap(cMap,"length")!=NULL){
+	map* tmpLength=getMap(cMap,"length");
+	int len=atoi(tmpLength->value);
+	int k=0;
+	for(k=0;k<len;k++){
+	  map* cMimeType=getMapArray(cMap,"mimeType",k);
+	  map* cValue=getMapArray(cMap,"value",k);
+	  map* cSize=getMapArray(cMap,"size",k);
+	  char file_ext[32];
+	  getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
+	  char* val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
+	  sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,k,file_ext);
+	  length=0;
+	  if(cSize!=NULL){
+	    length=atoi(cSize->value);
+	  }
+	  writeFile(val,cValue->value,length);
+	  setMapArray(cMap,"cache_file",k,val);
+	  free(val);
+	}
+      }else{
+	int length=0;
+	map* cMimeType=getMap(cMap,"mimeType");
+	map* cValue=getMap(cMap,"value");
+	map* cSize=getMap(cMap,"size");
+	char file_ext[32];
+	getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
+	char *val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
+	sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,0,file_ext);
+	if(cSize!=NULL){
+	  length=atoi(cSize->value);
+	}
+	writeFile(val,cValue->value,length);
+	addToMap(cMap,"cache_file",val);
+	free(val);
+      }
+    }
+    inputs=inputs->next;
+  }
+}
+
+
+/**
+ * Base64 encoding of a char*
+ *
+ * @param input the value to encode
+ * @param length the value length
+ * @return the buffer containing the base64 value
+ * @warning make sure to free the returned value
+ */
+char *base64(const char *input, int length)
+{
+  BIO *bmem, *b64;
+  BUF_MEM *bptr;
+
+  b64 = BIO_new(BIO_f_base64());
+  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+  bmem = BIO_new(BIO_s_mem());
+  b64 = BIO_push(b64, bmem);
+  BIO_write(b64, input, length);
+  BIO_flush(b64);
+  BIO_get_mem_ptr(b64, &bptr);
+
+  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
+  memcpy(buff, bptr->data, bptr->length);
+  buff[bptr->length] = 0;
+
+  BIO_free_all(b64);
+
+  return buff;
+}
+
+/**
+ * Base64 decoding of a char*
+ *
+ * @param input the value to decode
+ * @param length the value length
+ * @param red the value length
+ * @return the buffer containing the base64 value 
+ * @warning make sure to free the returned value
+ */
+char *base64d(const char *input, int length,int* red)
+{
+  BIO *b64, *bmem;
+
+  char *buffer = (char *)malloc(length);
+  if(buffer){
+    memset(buffer, 0, length);
+    b64 = BIO_new(BIO_f_base64());
+    if(b64){
+      bmem = BIO_new_mem_buf((unsigned char*)input,length);
+      bmem = BIO_push(b64, bmem);
+      *red=BIO_read(bmem, buffer, length);
+      buffer[length-1]=0;
+      BIO_free_all(bmem);
+    }
+  }
+  return buffer;
+}
+
+/**
+ * Read Base64 value and split it value by lines of 64 char.
+ *
+ * @param in the map containing the value to split
+ */
+void readBase64(map **in){
+  char *res = NULL;
+  char *curs = (*in)->value;
+  int i = 0;
+  for (i = 0; i <= strlen ((*in)->value) / 64;
+       i++)
+    {
+      if (res == NULL)
+	res =
+	  (char *) malloc (65 * sizeof (char));
+      else
+	res =
+	  (char *) realloc (res,
+			    (((i + 1) * 65) +
+			     i) * sizeof (char));
+      int csize = i * 65;
+      strncpy (res + csize, curs, 64);
+      if (i == strlen ((*in)->value) / 64)
+	strcat (res, "\n\0");
+      else
+	{
+	  strncpy (res + (((i + 1) * 64) + i),
+		   "\n\0", 2);
+	  curs += 64;
+	}
+    }
+  free ((*in)->value);
+  (*in)->value = zStrdup (res);
+  free (res);
+}
+
+
+/**
+ * Add the default values defined in the zcfg to a maps.
+ *
+ * @param out the maps containing the inputs or outputs given in the initial
+ *  HTTP request
+ * @param in the description of all inputs or outputs available for a service
+ * @param m the maps containing the settings of the main.cfg file
+ * @param type 0 for inputs and 1 for outputs
+ * @param err the map to store potential missing mandatory input parameters or
+ *  wrong output names depending on the type.
+ * @return "" if no error was detected, the name of last input or output causing
+ *  an error.
+ */
+char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
+  map *res=*err;
+  elements* tmpInputs=in;
+  maps* out1=*out;
+  char *result=NULL;
+  int nb=0;
+  if(type==1){
+    while(out1!=NULL){
+      if(getElements(in,out1->name)==NULL){
+	if(res==NULL){
+	  res=createMap("value",out1->name);
+	}else{
+	  setMapArray(res,"value",nb,out1->name);
+	}
+	nb++;
+	result=out1->name;
+      }
+      out1=out1->next;
+    }
+    if(res!=NULL){
+      *err=res;
+      return result;
+    }
+    out1=*out;
+  }
+  while(tmpInputs!=NULL){
+    maps *tmpMaps=getMaps(out1,tmpInputs->name);
+    if(tmpMaps==NULL){
+      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
+      tmpMaps2->name=strdup(tmpInputs->name);
+      tmpMaps2->content=NULL;
+      tmpMaps2->next=NULL;
+      
+      if(type==0){
+	map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
+	if(tmpMapMinO!=NULL){
+	  if(atoi(tmpMapMinO->value)>=1){
+	    freeMaps(&tmpMaps2);
+	    free(tmpMaps2);
+	    if(res==NULL){
+	      res=createMap("value",tmpInputs->name);
+	    }else{
+	      setMapArray(res,"value",nb,tmpInputs->name);
+	    }
+	    nb++;
+	    result=tmpInputs->name;
+	  }
+	  else{
+	    if(tmpMaps2->content==NULL)
+	      tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
+	    else
+	      addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
+	  }
+	}
+	if(res==NULL){
+	  map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
+	  if(tmpMaxO!=NULL){
+	    if(tmpMaps2->content==NULL)
+	      tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
+	    else
+	      addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
+	  }
+	  map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
+	  if(tmpMaxMB!=NULL){
+	    if(tmpMaps2->content==NULL)
+	      tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
+	    else
+	      addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
+	  }
+	}
+      }
+
+      if(res==NULL){
+	iotype* tmpIoType=tmpInputs->defaults;
+	if(tmpIoType!=NULL){
+	  map* tmpm=tmpIoType->content;
+	  while(tmpm!=NULL){
+	    if(tmpMaps2->content==NULL)
+	      tmpMaps2->content=createMap(tmpm->name,tmpm->value);
+	    else
+	      addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
+	    tmpm=tmpm->next;
+	  }
+	}
+	addToMap(tmpMaps2->content,"inRequest","false");
+	if(type==0){
+	  map *tmpMap=getMap(tmpMaps2->content,"value");
+	  if(tmpMap==NULL)
+	    addToMap(tmpMaps2->content,"value","NULL");
+	}
+	if(out1==NULL){
+	  *out=dupMaps(&tmpMaps2);
+	  out1=*out;
+	}
+	else
+	  addMapsToMaps(&out1,tmpMaps2);
+	freeMap(&tmpMaps2->content);
+	free(tmpMaps2->content);
+	tmpMaps2->content=NULL;
+	freeMaps(&tmpMaps2);
+	free(tmpMaps2);
+	tmpMaps2=NULL;
+      }
+    }
+    else{
+      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
+					     tmpMaps->content);
+      if(type==0) {
+	/**
+	 * In case of an Input maps, then add the minOccurs and maxOccurs to the
+	 * content map.
+	 */
+	map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
+	if(tmpMap1!=NULL){
+	  if(tmpMaps->content==NULL)
+	    tmpMaps->content=createMap("minOccurs",tmpMap1->value);
+	  else
+	    addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
+	}
+	map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
+	if(tmpMaxO!=NULL){
+	  if(tmpMaps->content==NULL)
+	    tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
+	  else
+	    addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
+	}
+	map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
+	if(tmpMaxMB!=NULL){
+	  if(tmpMaps->content==NULL)
+	    tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
+	  else
+	    addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
+	}
+	/**
+	 * Parsing BoundingBoxData, fill the following map and then add it to
+	 * the content map of the Input maps: 
+	 * lowerCorner, upperCorner, srs and dimensions
+	 * cf. parseBoundingBox
+	 */
+	if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
+	  maps* tmpI=getMaps(*out,tmpInputs->name);
+	  if(tmpI!=NULL){
+	    map* tmpV=getMap(tmpI->content,"value");
+	    if(tmpV!=NULL){
+	      char *tmpVS=strdup(tmpV->value);
+	      map* tmp=parseBoundingBox(tmpVS);
+	      free(tmpVS);
+	      map* tmpC=tmp;
+	      while(tmpC!=NULL){
+		addToMap(tmpMaps->content,tmpC->name,tmpC->value);
+		tmpC=tmpC->next;
+	      }
+	      freeMap(&tmp);
+	      free(tmp);
+	    }
+	  }
+	}
+      }
+
+      if(tmpIoType!=NULL){
+	map* tmpContent=tmpIoType->content;
+	map* cval=NULL;
+	int hasPassed=-1;
+	while(tmpContent!=NULL){
+	  if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
+#ifdef DEBUG
+	    fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
+#endif
+	    if(tmpMaps->content==NULL)
+	      tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
+	    else
+	      addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
+	    
+	    if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
+	      map* length=getMap(tmpMaps->content,"length");
+	      int i;
+	      char *tcn=strdup(tmpContent->name);
+	      for(i=1;i<atoi(length->value);i++){
+#ifdef DEBUG
+		dumpMap(tmpMaps->content);
+		fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
+#endif
+		int len=strlen((char*) tcn);
+		char *tmp1=(char *)malloc((len+10)*sizeof(char));
+		sprintf(tmp1,"%s_%d",tcn,i);
+#ifdef DEBUG
+		fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
+#endif
+		addToMap(tmpMaps->content,tmp1,tmpContent->value);
+		free(tmp1);
+		hasPassed=1;
+	      }
+	      free(tcn);
+	    }
+	  }
+	  tmpContent=tmpContent->next;
+	}
+#ifdef USE_MS
+	/**
+	 * check for useMapServer presence
+	 */
+	map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
+	if(tmpCheck!=NULL){
+	  // Get the default value
+	  tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
+	  tmpCheck=getMap(tmpMaps->content,"mimeType");
+	  addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
+	  map* cursor=tmpIoType->content;
+	  while(cursor!=NULL){
+	    addToMap(tmpMaps->content,cursor->name,cursor->value);
+	    cursor=cursor->next;
+	  }
+	  
+	  cursor=tmpInputs->content;
+	  while(cursor!=NULL){
+	    if(strcasecmp(cursor->name,"Title")==0 ||
+	       strcasecmp(cursor->name,"Abstract")==0)
+	      addToMap(tmpMaps->content,cursor->name,cursor->value);
+           cursor=cursor->next;
+	  }
+	}
+#endif
+      }
+      if(tmpMaps->content==NULL)
+	tmpMaps->content=createMap("inRequest","true");
+      else
+	addToMap(tmpMaps->content,"inRequest","true");
+
+    }
+    tmpInputs=tmpInputs->next;
+  }
+  if(res!=NULL){
+    *err=res;
+    return result;
+  }
+  return "";
+}
+
+/**
+ * Access the last error message returned by the OS when trying to dynamically
+ * load a shared library.
+ *
+ * @return the last error message
+ * @warning The character string returned from getLastErrorMessage resides
+ * in a static buffer. The application should not write to this
+ * buffer or attempt to free() it.
+ */ 
+char* getLastErrorMessage() {                                              
+#ifdef WIN32
+  LPVOID lpMsgBuf;
+  DWORD errCode = GetLastError();
+  static char msg[ERROR_MSG_MAX_LENGTH];
+  size_t i;
+  
+  DWORD length = FormatMessage(
+			       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+			       FORMAT_MESSAGE_FROM_SYSTEM |
+			       FORMAT_MESSAGE_IGNORE_INSERTS,
+			       NULL,
+			       errCode,
+			       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+			       (LPTSTR) &lpMsgBuf,
+			       0, NULL );	
+  
+#ifdef UNICODE		
+  wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
+	      (wchar_t*) lpMsgBuf, _TRUNCATE );
+#else
+  strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
+	    (char *) lpMsgBuf );		
+#endif	
+  LocalFree(lpMsgBuf);
+  
+  return msg;
+#else
+  return dlerror();
+#endif
+}
+
+#include <dirent.h>
+#ifndef RELY_ON_DB
+/**
+ * Read the Result file (.res).
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ */
+void readFinalRes(maps* conf,char* pid,map* statusInfo){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char* fbkpid =
+    (char *)
+    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
+  sprintf (fbkpid, "%s/%s.res", r_inputs->value, pid);
+  struct stat file_status;
+  int istat = stat (fbkpid, &file_status);
+  if (istat == 0 && file_status.st_size > 0)
+    {
+      maps *res = (maps *) malloc (MAPS_SIZE);
+      conf_read (fbkpid, res);
+      map* status=getMapFromMaps(res,"status","status");
+      addToMap(statusInfo,"Status",status->value);
+      freeMaps(&res);
+      free(res);
+    }
+  else
+    addToMap(statusInfo,"Status","Failed");  
+  free(fbkpid);
+}
+
+/**
+ * Check if a service is running.
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the unique service identifier (usid from the lenv section)
+ * @return 1 in case the service is still running, 0 otherwise
+ */
+int isRunning(maps* conf,char* pid){
+  int res=0;
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char* fbkpid =
+    (char *)
+    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
+  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
+  FILE* f0 = fopen (fbkpid, "r");
+  if(f0!=NULL){
+    fclose(f0);
+    res=1;
+  }
+  free(fbkpid);
+  return res;
+}
+#else
+#include "sqlapi.h"
+#endif
+
+/**
+ * Run GetStatus requests.
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @param req the request (GetStatus / GetResult)
+ */
+void runGetStatus(maps* conf,char* pid,char* req){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char *sid=getStatusId(conf,pid);
+  if(sid==NULL){
+    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
+		    "NoSuchJob", pid);
+  }else{
+    map* statusInfo=createMap("JobID",pid);
+    if(isRunning(conf,pid)>0){
+      if(strncasecmp(req,"GetResult",strlen(req))==0){
+	errorException (conf, _("The result for the requested JobID has not yet been generated. "),
+			"ResultNotReady", pid);
+	return;
+      }
+      else
+	if(strncasecmp(req,"GetStatus",strlen(req))==0){
+	  addToMap(statusInfo,"Status","Running");
+	  char* tmpStr=_getStatus(conf,pid);
+	  if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
+	    char *tmpStr1=strdup(tmpStr);
+	    char *tmpStr0=strdup(strstr(tmpStr,"|")+1);
+	    free(tmpStr);
+	    tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
+	    addToMap(statusInfo,"PercentCompleted",tmpStr1);
+	    addToMap(statusInfo,"Message",tmpStr0);
+	    free(tmpStr0);
+	    free(tmpStr1);
+	  }
+	}
+    }
+    else{
+      if(strncasecmp(req,"GetResult",strlen(req))==0){
+	char* result=_getStatusFile(conf,pid);
+	if(result!=NULL){
+	  char *encoding=getEncoding(conf);
+	  fprintf(stdout,"Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
+	  fprintf(stdout,"%s",result);
+	  fflush(stdout);
+	  freeMap(&statusInfo);
+	  free(statusInfo);
+	  return;
+	}else{
+	  errorException (conf, _("The result for the requested JobID has not yet been generated. "),
+			  "ResultNotReady", pid);
+	  freeMap(&statusInfo);
+	  free(statusInfo);
+	  return;
+	}
+      }else
+	if(strncasecmp(req,"GetStatus",strlen(req))==0){
+	  readFinalRes(conf,pid,statusInfo);
+	  char* tmpStr=_getStatus(conf,pid);
+	  if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
+	    char *tmpStr1=strdup(tmpStr);
+	    char *tmpStr0=strdup(strstr(tmpStr,"|")+1);
+	    free(tmpStr);
+	    tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
+	    addToMap(statusInfo,"PercentCompleted",tmpStr1);
+	    addToMap(statusInfo,"Message",tmpStr0);
+	    free(tmpStr0);
+	    free(tmpStr1);
+	  }
+	}
+    }
+    printStatusInfo(conf,statusInfo,req);
+    freeMap(&statusInfo);
+    free(statusInfo);
+  }
+  return;
+}
+
+/**
+ * Run Dismiss requests.
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ */
+void runDismiss(maps* conf,char* pid){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char *sid=getStatusId(conf,pid);
+  if(sid==NULL){
+    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
+		    "NoSuchJob", pid);
+  }else{
+    // We should send the Dismiss request to the target host if it differs
+    char* fbkpid =
+      (char *)
+      malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
+    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, pid);
+    FILE* f0 = fopen (fbkpid, "r");
+    if(f0!=NULL){
+      long flen;
+      char *fcontent;
+      fseek (f0, 0, SEEK_END);
+      flen = ftell (f0);
+      fseek (f0, 0, SEEK_SET);
+      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
+      fread(fcontent,flen,1,f0);
+      fcontent[flen]=0;
+      fclose(f0);
+      kill(atoi(fcontent),SIGKILL);
+      free(fcontent);
+    }
+    free(fbkpid);
+    struct dirent *dp;
+    DIR *dirp = opendir(r_inputs->value);
+    char fileName[1024];
+    int hasFile=-1;
+    if(dirp!=NULL){
+      while ((dp = readdir(dirp)) != NULL){
+#ifdef DEBUG
+	fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
+#endif
+	if(strstr(dp->d_name,pid)!=0){
+	  sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
+	  if(unlink(fileName)!=0){
+	    errorException (conf, _("The job cannot be removed, a file cannot be removed"),
+			    "NoApplicableCode", NULL);
+	    return;
+	  }
+	}
+      }
+    }
+#ifdef RELY_ON_DB
+    removeService(conf,pid);
+#endif
+    map* statusInfo=createMap("JobID",pid);
+    addToMap(statusInfo,"Status","Dismissed");
+    printStatusInfo(conf,statusInfo,"Dismiss");
+    free(statusInfo);
+  }
+  return;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/server_internal.h	(revision 672)
@@ -0,0 +1,63 @@
+/*
+ * Author : Gérald Fenoy
+ *
+ *  Copyright 2008-2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "ulinet.h"
+#include "service.h"
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+extern   int conf_read(const char*,maps*);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+  char *get_uuid();  
+  char *base64(const char*,int);
+  char *base64d(const char*,int,int*);
+  void readBase64(map **);
+  char *url_decode(char *);
+  int getVersionId(const char*);
+  void readGeneratedFile(maps*,map*,char*);
+  int getServiceFromYAML(maps*,char*,service**,char *name);
+  char* addDefaultValues(maps**,elements*,maps*,int,map**);
+  char* getEncoding(maps*);
+  void parseIdentifier(maps*,char*,char*,char*);
+  void dumpMapsValuesToFiles(maps**,maps**);
+  void runDismiss(maps*,char*);
+  void runGetStatus(maps*,char*,char*);
+
+  int isValidLang(maps*,const char*);
+  
+  char* getLastErrorMessage();
+  
+#ifdef __cplusplus
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.c	(revision 672)
@@ -0,0 +1,1507 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service.h"
+
+/**
+ * Dump a map on stderr
+ *
+ * @param t the map to dump
+ */
+void _dumpMap(map* t){
+  if(t!=NULL){
+    fprintf(stderr,"%s: %s\n",t->name,t->value);
+    fflush(stderr);
+  }else{
+    fprintf(stderr,"NULL\n");
+    fflush(stderr);
+  }
+}
+
+/**
+ * Dump a map on stderr, see _dumpMap()
+ *
+ * @param t the map to dump
+ */
+void dumpMap(map* t){
+  map* tmp=t;
+  while(tmp!=NULL){
+    _dumpMap(tmp);
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Dump a map to a file
+ *
+ * @param t the map to dump to file
+ * @param file the file to store the map
+ */
+void dumpMapToFile(map* t,FILE* file){
+  map* tmp=t;
+  while(tmp!=NULL){
+#ifdef DEBUG
+    fprintf(stderr,"%s = %s\n",tmp->name,tmp->value);
+#endif
+    fprintf(file,"%s = %s\n",tmp->name,tmp->value);
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Dump a maps on stderr, see dumpMap().
+ *
+ * @param m the map to dump
+ */
+void dumpMaps(maps* m){
+  maps* tmp=m;
+  while(tmp!=NULL){
+    fprintf(stderr,"MAP => [%s] \n",tmp->name);
+    dumpMap(tmp->content);
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Dump a maps to a file, see dumpMapToFile().
+ *
+ * @param m the map to dump
+ * @param file_path the full path to the file name to store the map
+ */
+void dumpMapsToFile(maps* m,char* file_path){
+  FILE* file=fopen(file_path,"w");
+  maps* tmp=m;
+  while(tmp!=NULL){
+    fprintf(file,"[%s]\n",tmp->name);
+    dumpMapToFile(tmp->content,file);
+    fflush(file);
+    tmp=tmp->next;
+  }
+  fclose(file);
+}
+  
+/**
+ * Create a new map
+ *
+ * @param name the key to add to the map
+ * @param value the corresponding value to add to the map
+ * @return the allocated map
+ */
+map* createMap(const char* name,const char* value){
+  map* tmp=(map *)malloc(MAP_SIZE);
+  tmp->name=zStrdup(name);
+  tmp->value=zStrdup(value);
+  tmp->next=NULL;
+  return tmp;
+}
+
+/**
+ * Count number of map in a map
+ *
+ * @param m the maps to count
+ * @return number of map in a map
+ */
+int count(map* m){
+  map* tmp=m;
+  int c=0;
+  while(tmp!=NULL){
+    c++;
+    tmp=tmp->next;
+  }
+  return c;
+}
+
+/**
+ * Verify if a key exist in a map
+ *
+ * @param m the map to search for the key
+ * @param key the key to search in the map
+ * @return true if the key wwas found, false in other case
+ */
+bool hasKey(map* m,const char *key){
+  map* tmp=m;
+  while(tmp!=NULL){
+    if(strcasecmp(tmp->name,key)==0)
+      return true;
+    tmp=tmp->next;
+  }
+#ifdef DEBUG_MAP
+  fprintf(stderr,"NOT FOUND \n");
+#endif
+  return false;
+}
+
+/**
+ * Access a specific maps
+ *
+ * @param m the maps to search for the key
+ * @param key the key to search in the maps
+ * @return a pointer on the maps found or NULL if not found
+ */
+maps* getMaps(maps* m,const char *key){
+  maps* tmp=m;
+  while(tmp!=NULL){
+    if(strcasecmp(tmp->name,key)==0){
+      return tmp;
+    }
+    tmp=tmp->next;
+  }
+  return NULL;
+}
+
+/**
+ * Access a specific map
+ *
+ * @param m the map to search for the key
+ * @param key the key to search in the map
+ * @return a pointer on the map found or NULL if not found
+ */
+map* getMap(map* m,const char *key){
+  map* tmp=m;
+  while(tmp!=NULL){
+    if(strcasecmp(tmp->name,key)==0){
+      return tmp;
+    }
+    tmp=tmp->next;
+  }
+  return NULL;
+}
+
+
+/**
+ * Access the last map
+ *
+ * @param m the map to search for the lastest map
+ * @return a pointer on the lastest map found or NULL if not found
+ */
+map* getLastMap(map* m){
+  map* tmp=m;
+  while(tmp!=NULL){
+    if(tmp->next==NULL){
+      return tmp;
+    }
+    tmp=tmp->next;
+  }
+  return NULL;
+}
+
+/**
+ * Access a specific map from a maps
+ *
+ * @param m the maps to search for the key
+ * @param key the key to search in the maps
+ * @param subkey the key to search in the map (found for the key, if any)
+ * @return a pointer on the map found or NULL if not found
+ */
+map* getMapFromMaps(maps* m,const char* key,const char* subkey){
+  maps* _tmpm=getMaps(m,key);
+  if(_tmpm!=NULL){
+    map* _ztmpm=getMap(_tmpm->content,subkey);
+    return _ztmpm;
+  }
+  else return NULL;
+}
+
+/**
+ * Free allocated memory of a map.
+ * Require to call free on mo after calling this function.
+ *
+ * @param mo the map to free
+ */
+void freeMap(map** mo){
+  map* _cursor=*mo;
+  if(_cursor!=NULL){
+#ifdef DEBUG
+    fprintf(stderr,"freeMap\n");
+#endif
+    free(_cursor->name);
+    free(_cursor->value);
+    if(_cursor->next!=NULL){
+      freeMap(&_cursor->next);
+      free(_cursor->next);
+    }
+  }
+}
+
+/**
+ * Free allocated memory of a maps.
+ * Require to call free on mo after calling this function.
+ *
+ * @param mo the maps to free
+ */
+void freeMaps(maps** mo){
+  maps* _cursor=*mo;
+  if(_cursor && _cursor!=NULL){
+#ifdef DEBUG
+    fprintf(stderr,"freeMaps\n");
+#endif
+    free(_cursor->name);
+    if(_cursor->content!=NULL){
+      freeMap(&_cursor->content);
+      free(_cursor->content);
+    }
+    if(_cursor->next!=NULL){
+      freeMaps(&_cursor->next);
+      free(_cursor->next);
+    }
+  }
+}
+
+/**
+ * Verify if an elements contains a name equal to the given key.
+ *
+ * @param e the elements to search for the key
+ * @param key the elements name to search
+ * @return true if the elements contains the name, false in other cases.
+ */ 
+bool hasElement(elements* e,const char* key){
+  elements* tmp=e;
+  while(tmp!=NULL){
+    if(strcasecmp(key,tmp->name)==0)
+      return true;
+    tmp=tmp->next;
+  }
+  return false;
+}
+
+/**
+ * Access a specific elements named key.
+ *
+ * @param m the elements to search
+ * @param key the elements name to search
+ * @return a pointer to the specific element if found, NULL in other case.
+ */ 
+elements* getElements(elements* m,char *key){
+  elements* tmp=m;
+  while(tmp!=NULL){
+    if(strcasecmp(tmp->name,key)==0)
+      return tmp;
+    tmp=tmp->next;
+  }
+  return NULL;
+}
+
+/**
+ * Free allocated memory of an iotype.
+ * Require to call free on i after calling this function.
+ *
+ * @param i the iotype to free
+ */
+void freeIOType(iotype** i){
+  iotype* _cursor=*i;
+  if(_cursor!=NULL){
+    if(_cursor->next!=NULL){
+      freeIOType(&_cursor->next);
+      free(_cursor->next);
+    }
+    freeMap(&_cursor->content);
+    free(_cursor->content);
+  }
+}
+
+/**
+ * Free allocated memory of an elements.
+ * Require to call free on e after calling this function.
+ *
+ * @param e the iotype to free
+ */
+void freeElements(elements** e){
+  elements* tmp=*e;
+  if(tmp!=NULL){
+    if(tmp->name!=NULL)
+      free(tmp->name);
+    freeMap(&tmp->content);
+    if(tmp->content!=NULL)
+      free(tmp->content);
+    freeMap(&tmp->metadata);
+    if(tmp->metadata!=NULL)
+      free(tmp->metadata);
+    if(tmp->format!=NULL)
+      free(tmp->format);
+    freeIOType(&tmp->defaults);
+    if(tmp->defaults!=NULL)
+      free(tmp->defaults);
+    freeIOType(&tmp->supported);
+    if(tmp->supported!=NULL){
+      free(tmp->supported);
+    }
+    freeElements(&tmp->next);
+    if(tmp->next!=NULL)
+      free(tmp->next);
+  }
+}
+
+/**
+ * Free allocated memory of a service.
+ * Require to call free on e after calling this function.
+ *
+ * @param s the service to free
+ */
+void freeService(service** s){
+  service* tmp=*s;
+  if(tmp!=NULL){
+    if(tmp->name!=NULL)
+      free(tmp->name);
+    freeMap(&tmp->content);
+    if(tmp->content!=NULL)
+      free(tmp->content);
+    freeMap(&tmp->metadata);
+    if(tmp->metadata!=NULL)
+      free(tmp->metadata);
+    freeElements(&tmp->inputs);
+    if(tmp->inputs!=NULL)
+      free(tmp->inputs);
+    freeElements(&tmp->outputs);
+    if(tmp->outputs!=NULL)
+      free(tmp->outputs);
+  }
+}
+
+/**
+ * Add key value pair to an existing map.
+ *
+ * @param m the map to add the KVP
+ * @param n the key to add
+ * @param v the corresponding value to add
+ */
+void addToMap(map* m,const char* n,const char* v){
+  if(hasKey(m,n)==false){
+    map* _cursor=m;
+    while(_cursor->next!=NULL){
+      _cursor=_cursor->next;
+    }
+    _cursor->next=createMap(n,v);
+  }
+  else{
+    map *tmp=getMap(m,n);
+    if(tmp->value!=NULL)
+      free(tmp->value);
+    tmp->value=zStrdup(v);
+  }
+}
+
+/**
+ * Add a key and an integer value to an existing map.
+ *
+ * @param m the map to add the KVP
+ * @param n the key to add
+ * @param v the corresponding value to add
+ */
+void addIntToMap(map* m,const char* n,const int v){
+  char svalue[10];
+  sprintf(svalue,"%d",v);
+  if(hasKey(m,n)==false){
+    map* _cursor=m;
+    while(_cursor->next!=NULL){
+      _cursor=_cursor->next;
+    }
+    _cursor->next=createMap(n,svalue);
+  }
+  else{
+    map *tmp=getMap(m,n);
+    if(tmp->value!=NULL)
+      free(tmp->value);
+    tmp->value=zStrdup(svalue);
+  }
+}
+
+/**
+ * Add a key and a binary value to an existing map.
+ *
+ * @param m the map to add the KVP
+ * @param n the key to add
+ * @param v the corresponding value to add
+ * @param size the size of the given value
+ */
+void addToMapWithSize(map* m,const char* n,const char* v,int size){
+  if(hasKey(m,n)==false){
+    map* _cursor=m;
+    if(_cursor!=NULL){
+      addToMap(m,n,"");
+    }else{
+      m=createMap(n,"");
+    }
+  }
+  char sname[10]="size";
+  if(strlen(n)>5)
+    sprintf(sname,"size_%s",n+6);
+  map *tmp=getMap(m,n);
+  if(tmp->value!=NULL)
+    free(tmp->value);
+  tmp->value=(char*)malloc((size+1)*sizeof(char));
+  memmove(tmp->value,v,size*sizeof(char));
+  tmp->value[size]=0;
+  char sin[128];
+  sprintf(sin,"%d",size);
+  addToMap(m,sname,sin);
+}
+
+/**
+ * Add a map at the end of another map.
+ *
+ * @param mo the map to add mi
+ * @param mi the map to add to mo
+ */
+void addMapToMap(map** mo,map* mi){
+  map* tmp=mi;
+  map* _cursor=*mo;
+  while(tmp!=NULL){
+    if(_cursor==NULL){
+      *mo=createMap(tmp->name,tmp->value);
+      (*mo)->next=NULL;
+    }
+    else{
+#ifdef DEBUG
+      fprintf(stderr,"_CURSOR\n");
+      dumpMap(_cursor);
+#endif
+      while(_cursor->next!=NULL)
+	_cursor=_cursor->next;
+      map* tmp1=getMap(*mo,tmp->name);
+      if(tmp1==NULL){
+	_cursor->next=createMap(tmp->name,tmp->value);
+      }
+      else{
+	addToMap(*mo,tmp->name,tmp->value);
+      }
+    }
+    _cursor=*mo;
+    tmp=tmp->next;
+#ifdef DEBUG
+    fprintf(stderr,"MO\n");
+    dumpMap(*mo);
+#endif
+  }
+}
+
+/**
+ * Add a map to iotype.
+ *
+ * @param io the iotype to add the map
+ * @param mi the map to add to io
+ */
+void addMapToIoType(iotype** io,map* mi){
+  iotype* tmp=*io;
+  while(tmp->next!=NULL){
+    tmp=tmp->next;
+  }
+  tmp->next=(iotype*)malloc(IOTYPE_SIZE);
+  tmp->next->content=NULL;
+  addMapToMap(&tmp->next->content,mi);
+  tmp->next->next=NULL;
+}
+
+/**
+ * Access a specific map or set its value.
+ *
+ * @param m the map to search for the key
+ * @param key the key to search/add in the map
+ * @param value the value to add if the key does not exist
+ * @return a pointer on the map found or NULL if not found
+ */
+map* getMapOrFill(map** m,const char *key,const char* value){
+  map* tmp=*m;
+  map* tmpMap=getMap(tmp,key);
+  if(tmpMap==NULL){
+    if(tmp!=NULL){
+      addToMap((*m),key,value);
+    }
+    else
+      (*m)=createMap(key,value);
+    tmpMap=getMap(*m,key);
+  }
+  return tmpMap;
+}
+
+/**
+ * Verify if a map is contained in another map.
+ *
+ * @param m the map to search for i
+ * @param i the map to search in m
+ * @return true if i was found in m, false in other case
+ */
+bool contains(map* m,map* i){
+  while(i!=NULL){      
+    if(strcasecmp(i->name,"value")!=0 &&
+       strcasecmp(i->name,"xlink:href")!=0 &&
+       strcasecmp(i->name,"useMapServer")!=0 &&
+       strcasecmp(i->name,"asReference")!=0){
+      map *tmp;
+      if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL && 
+	 strcasecmp(i->value,tmp->value)!=0)
+	return false;
+    }
+    i=i->next;
+  }
+  return true;
+}
+
+/**
+ * Access a specific iotype from an elements.
+ *
+ * @param e the elements to search for the name
+ * @param name the name to search in the elements e
+ * @param values the map to verify it was contained in the defaults or 
+ *  supported content of the elements e
+ * @return a pointer on the iotype found or NULL if not found
+ */
+iotype* getIoTypeFromElement(elements* e,char *name, map* values){
+  elements* cursor=e;
+  while(cursor!=NULL){
+    if(strcasecmp(cursor->name,name)==0){
+      if(contains(cursor->defaults->content,values)==true)
+	return cursor->defaults;
+      else{
+	iotype* tmp=cursor->supported;
+	while(tmp!=NULL){
+	  if(contains(tmp->content,values)==true)
+	    return tmp;	    
+	  tmp=tmp->next;
+	}
+      }
+    }
+    cursor=cursor->next;
+  }
+  return NULL;
+}
+
+/**
+ * Load binary values from a map (in) and add them to another map (out)
+ *
+ * @param out the map to add binaries values
+ * @param in the map containing the binary values to add ti out
+ * @param pos index of the binary in an array (in case of "MapArray")
+ */
+void loadMapBinary(map** out,map* in,int pos){
+  map* size=getMap(in,"size");
+  map *lout=*out;
+  if(size!=NULL && pos>0){
+    char tmp[11];
+    sprintf(tmp,"size_%d",pos);
+    size=getMap(in,tmp);
+    sprintf(tmp,"value_%d",pos);
+    map* tmpVin=getMap(in,tmp);
+    map* tmpVout=getMap(lout,tmp);
+    free(tmpVout->value);
+    tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
+    memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
+    tmpVout->value[atoi(size->value)]=0;
+  }else{
+    if(size!=NULL){
+      map* tmpVin=getMap(in,"value");
+      map* tmpVout=getMap(lout,"value");
+      free(tmpVout->value);
+      tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
+      memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
+      tmpVout->value[atoi(size->value)]=0;
+    }
+  }
+}
+  
+/**
+ * Load binary values from a map (in) and add them to another map (out).
+ * This function will take care of MapArray.
+ * @see loadMapBinary
+ *
+ * @param out the map to add binaries values
+ * @param in the map containing the binary values to add ti out
+ */
+void loadMapBinaries(map** out,map* in){
+  map* size=getMap(in,"size");
+  map* length=getMap(in,"length");
+  if(length!=NULL){
+    int len=atoi(length->value);
+    int i=0;
+    for(i=0;i<len;i++){
+      loadMapBinary(out,in,i);
+    }
+  }
+  else
+    if(size!=NULL)
+      loadMapBinary(out,in,-1);
+}
+
+/**
+ * Duplicate a Maps
+ * 
+ * @param mo the maps to clone
+ * @return the allocated maps containing a copy of the mo maps
+ */
+maps* dupMaps(maps** mo){
+  maps* _cursor=*mo;
+  maps* res=NULL;
+  if(_cursor!=NULL){
+    res=(maps*)malloc(MAPS_SIZE);
+    res->name=zStrdup(_cursor->name);
+    res->content=NULL;
+    res->next=NULL;
+    map* mc=_cursor->content;
+    if(mc!=NULL){
+      addMapToMap(&res->content,mc);
+      loadMapBinaries(&res->content,mc);
+    }
+    res->next=dupMaps(&_cursor->next);
+  }
+  return res;
+}
+
+/**
+ * Add a maps at the end of another maps.
+ *
+ * @see addMapToMap, dupMaps, getMaps
+ * @param mo the maps to add mi
+ * @param mi the maps to add to mo
+ */
+void addMapsToMaps(maps** mo,maps* mi){
+  maps* tmp=mi;
+  maps* _cursor=*mo;
+  while(tmp!=NULL){
+    if(_cursor==NULL){
+      *mo=dupMaps(&mi);
+    }
+    else{
+      while(_cursor->next!=NULL)
+	_cursor=_cursor->next;
+      maps* tmp1=getMaps(*mo,tmp->name);
+      if(tmp1==NULL)
+	_cursor->next=dupMaps(&tmp);
+      else
+	addMapToMap(&tmp1->content,tmp->content);
+      _cursor=*mo;
+    }
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Access a specific map array element
+ *
+ * @param m the map to search for the key
+ * @param key the key to search in the map
+ * @param index of the MapArray 
+ * @return a pointer on the map found or NULL if not found
+ */
+map* getMapArray(map* m,const char* key,int index){
+  char tmp[1024];
+  if(index>0)
+    sprintf(tmp,"%s_%d",key,index);
+  else
+    sprintf(tmp,"%s",key);
+#ifdef DEBUG
+  fprintf(stderr,"** KEY %s\n",tmp);
+#endif
+  map* tmpMap=getMap(m,tmp);
+#ifdef DEBUG
+  if(tmpMap!=NULL)
+    dumpMap(tmpMap);
+#endif
+  return tmpMap;
+}
+
+/**
+ * Add a key value in a MapArray for a specific index
+ *
+ * @param m the map to search for the key
+ * @param key the key to search in the map
+ * @param index the index of the MapArray 
+ * @param value the value to set in the MapArray 
+ * @return a pointer on the map found or NULL if not found
+ */
+void setMapArray(map* m,const char* key,int index,const char* value){
+  char tmp[1024];
+  if(index>0){
+    sprintf(tmp,"%s_%d",key,index);
+    map* len=getMap(m,"length");
+    if((len!=NULL && atoi(len->value)<index+1) || len==NULL){
+      char tmp0[5];
+      sprintf(tmp0,"%d",index+1);
+      addToMap(m,"length",tmp0);
+    }
+  }
+  else
+    sprintf(tmp,"%s",key);
+  map* tmpSize=getMapArray(m,"size",index);
+  if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
+#ifdef DEBUG
+    fprintf(stderr,"%s\n",tmpSize->value);
+#endif
+    map* ptr=getMapOrFill(&m,tmp,(char *)"");
+    free(ptr->value);
+    ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
+    memcpy(ptr->value,value,atoi(tmpSize->value)); 
+  }
+  else
+    addToMap(m,tmp,value);
+}
+
+/**
+ * Access the map "type"
+ *
+ * @param mt the map
+ * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
+ *  other case
+ */
+map* getMapType(map* mt){
+  map* tmap=getMap(mt,(char *)"mimeType");
+  if(tmap==NULL){
+    tmap=getMap(mt,"dataType");
+    if(tmap==NULL){
+      tmap=getMap(mt,"CRS");
+    }
+  }
+#ifdef DEBUG
+  dumpMap(tmap);
+#endif
+  return tmap;
+}
+
+/**
+ * Add a Maps containing a MapArray to a Maps
+ *
+ * @see getMapType
+ * @param mo the maps
+ * @param mi the maps
+ * @param typ the map "type"
+ * @return 
+ */
+int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
+  maps* tmp=mi;    
+  maps* _cursor=getMaps(*mo,tmp->name);
+
+  if(_cursor==NULL)
+    return -1;
+
+  map* tmpLength=getMap(_cursor->content,"length");
+  char tmpLen[10];
+  int len=1;
+  if(tmpLength!=NULL){
+    len=atoi(tmpLength->value);
+  }
+
+  char *tmpV[12]={
+    (char*)"size",
+    (char*)"value",
+    (char*)"uom",
+    (char*)"Reference",
+    (char*)"Order",
+    (char*)"cache_file",
+    (char*)"fmimeType",
+    (char*)"xlink:href",
+    typ,
+    (char*)"schema",
+    (char*)"encoding",
+    (char*)"isCached"
+  };
+  sprintf(tmpLen,"%d",len+1);
+  addToMap(_cursor->content,"length",tmpLen);
+  int i=0;
+  for(i=0;i<12;i++){
+    map* tmpVI=getMap(tmp->content,tmpV[i]);
+    if(tmpVI!=NULL){
+#ifdef DEBUG
+      fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
+#endif
+      setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
+    }
+  }
+    
+  addToMap(_cursor->content,"isArray","true");
+  return 0;
+}
+
+/**
+ * Set a key value pair to a map contained in a Maps
+ *
+ * @param m the maps
+ * @param key the maps name
+ * @param subkey the map name included in the maps corresponding to key
+ * @param value the corresponding value to add in the map
+ */
+void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
+  maps* _tmpm=getMaps(m,key);
+  if(_tmpm!=NULL){
+    map* _ztmpm=getMap(_tmpm->content,subkey);
+    if(_ztmpm!=NULL){
+      if(_ztmpm->value!=NULL)
+	free(_ztmpm->value);
+      _ztmpm->value=zStrdup(value);
+    }else{
+      maps *tmp=(maps*)malloc(MAPS_SIZE);
+      tmp->name=zStrdup(key);
+      tmp->content=createMap(subkey,value);
+      tmp->next=NULL;
+      addMapsToMaps(&_tmpm,tmp);
+      freeMaps(&tmp);
+      free(tmp);
+    }
+  }else{
+    maps *tmp=(maps*)malloc(MAPS_SIZE);
+    tmp->name=zStrdup(key);
+    tmp->content=createMap(subkey,value);
+    tmp->next=NULL;
+    addMapsToMaps(&m,tmp);
+    freeMaps(&tmp);
+    free(tmp);
+  }
+}
+
+/**
+ * Dump an elements on stderr
+ *
+ * @param e the elements to dump
+ */
+void dumpElements(elements* e){
+  elements* tmp=e;
+  while(tmp!=NULL){
+    fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
+    fprintf(stderr," > CONTENT [%s]\n",tmp->name);
+    dumpMap(tmp->content);
+    fprintf(stderr," > METADATA [%s]\n",tmp->name);
+    dumpMap(tmp->metadata);
+    fprintf(stderr," > FORMAT [%s]\n",tmp->format);
+    iotype* tmpio=tmp->defaults;
+    int ioc=0;
+    while(tmpio!=NULL){
+      fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
+      dumpMap(tmpio->content);
+      tmpio=tmpio->next;
+      ioc++;
+    }
+    tmpio=tmp->supported;
+    ioc=0;
+    while(tmpio!=NULL){
+      fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
+      dumpMap(tmpio->content);
+      tmpio=tmpio->next;
+      ioc++;
+    }
+    fprintf(stderr,"------------------\n");
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Dump an elements on stderr using the YAML syntaxe
+ *
+ * @param e the elements to dump
+ */
+void dumpElementsAsYAML(elements* e){
+  elements* tmp=e;
+  int i;
+  while(tmp!=NULL){
+    for(i=0;i<2;i++)
+      fprintf(stderr," ");
+    fprintf(stderr,"%s:\n",tmp->name);
+    map* mcurs=tmp->content;
+    while(mcurs!=NULL){
+      for(i=0;i<4;i++)
+	fprintf(stderr," ");
+      _dumpMap(mcurs);
+      mcurs=mcurs->next;
+    }
+    mcurs=tmp->metadata;
+    if(mcurs!=NULL){
+      for(i=0;i<4;i++)
+	fprintf(stderr," ");
+      fprintf(stderr,"MetaData:\n");
+      while(mcurs!=NULL){
+	for(i=0;i<6;i++)
+	  fprintf(stderr," ");
+	_dumpMap(mcurs);
+	mcurs=mcurs->next;
+      }
+    }
+    for(i=0;i<4;i++)
+      fprintf(stderr," ");
+    fprintf(stderr,"%s:\n",tmp->format);
+    iotype* tmpio=tmp->defaults;
+    int ioc=0;
+    while(tmpio!=NULL){
+      for(i=0;i<6;i++)
+	fprintf(stderr," ");
+      fprintf(stderr,"default:\n");
+      mcurs=tmpio->content;
+      while(mcurs!=NULL){
+	for(i=0;i<8;i++)
+	  fprintf(stderr," ");
+	if(strcasecmp(mcurs->name,"range")==0){
+	  fprintf(stderr,"range: \"%s\"\n",mcurs->value);
+	}else
+	  _dumpMap(mcurs);
+	mcurs=mcurs->next;
+      }
+      tmpio=tmpio->next;
+      ioc++;
+    }
+    tmpio=tmp->supported;
+    ioc=0;
+    while(tmpio!=NULL){
+      for(i=0;i<6;i++)
+	fprintf(stderr," ");
+      fprintf(stderr,"supported:\n");
+      mcurs=tmpio->content;
+      while(mcurs!=NULL){
+	for(i=0;i<8;i++)
+	  fprintf(stderr," ");
+	if(strcasecmp(mcurs->name,"range")==0){
+	  fprintf(stderr,"range: \"%s\"\n",mcurs->value);
+	}else
+	  _dumpMap(mcurs);
+	mcurs=mcurs->next;
+      }
+      tmpio=tmpio->next;
+      ioc++;
+    }
+    tmp=tmp->next;
+  }
+}
+
+/**
+ * Duplicate an elements
+ * 
+ * @param e the elements to clone
+ * @return the allocated elements containing a copy of the elements e
+ */
+elements* dupElements(elements* e){
+  elements* cursor=e;
+  elements* tmp=NULL;
+  if(cursor!=NULL){
+#ifdef DEBUG
+    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
+    dumpElements(e);
+    fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
+#endif
+    tmp=(elements*)malloc(ELEMENTS_SIZE);
+    tmp->name=zStrdup(e->name);
+    tmp->content=NULL;
+    addMapToMap(&tmp->content,e->content);
+    tmp->metadata=NULL;
+    addMapToMap(&tmp->metadata,e->metadata);
+    if(e->format!=NULL)
+      tmp->format=zStrdup(e->format);
+    else
+      tmp->format=NULL;
+    if(e->defaults!=NULL){
+      tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
+      tmp->defaults->content=NULL;
+      addMapToMap(&tmp->defaults->content,e->defaults->content);
+      tmp->defaults->next=NULL;
+#ifdef DEBUG
+      fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
+      dumpMap(tmp->defaults->content);
+#endif
+    }else
+      tmp->defaults=NULL;
+    if(e->supported!=NULL){
+      tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
+      tmp->supported->content=NULL;
+      addMapToMap(&tmp->supported->content,e->supported->content);
+      tmp->supported->next=NULL;
+      iotype *tmp2=e->supported->next;
+      while(tmp2!=NULL){
+	addMapToIoType(&tmp->supported,tmp2->content);
+#ifdef DEBUG
+	fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
+	dumpMap(tmp->defaults->content);
+#endif
+	tmp2=tmp2->next;
+      }
+    }
+    else
+      tmp->supported=NULL;
+    tmp->next=dupElements(cursor->next);
+  }
+  return tmp;
+}
+
+/**
+ * Add an elements to another elements.
+ *
+ * @see dupElements
+ * @param m the elements to add the e
+ * @param e the elements to be added to m
+ */
+void addToElements(elements** m,elements* e){
+  elements* tmp=e;
+  if(*m==NULL){
+    *m=dupElements(tmp);
+  }else{
+    addToElements(&(*m)->next,tmp);
+  }
+}
+  
+/**
+ * Dump a service on stderr
+ *
+ * @param s the service to dump
+ */
+void dumpService(service* s){
+  if(s==NULL)
+    return;
+  fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
+  if(s->content!=NULL){
+    fprintf(stderr,"CONTENT MAP\n");
+    dumpMap(s->content);
+    fprintf(stderr,"CONTENT METADATA\n");
+    dumpMap(s->metadata);
+  }
+  if(s->inputs!=NULL){
+    fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
+    dumpElements(s->inputs);
+  }
+  if(s->outputs!=NULL){
+    fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
+    dumpElements(s->outputs);
+  }
+  fprintf(stderr,"++++++++++++++++++\n");
+}
+
+/**
+ * Dump a service on stderr using the YAML syntaxe
+ *
+ * @param s the service to dump
+ */
+void dumpServiceAsYAML(service* s){
+  int i;
+  fprintf(stderr,"# %s\n\n",s->name);
+  if(s->content!=NULL){
+    map* mcurs=s->content;
+    dumpMap(mcurs);
+    mcurs=s->metadata;
+    if(mcurs!=NULL){
+      fprintf(stderr,"MetaData:\n");
+      while(mcurs!=NULL){
+	for(i=0;i<2;i++)
+	  fprintf(stderr," ");
+	_dumpMap(mcurs);
+	mcurs=mcurs->next;
+      }
+    }
+  }
+  if(s->inputs!=NULL){
+    fprintf(stderr,"\ninputs:\n");
+    dumpElementsAsYAML(s->inputs);
+  }
+  if(s->outputs!=NULL){
+    fprintf(stderr,"\noutputs:\n");
+    dumpElementsAsYAML(s->outputs);
+  }
+}
+
+/**
+ * Duplicate a service
+ * 
+ * @param s the service to clone
+ * @return the allocated service containing a copy of the serfvice s
+ */
+service* dupService(service* s){
+  service *res=(service*)malloc(SERVICE_SIZE);
+  res->name=zStrdup(s->name);
+  res->content=NULL;
+  addMapToMap(&res->content,s->content);
+  res->metadata=NULL;
+  addMapToMap(&res->metadata,s->metadata);
+  res->inputs=dupElements(s->inputs);
+  res->outputs=dupElements(s->outputs);
+  return res;
+}
+
+/**
+ * Print the registry on stderr.
+ * 
+ * @param r the registry
+ */
+void dumpRegistry(registry* r){
+  registry* p=r;
+  while(p!=NULL){
+    fprintf(stderr,"%s \n",p->name);
+    services* s=p->content;
+    s=p->content;
+    while(s!=NULL){
+      dumpService(s->content);
+      s=s->next;
+    }
+    p=p->next;
+  }
+}
+
+/**
+ * Add a service to the registry
+ *
+ * @param reg the resgitry to add the service
+ * @param name the registry name to update
+ * @param content the service to add
+ */
+bool addServiceToRegistry(registry** reg,char* name,service* content){
+  registry *l=*reg;
+  int isInitial=-1;
+  if(l==NULL){
+    l=(registry*)malloc(REGISTRY_SIZE);
+    isInitial=1;
+  }
+  if(l!=NULL){
+    int hasLevel=-1;
+    while(isInitial<0 && l!=NULL){
+      if(l->name!=NULL && strcasecmp(name,l->name)==0){
+	hasLevel=1;
+	break;
+      }
+      l=l->next;
+    }
+    if(hasLevel<0){
+      if(isInitial<0)
+	l=(registry*)malloc(REGISTRY_SIZE);
+      l->name=zStrdup(name);
+      l->content=NULL;
+      l->next=NULL;
+    }
+    if(l->content==NULL){
+      l->content=(services*)malloc(SERVICES_SIZE);
+      l->content->content=dupService(content);
+      l->content->next=NULL;
+    }
+    else{
+      services* s=l->content;
+      while(s->next!=NULL)
+	s=s->next;
+      s->next=(services*)malloc(SERVICES_SIZE);
+      s->next->content=dupService(content);
+      s->next->next=NULL;
+    }
+    l->next=NULL;
+    if(isInitial>0)
+      *reg=l;
+    else{
+      registry *r=*reg;
+      while(r->next!=NULL)
+	r=r->next;
+      r->next=l;
+      r->next->next=NULL;
+    }
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * Free memory allocated for the registry
+ *
+ * @param r the registry
+ */
+void freeRegistry(registry** r){
+  registry* lr=*r;
+  while(lr!=NULL){
+    services* s=lr->content;
+    free(lr->name);
+    while(s!=NULL){
+      service* s1=s->content;
+      s=s->next;
+      if(s1!=NULL){
+	freeService(&s1);
+	free(s1);
+	s1=NULL;
+      }
+    }
+    lr=lr->next;
+  }    
+}
+
+/**
+ * Access a service in the registry
+ *
+ * @param r the registry
+ * @param level the regitry to search ("concept", "generic" or "implementation")
+ * @param sname the service name
+ * @return the service pointer if a corresponding service was found or NULL
+ */
+service* getServiceFromRegistry(registry* r,char  *level,char* sname){
+  registry *lr=r;
+  while(lr!=NULL){
+    if(strcasecmp(lr->name,level)==0){
+      services* s=lr->content;
+      while(s!=NULL){
+	if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
+	  return s->content;
+	s=s->next;
+      }
+      break;
+    }
+    lr=lr->next;
+  }
+  return NULL;
+}
+
+/**
+ * Apply inheritance to an out map from a reference in map
+ *
+ * @param out the map to update
+ * @param in the reference map (containing inherited properties)
+ */
+void inheritMap(map** out,map* in){
+  map* content=in;
+  while(content!=NULL && *out!=NULL){
+    map* cmap=getMap(*out,content->name);
+    if(cmap==NULL)
+      addToMap(*out,content->name,content->value);
+    content=content->next;
+  }
+}
+
+/**
+ * Apply inheritance to an out iotype from a reference in iotype
+ * 
+ * @param out the iotype to update
+ * @param in the reference iotype (containing inherited properties)
+ */
+void inheritIOType(iotype** out,iotype* in){
+  iotype* io=in;
+  iotype* oio=*out;
+  if(io!=NULL){
+    if(*out==NULL){
+      *out=(iotype*)malloc(IOTYPE_SIZE);
+      (*out)->content=NULL;
+      addMapToMap(&(*out)->content,io->content);
+      (*out)->next=NULL;
+      oio=*out;
+      inheritIOType(&oio->next,io->next);
+    }else{
+      inheritIOType(&oio->next,io->next);
+    }
+  }
+}
+
+/**
+ * Apply inheritance to an out elements from a reference in elements
+ * 
+ * @param out the elements to update
+ * @param in the reference elements (containing inherited properties)
+ */
+void inheritElements(elements** out,elements* in){
+  elements* content=in;
+  while(content!=NULL && *out!=NULL){
+    elements* cmap=getElements(*out,content->name);
+    if(cmap==NULL)
+      addToElements(out,content);
+    else{
+      inheritMap(&cmap->content,content->content);
+      inheritMap(&cmap->metadata,content->metadata);
+      if(cmap->format==NULL && content->format!=NULL)
+	cmap->format=zStrdup(content->format);
+      inheritIOType(&cmap->defaults,content->defaults);
+      if(cmap->supported==NULL)
+	inheritIOType(&cmap->supported,content->supported);
+      else{
+	iotype* p=content->supported;
+	while(p!=NULL){
+	  addMapToIoType(&cmap->supported,p->content);
+	  p=p->next;
+	}
+      }
+    }
+    content=content->next;
+  }
+}
+
+/**
+ * Apply inheritance to a service based on a registry
+ * 
+ * @param r the registry storing profiles hierarchy
+ * @param s the service to update depending on its inheritance
+ */
+void inheritance(registry *r,service** s){
+  if(r==NULL)
+    return;
+  service* ls=*s;
+  if(ls->content==NULL)
+    return;
+  map* profile=getMap(ls->content,"extend");
+  map* level=getMap(ls->content,"level");
+  if(profile!=NULL&&level!=NULL){
+    service* s1;
+    if(strncasecmp(level->value,"profile",7)==0)
+      s1=getServiceFromRegistry(r,(char*)"generic",profile->value);
+    else
+      s1=getServiceFromRegistry(r,level->value,profile->value);
+      
+    inheritMap(&ls->content,s1->content);
+    inheritMap(&ls->metadata,s1->metadata);
+    if(ls->inputs==NULL && s1->inputs!=NULL){
+      ls->inputs=dupElements(s1->inputs);
+    }else{
+      inheritElements(&ls->inputs,s1->inputs);
+    }
+    if(ls->outputs==NULL && s1->outputs!=NULL){
+      ls->outputs=dupElements(s1->outputs);
+    }else
+      inheritElements(&ls->outputs,s1->outputs);
+  }
+}
+
+/**
+ * Convert a maps to a char*** (only used for Fortran support)
+ *
+ * @param m the maps to convert
+ * @param c the resulting array
+ */
+void mapsToCharXXX(maps* m,char*** c){
+  maps* tm=m;
+  int i=0;
+  int j=0;
+  char tmp[10][30][1024];
+  memset(tmp,0,1024*10*10);
+  while(tm!=NULL){
+    if(i>=10)
+      break;
+    strcpy(tmp[i][j],"name");
+    j++;
+    strcpy(tmp[i][j],tm->name);
+    j++;
+    map* tc=tm->content;
+    while(tc!=NULL){
+      if(j>=30)
+	break;
+      strcpy(tmp[i][j],tc->name);
+      j++;
+      strcpy(tmp[i][j],tc->value);
+      j++;
+      tc=tc->next;
+    }
+    tm=tm->next;
+    j=0;
+    i++;
+  }
+  memcpy(c,tmp,10*10*1024);
+}
+
+/**
+ * Convert a char*** to a maps (only used for Fortran support)
+ *
+ * @param c the array to convert
+ * @param m the resulting maps
+ */
+void charxxxToMaps(char*** c,maps**m){
+  maps* trorf=*m;
+  int i,j;
+  char tmp[10][30][1024];
+  memcpy(tmp,c,10*30*1024);
+  for(i=0;i<10;i++){
+    if(strlen(tmp[i][1])==0)
+      break;
+    trorf->name=tmp[i][1];
+    trorf->content=NULL;
+    trorf->next=NULL;
+    for(j=2;j<29;j+=2){
+      if(strlen(tmp[i][j+1])==0)
+	break;
+      if(trorf->content==NULL)
+	trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
+      else
+	addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
+    }
+    trorf=trorf->next;
+  }
+  m=&trorf;
+}
+
+#ifdef WIN32
+char* getMapsAsKVP(maps* m,int length,int type){
+  char *dataInputsKVP=(char*) malloc(length*sizeof(char));
+  char *dataInputsKVPi=NULL;
+  maps* curs=m;
+  int i=0;
+  while(curs!=NULL){
+    map *inRequest=getMap(curs->content,"inRequest");
+    map *hasLength=getMap(curs->content,"length");
+    if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
+       inRequest==NULL){
+      if(i==0)
+	if(type==0){
+	  sprintf(dataInputsKVP,"%s=",curs->name);
+	  if(hasLength!=NULL){
+	    dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
+	    sprintf(dataInputsKVPi,"%s=",curs->name);
+	  }
+	}
+	else
+	  sprintf(dataInputsKVP,"%s",curs->name);
+      else{
+	char *temp=zStrdup(dataInputsKVP);
+	if(type==0)
+	  sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
+	else
+	  sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
+      }
+      map* icurs=curs->content;
+      if(type==0){
+	char *temp=zStrdup(dataInputsKVP);
+	if(getMap(curs->content,"xlink:href")!=NULL)
+	  sprintf(dataInputsKVP,"%sReference",temp);
+	else{
+	  if(hasLength!=NULL){
+	    int j;
+	    for(j=0;j<atoi(hasLength->value);j++){
+	      map* tmp0=getMapArray(curs->content,"value",j);
+	      if(j==0)
+		free(temp);
+	      temp=zStrdup(dataInputsKVP);
+	      if(j==0)
+		sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
+	      else
+		sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
+	    }
+	  }
+	  else
+	    sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
+	}
+	free(temp);
+      }
+      while(icurs!=NULL){
+	if(strncasecmp(icurs->name,"value",5)!=0 &&
+	   strncasecmp(icurs->name,"mimeType_",9)!=0 &&
+	   strncasecmp(icurs->name,"dataType_",9)!=0 &&
+	   strncasecmp(icurs->name,"size",4)!=0 &&
+	   strncasecmp(icurs->name,"length",4)!=0 &&
+	   strncasecmp(icurs->name,"isArray",7)!=0 &&
+	   strcasecmp(icurs->name,"Reference")!=0 &&
+	   strcasecmp(icurs->name,"minOccurs")!=0 &&
+	   strcasecmp(icurs->name,"maxOccurs")!=0 &&
+	   strncasecmp(icurs->name,"fmimeType",9)!=0 &&
+	   strcasecmp(icurs->name,"inRequest")!=0){
+	  char *itemp=zStrdup(dataInputsKVP);
+	  if(strcasecmp(icurs->name,"xlink:href")!=0)
+	    sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
+	  else
+	    sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
+	  free(itemp);
+	}
+	icurs=icurs->next;
+      }
+    }
+    curs=curs->next;
+    i++;
+  }
+  return dataInputsKVP;
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service.h	(revision 672)
@@ -0,0 +1,328 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_H
+#define ZOO_SERVICE_H 1
+
+#pragma once
+
+#ifdef WIN32
+#ifndef USE_MS
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+#ifndef snprintf
+#define snprintf sprintf_s
+#endif
+#define zStrdup _strdup
+#define zMkdir _mkdir
+#define zOpen _open
+#define zWrite _write
+#define zSleep Sleep
+#include <sys/timeb.h>
+struct ztimeval {
+  long tv_sec; /* seconds */
+  long tv_usec; /* and microseconds */
+};
+static int zGettimeofday(struct ztimeval* tp, void* tzp)
+{
+  if (tp == 0) {
+    return -1;
+  }
+  
+  struct _timeb theTime;
+  _ftime(&theTime);
+  tp->tv_sec = theTime.time;
+  tp->tv_usec = theTime.millitm * 1000;
+  
+  return 0; // The gettimeofday() function shall return 0 on success
+}
+#else
+/**
+ * The crossplatform strdup alias
+ */
+#define zStrdup strdup
+/**
+ * The crossplatform mkdir alias
+ */
+#define zMkdir mkdir
+/**
+ * The crossplatform open alias
+ */
+#define zOpen open
+/**
+ * The crossplatform write alias
+ */
+#define zWrite write
+/**
+ * The crossplatform sleep alias
+ */
+#define zSleep sleep
+/**
+ * The crossplatform gettimeofday alias
+ */
+#define zGettimeofday gettimeofday
+/**
+ * The crossplatform timeval alias
+ */
+#define ztimeval timeval
+#endif 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+#ifdef USE_MS
+#include <mapserver.h>
+#endif
+#endif
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef WIN32
+#include <ctype.h>
+#ifndef bool
+#define bool int
+#endif
+#ifndef true
+  /**
+   * Local true definition
+   */
+#define true 1
+  /**
+   * Local false definition
+   */
+#define false 0
+#endif
+#endif
+
+/**
+ * The global accepted status for a service
+ */
+#define SERVICE_ACCEPTED 0
+/**
+ * The global started status for a service
+ */
+#define SERVICE_STARTED 1
+/**
+ * The global paused status for a service
+ */
+#define SERVICE_PAUSED 2
+/**
+ * The global succeeded status for a service
+ */
+#define SERVICE_SUCCEEDED 3
+/**
+ * The global failed status for a service
+ */
+#define SERVICE_FAILED 4
+
+/**
+ * The memory size to create an elements
+ */
+#define ELEMENTS_SIZE (sizeof(char*)+(((2*sizeof(char*))+sizeof(maps*))*2)+sizeof(char*)+(((2*sizeof(char*))+sizeof(iotype*))*2)+(2*sizeof(elements*)))
+/**
+ * The memory size to create a map
+ */
+#define MAP_SIZE (2*sizeof(char*))+sizeof(NULL)
+/**
+ * The memory size to create an iotype
+ */
+#define IOTYPE_SIZE MAP_SIZE+sizeof(NULL)
+/**
+ * The memory size to create a maps
+ */
+#define MAPS_SIZE (2*sizeof(char*))+sizeof(map*)+MAP_SIZE
+/**
+ * The memory size to create a service
+ */
+#define SERVICE_SIZE (ELEMENTS_SIZE*2)+(MAP_SIZE*2)+sizeof(char*)
+/**
+ * The memory size to create a services
+ */
+#define SERVICES_SIZE SERVICE_SIZE+sizeof(services*)
+/**
+ * The memory size to create a registry
+ */
+#define REGISTRY_SIZE SERVICES_SIZE+sizeof(char*)
+
+#define SHMSZ     27
+
+#include "version.h" 
+
+#ifdef DEBUG_STACK
+  void debugStack(const char* file,const int line){
+    int stack;
+    fprintf(stderr,"stack %p (%s: %d) \n",&stack,file,line);
+  }
+#endif
+
+  /**
+   * KVP linked list
+   */
+  typedef struct map{
+    char* name; //!< the key
+    char* value; //!< the value
+    struct map* next; //!< the pointer to the next map if any or NULL
+  } map;
+
+#ifdef WIN32
+#define NULLMAP ((map*) 0)
+#else
+#define NULLMAP NULL
+#endif
+
+  /**
+   * linked list of map pointer
+   *
+   * Small object to store WPS KVP set.
+   */
+  typedef struct maps{
+    char* name; //!< the maps name
+    struct map* content; //!< the content map
+    struct maps* next; //!< the pointer to the next maps if any or NULL
+  } maps;
+  
+  /**
+   * Not named linked list
+   *
+   * Used to store informations about formats, such as mimeType, encoding ... 
+   */
+  typedef struct iotype{
+    struct map* content; //!< the content map
+    struct iotype* next; //!< the pointer to the next iotype if any or NULL
+  } iotype;
+
+  /**
+   * Metadata information about input or output.
+   *
+   * The elements are used to store metadata informations defined in the ZCFG.
+   */
+  typedef struct elements{
+    char* name; //!< the name
+    struct map* content; //!< the content map
+    struct map* metadata; //!< the metadata map
+    char* format; //!< the format: LiteralData or ComplexData or BoundingBoxData
+    struct iotype* defaults; //!< the default iotype 
+    struct iotype* supported; //!< the supported iotype 
+    struct elements* child; //!< the pointer to the children element if any (or NULL)
+    struct elements* next; //!< the pointer to the next element if any (or NULL)
+  } elements;
+
+  /**
+   * Metadata informations about a full Service.
+   */
+  typedef struct service{
+    char* name; //!< the name
+    struct map* content; //!< the content map
+    struct map* metadata; //!< the metadata map
+    struct elements* inputs; //!< the inputs elements
+    struct elements* outputs; //!< the outputs elements
+  } service;
+
+  /**
+   * Services chained list.
+   */
+  typedef struct services{
+    struct service* content; //!< the content service pointer
+    struct services* next; //!< the pointer to the next services*
+  } services;
+
+  /**
+   * Profile registry.
+   */
+  typedef struct registry{
+    char *name; //!< the name
+    struct services* content; //!< the content services pointer
+    struct registry* next; //!< the next registry pointer
+  } registry;
+
+
+  void _dumpMap(map*);
+  void dumpMap(map*);
+  void dumpMapToFile(map*,FILE*);
+  void dumpMaps(maps* m);
+  void dumpMapsToFile(maps*,char*);
+  map* createMap(const char*,const char*);
+  int count(map*);
+  bool hasKey(map*,const char*);
+  maps* getMaps(maps*,const char*);
+  map* getMap(map*,const char*);
+  map* getLastMap(map*);
+  map* getMapFromMaps(maps*,const char*,const char*);
+  void freeMap(map**);
+  void freeMaps(maps** mo);
+  
+
+  bool hasElement(elements*,const char*);
+  elements* getElements(elements*,char*);
+  void freeIOType(iotype**);
+  void freeElements(elements**);
+  void freeService(service**);
+  void addToMap(map*,const char*,const char*);
+  void addIntToMap(map*,const char*,const int);
+  void addToMapWithSize(map*,const char*,const char*,int);
+  void addMapToMap(map**,map*);
+  void addMapToIoType(iotype**,map*);
+  map* getMapOrFill(map**,const char*,const char*);
+  bool contains(map*,map*);
+  iotype* getIoTypeFromElement(elements*,char*, map*);
+  void loadMapBinary(map**,map*,int);
+  void loadMapBinaries(map**,map*);
+  maps* dupMaps(maps**);
+  void addMapsToMaps(maps**,maps*);
+  map* getMapArray(map*,const char*,int);
+  void setMapArray(map*,const char*,int,const char*);
+  map* getMapType(map*);
+  int addMapsArrayToMaps(maps**,maps*,char*);
+  void setMapInMaps(maps*,const char*,const char*,const char*);
+  void dumpElements(elements*);
+  void dumpElementsAsYAML(elements*);
+  elements* dupElements(elements*);
+  void addToElements(elements**,elements*);
+  void dumpService(service*);
+  void dumpServiceAsYAML(service*);
+  service* dupService(service*);
+  void dumpRegistry(registry*);
+  bool addServiceToRegistry(registry**,char*,service*);
+  void freeRegistry(registry**);
+  service* getServiceFromRegistry(registry*,char*,char*);
+  void inheritMap(map**,map*);
+  void inheritIOType(iotype**,iotype*);
+  void inheritElements(elements**,elements*);
+  void inheritance(registry*,service**);
+  void mapsToCharXXX(maps*,char***);
+  void charxxxToMaps(char***,maps**);
+#ifdef WIN32
+  extern char *url_encode(char *);
+  char* getMapsAsKVP(maps*,int,int);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.l
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.l	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.l	(revision 672)
@@ -0,0 +1,102 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 209-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+%option noyywrap
+%option yylineno
+
+
+%{
+
+#include <string.h>
+#include "service_conf.tab.h"
+
+char *lmsg=NULL;
+
+%}
+
+S		[ \t\r\n]+
+
+CharRef		"&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";"
+
+egalevolue		{S}?"="{S}?
+
+Name		([_:]|[\x41-\x5A]|[\x61-\x7A]|[\xC0-\xD6]|[\xD8-\xF6]|[\xF8-\xFF])(([\x41-\x5A]|[\x61-\x7A]|[\xC0-\xD6]|[\xD8-\xF6]|[\xF8-\xFF])|[0-9.\-_:])*
+
+chardata	[^<]*
+
+attname	[a-zA-Z0-9._\-]+
+attvalue1      [\x80-\xbf\xc2-\xdf\xe0-\xef\xf0-\xf4="#°²θé\^\*\+\,\;;?!~`Ãº@a-zA-Z0-9%_\-:\:.:" "\"\'/\\\(\)\t\|\$\&>\[\]]+
+
+attvalue		\"[^"]*\"|\'[^']*\'\(\)
+
+whitespace                      [\t]{0,}|[ ]{0,}
+whitesp                      [\t]|[ ]
+newline                 [\r\n]|[\n]
+newlines                 [\r\n]{1,}|[\n]{1,}
+
+
+%x DANSBALISE HORSBALISE PAIRSTART
+
+
+
+
+%%
+
+"\n" { }
+
+{newline}+{whitesp}*			{ return NEWLINE; }
+
+<INITIAL,HORSBALISE>"["{attname}"]"             {  srlval.chaine=yytext;return ANID; }
+
+<INITIAL,HORSBALISE>{attname}             {  srlval.chaine=yytext; return SPAIR; }
+
+<PAIRSTART,HORSBALISE>{attvalue1}             { srlval.chaine=yytext;/*BEGIN(INITIAL);*/ return EPAIR;}
+
+<PAIRSTART,INITIAL,HORSBALISE>{whitesp}*"="{whitesp}*             {  BEGIN(PAIRSTART);}
+
+<PAIRSTART,INITIAL,HORSBALISE>{newline}+{whitesp}*             { BEGIN(INITIAL);  return NEWLINE;}
+
+<DANSBALISE,INITIAL,HORSBALISE>{S}   {  }
+
+<INITIAL,HORSBALISE>{newline}*"<"		    { BEGIN(DANSBALISE); return INFCAR;}
+
+
+<DANSBALISE>">"			{ BEGIN(HORSBALISE);return SUPCAR;}
+
+
+<DANSBALISE>"/"		{return SLASH;}
+
+
+<DANSBALISE>{egalevolue}			{return Eq;}
+
+
+<DANSBALISE>{Name}{newline}*			{memmove(srlval.chaine,yytext,(strlen(yytext)+1)*sizeof(char));return ID;}
+
+
+<DANSBALISE>{attvalue}		{return ATTVALUE;}
+
+
+<INITIAL,DANSBALISE,HORSBALISE>.|\n	{lmsg=(char*)malloc(1024*sizeof(char));sprintf(lmsg,"error: line %d: character not allowed '%s'",srlineno,yytext);fprintf(stderr,"%s \n",lmsg);srlval.chaine=lmsg;fprintf(stderr,"%s \n",lmsg);return -1;}
+
+%%
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.y
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.y	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_conf.y	(revision 672)
@@ -0,0 +1,873 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 209-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+%{
+
+#include <string>
+#include <stdio.h>
+#include <ctype.h>
+#include <service.h>
+
+static int tmp_count=1;
+static int defaultsc=0;
+static bool wait_maincontent=true;
+static bool wait_mainmetadata=false;
+static bool wait_metadata=false;
+static bool wait_inputs=false;
+static bool wait_defaults=false;
+static bool wait_supporteds=false;
+static bool wait_outputs=false;
+static bool wait_data=false;
+static service* my_service=NULL;
+static map* current_content=NULL;
+static elements* current_element=NULL;
+static char* curr_key;
+static int debug=0;
+static int data=-1;
+static int previous_data=0;
+static int current_data=0;
+// namespace
+using namespace std;
+
+// srerror
+void srerror(const char *s);
+
+// usage ()
+void usage(void) ;
+
+// srdebug
+extern int srdebug;
+
+extern char srtext[];
+
+// srlineno
+extern int srlineno;
+
+// srin
+extern FILE* srin;
+
+// srlex
+extern int srlex(void);
+extern int srlex_destroy(void);
+
+%}
+
+
+
+%union 
+{char * s;char* chaine;char* key;char* val;}
+
+// jetons //
+%token <s> ID
+%token <s> CHAINE
+
+%token INFCAR SUPCAR 
+
+/* / = a1  texte "texte" */
+%token SLASH Eq CHARDATA ATTVALUE PAIR SPAIR EPAIR ANID
+%type <chaine> PAIR
+%type <chaine> EPAIR
+%type <chaine> SPAIR
+
+/* <!-- xxx -> <? xxx yyy ?> */
+%token PI PIERROR /** COMMENT **/
+
+/* <!-- xxx -> <? xxx yyy ?> */
+%token ERREURGENERALE CDATA WHITESPACE NEWLINE
+%type <s> STag
+%type <s> ETag
+%type <s> ANID
+
+// % start
+
+%%
+// document 
+// regle 1
+// on est a la racine du fichier xml
+document
+ : miscetoile element miscetoile {}
+ | contentetoile processid contentetoile document {}
+ ;
+
+miscetoile
+ : miscetoile PIERROR {  srerror("processing instruction begining with <?xml ?> impossible\n");}
+ | miscetoile PI {}
+ | {}
+ ;
+// element
+// regle 39
+// OUVRANTE CONTENU FERMANTE obligatoirement
+// ou neutre
+// on ne peut pas avoir Epsilon
+// un fichier xml ne peut pas etre vide ou seulement avec un prolog
+element
+ : STag contentetoile ETag	
+{
+}
+
+// pour neutre
+// on a rien a faire, meme pas renvoyer l identificateur de balise
+// vu qu'il n y a pas de comparaison d'identificateurs avec un balise jumelle .
+ | EmptyElemTag          {}
+ ;
+
+// STag
+// regle 40
+// BALISE OUVRANTE
+// on est obligé de faire appel a infcar et supcar
+// pour acceder aux start conditions DANSBALISE et INITIAL
+STag
+: INFCAR ID Attributeetoile SUPCAR
+{
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"STag (%s %d) %s %d %d \n",__FILE__,__LINE__,$2,current_data,previous_data);
+  fflush(stderr);
+  dumpMap(current_content);
+#endif
+  if(my_service->content==NULL){
+#ifdef DEBUG_SERVICE_CONF
+    fprintf(stderr,"NO CONTENT\n");
+#endif
+    addMapToMap(&my_service->content,current_content);
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+    my_service->metadata=NULL;
+    wait_maincontent=false;
+  }
+  if(strncasecmp($2,"DataInputs",10)==0){
+    if(current_element==NULL){
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"(DATAINPUTS - %d) FREE current_element\n",__LINE__);
+#endif
+      freeElements(&current_element);
+      free(current_element);
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"(DATAINPUTS - %d) ALLOCATE current_element\n",__LINE__);
+#endif
+      current_element=NULL;
+      current_element=(elements*)malloc(ELEMENTS_SIZE);
+      current_element->name=NULL;
+      current_element->content=NULL;
+      current_element->metadata=NULL;
+      current_element->format=NULL;
+      current_element->defaults=NULL;
+      current_element->supported=NULL;
+      current_element->child=NULL;
+      current_element->next=NULL;
+    }
+    wait_inputs=true;
+    current_data=1;
+    previous_data=1;
+  }
+  else
+    if(strncasecmp($2,"DataOutputs",11)==0){
+      if(wait_inputs==true){
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"(DATAOUTPUTS %d) DUP INPUTS current_element\n",__LINE__);
+	fprintf(stderr,"CURRENT_ELEMENT\n");
+	dumpElements(current_element);
+	fprintf(stderr,"SERVICE INPUTS\n");
+	dumpElements(my_service->inputs);
+	dumpService(my_service);
+#endif	
+	if(my_service->inputs==NULL && current_element!=NULL && current_element->name!=NULL){
+	  my_service->inputs=dupElements(current_element);
+	  my_service->inputs->next=NULL;
+	  freeElements(&current_element);
+	}
+	else if(current_element!=NULL && current_element->name!=NULL){
+	  addToElements(&my_service->inputs,current_element);
+	  freeElements(&current_element);
+	}
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"CURRENT_ELEMENT\n");
+	dumpElements(current_element);
+	fprintf(stderr,"SERVICE INPUTS\n");
+	dumpElements(my_service->inputs);
+	fprintf(stderr,"(DATAOUTPUTS) FREE current_element\n");
+#endif
+	free(current_element);
+	current_element=NULL;
+	wait_inputs=false;
+      }
+      if(current_element==NULL){
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"(DATAOUTPUTS - %d) ALLOCATE current_element (%s)\n",__LINE__,$2);
+	fflush(stderr);
+#endif
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=NULL;
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->child=NULL;
+	current_element->next=NULL;
+      }
+      wait_outputs=1;
+      current_data=2;
+      previous_data=2;
+    }
+    else
+      if(strncasecmp($2,"MetaData",8)==0){
+	previous_data=current_data;
+	current_data=3;
+	if(current_element!=NULL){
+#ifdef DEBUG_SERVICE_CONF
+	  fprintf(stderr,"add current_content to current_element->content\n");
+	  fprintf(stderr,"LINE %d",__LINE__);
+#endif
+	  addMapToMap(&current_element->content,current_content);
+	  freeMap(&current_content);
+	  free(current_content);
+	  if(previous_data==1 || previous_data==2)
+	    wait_metadata=true;
+	  else
+	    wait_mainmetadata=true;
+	}
+	else{
+	  if(previous_data==1 || previous_data==2)
+	    wait_metadata=true;
+	  else
+	    wait_mainmetadata=true;
+	}
+	current_content=NULL;
+      }
+      else
+	if(strncasecmp($2,"ComplexData",11)==0 || strncasecmp($2,"LiteralData",10)==0
+	   || strncasecmp($2,"ComplexOutput",13)==0 || strncasecmp($2,"LiteralOutput",12)==0
+	   || strncasecmp($2,"BoundingBoxOutput",13)==0 || strncasecmp($2,"BoundingBoxData",12)==0){
+	  current_data=4;
+	  addMapToMap(&current_element->content,current_content);
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_element->next=NULL;
+	  if($2!=NULL)
+	    current_element->format=zStrdup($2);
+	  current_element->defaults=NULL;
+	  current_element->supported=NULL;
+	  current_content=NULL;
+	}
+	else
+	  if(strncasecmp($2,"Default",7)==0){
+	    wait_defaults=true;
+	    current_data=5;
+	  }
+	  else
+	    if(strncasecmp($2,"Supported",9)==0){
+	      wait_supporteds=true;
+	      if(wait_defaults==true){
+		defaultsc++;
+	      }
+	      current_data=5;
+	    }
+#ifdef DEBUG_SERVICE_CONF
+  printf("* Identifiant : %s\n",$2);
+  fflush(stdout);
+#endif
+}
+ ;
+
+// Attributeetoile
+// regle 41
+// une liste qui peut etre vide d'attributs
+// utiliser la récursivité a gauche
+Attributeetoile
+: Attributeetoile attribute  {}
+ | 	                          {/* Epsilon */}
+ ;
+
+// attribute
+// regle 41
+// un attribut est compose d'un identifiant
+// d'un "="
+// et d'une définition de chaine de caractere
+// ( "xxx" ou 'xxx' )
+attribute
+ : ID Eq ATTVALUE		
+{
+#ifdef DEBUG_SERVICE_CONF
+  printf ("attribute : %s\n",$1) ;
+#endif
+}
+ ;
+
+// EmptyElemTag
+// regle 44
+// ICI ON DEFINIT NEUTRE
+// on ne renvoie pas de char*
+// parce qu'il n'y a pas de comparaisons a faire
+// avec un identifiant d'une balise jumelle
+EmptyElemTag
+ : INFCAR ID Attributeetoile SLASH SUPCAR	{
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"(%s %d)\n",__FILE__,__LINE__);
+#endif
+   if(strncasecmp($2,"Default",7)==0){
+     wait_defaults=false;
+     current_data=previous_data;
+     if(current_element->defaults==NULL){
+       current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+       current_element->defaults->content=NULL;
+     }
+     addMapToMap(&current_element->defaults->content,current_content);
+     freeMap(&current_content);
+     free(current_content);
+     current_element->defaults->next=NULL;
+     wait_defaults=false;
+     current_content=NULL;
+     current_element->supported=NULL;
+     current_element->next=NULL;
+   }
+ }
+ ;
+
+// ETag
+// BALISE FERMANTE
+// les separateurs après ID sont filtrés
+ETag
+ : INFCAR SLASH ID SUPCAR
+{
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"ETag %s (%s %d) %d %d \n",$3,__FILE__,__LINE__,current_data,previous_data);
+#endif
+  if(strcmp($3,"DataInputs")==0){
+    current_data=1;
+    if(current_content!=NULL){
+      if(current_element->content==NULL){
+	addMapToMap(&current_element->content,current_content);
+      }
+      freeMap(&current_content);
+      free(current_content);
+      current_content=NULL;
+    }
+    if(current_element!=NULL){
+      if(my_service->content!=NULL && current_element->name!=NULL){
+	if(my_service->inputs==NULL){
+	  my_service->inputs=dupElements(current_element);
+	  my_service->inputs->next=NULL;
+	  tmp_count++;
+	}
+	else{
+	  addToElements(&my_service->inputs,current_element);
+	}
+	freeElements(&current_element);
+	free(current_element);
+	current_element=NULL;
+      }
+    }
+  }
+  if(strcmp($3,"DataOutputs")==0){
+    current_data=2;
+  }
+  if(strcmp($3,"MetaData")==0){
+    if(current_content!=NULL){
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"add current_content to current_element->content\n");
+      fprintf(stderr,"LINE %d",__LINE__);
+#endif
+      if(wait_metadata){
+	current_element->metadata=NULL;
+	addMapToMap(&current_element->metadata,current_content);
+	current_element->next=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+      }else{
+	if(wait_mainmetadata){
+	  addMapToMap(&my_service->metadata,current_content);
+	}
+      }
+
+      freeMap(&current_content);
+      free(current_content);
+      current_content=NULL;
+    }
+    current_data=previous_data;
+    wait_mainmetadata=false;
+    wait_metadata=false;
+  }
+  if(strcmp($3,"ComplexData")==0 || strcmp($3,"LiteralData")==0 
+     || strcmp($3,"ComplexOutput")==0 || strcmp($3,"LiteralOutput")==0){
+    if(current_element->format==NULL)
+      current_element->format=zStrdup($3);
+    current_content=NULL;
+  }
+  if(strcmp($3,"Default")==0){
+    current_data=previous_data;
+    if(current_element->defaults==NULL){
+      current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+      current_element->defaults->content=NULL;
+    }
+    addMapToMap(&current_element->defaults->content,current_content);
+    freeMap(&current_content);
+    free(current_content);
+    current_element->defaults->next=NULL;
+    wait_defaults=false;
+    current_content=NULL;
+    current_element->supported=NULL;
+    current_element->next=NULL;
+  }
+  if(strcmp($3,"Supported")==0){
+    current_data=previous_data;
+    if(current_element->supported==NULL){
+      if(current_content!=NULL){
+	current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	current_element->supported->content=NULL;
+	addMapToMap(&current_element->supported->content,current_content);
+	freeMap(&current_content);
+	free(current_content);
+	current_element->supported->next=NULL;
+	current_content=NULL;
+      }else{
+	current_element->supported=NULL;
+	current_element->next=NULL;
+      }
+    }
+    else{
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"SECOND SUPPORTED FORMAT !!!!\n");
+#endif
+      addMapToIoType(&current_element->supported,current_content);
+      freeMap(&current_content);
+      free(current_content);
+      current_content=NULL;
+#ifdef DEBUG_SERVICE_CONF
+      dumpElements(current_element);
+      fprintf(stderr,"SECOND SUPPORTED FORMAT !!!!\n");
+#endif
+    }
+    current_content=NULL;
+  }
+}
+ ;
+
+//======================================================
+// contentetoile
+//======================================================
+// regle 43
+// ENTRE 2 BALISES
+// entre 2 balises, on peut avoir :
+// --- OUVRANTE CONTENU FERMANTE (recursivement !)
+// --- DU TEXTE quelconque
+// --- COMMENTS 
+// --- DES PROCESSES INSTRUCTIONS
+// --- /!\ il peut y avoir une processing instruction invalide ! <?xml
+// --- EPSILON
+// ### et/ou tout ca a la suite en nombre indeterminé
+// ### donc c'est un operateur etoile (*)
+//======================================================
+contentetoile
+: contentetoile element	          {}
+ | contentetoile PIERROR	          {srerror("processing instruction <?xml ?> impossible\n");}
+ | contentetoile PI	                  {}
+///// on filtre les commentaires | contentetoile comment              {} 
+ | contentetoile NEWLINE {/*printf("NEWLINE FOUND !!");*/}
+ | contentetoile pair {}
+ | contentetoile processid {}
+ | contentetoile texteinterbalise	  {}
+ | contentetoile CDATA {}  
+ | {/* Epsilon */}
+ ;
+
+// texteinterbalise
+// regle 14
+// DU TEXTE quelconque
+// c'est du CHARDATA
+// il y a eut un probleme avec ID,
+// on a mis des starts conditions,
+// maintenant on croise les ID dans les dbalises
+// et des CHARDATA hors des balises
+texteinterbalise
+ : CHARDATA		{}
+ ;
+
+pair: PAIR { if(debug) fprintf(stderr,"PAIR FOUND !!\n");if(curr_key!=NULL){free(curr_key);curr_key=NULL;} }
+| EPAIR {
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"EPAIR (%s %d)\n",__FILE__,__LINE__);
+  fprintf(stderr,"[%s=>%s]\n",curr_key,$1);
+  dumpMap(current_content);
+  fflush(stderr);
+#endif
+  if($1!=NULL && curr_key!=NULL){
+    if(current_content==NULL){
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"[ZOO: service_conf.y line %d free(%s)]\n",__LINE__,curr_key);
+#endif
+      current_content=createMap(curr_key,$1);
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"[ZOO: service_conf.y line %d free(%s)]\n",__LINE__,curr_key);
+#endif
+    }
+    else{ 
+#ifdef DEBUG_SERVICE_CONF
+      dumpMap(current_content);
+      fprintf(stderr,"addToMap(current_content,%s,%s) !! \n",curr_key,$1); 
+#endif
+      addToMap(current_content,curr_key,$1);
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"addToMap(current_content,%s,%s) end !! \n",curr_key,$1); 
+#endif    
+    }
+  }
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"[%s=>%s]\n",curr_key,$1);
+  fprintf(stderr,"[ZOO: service_conf.y line %d free(%s)]\n",__LINE__,curr_key);
+  dumpMap(current_content);
+  fflush(stderr);
+#endif
+  if(curr_key!=NULL){
+    free(curr_key);
+    curr_key=NULL;
+  }
+  }
+| SPAIR  { if(curr_key!=NULL) {free(curr_key);curr_key=NULL;} if($1!=NULL) curr_key=zStrdup($1);if(debug) fprintf(stderr,"SPAIR FOUND !!\n"); }
+ ;
+
+
+processid
+: ANID  {
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"processid (%s %d) %s\n",__FILE__,__LINE__,$1);
+#endif
+  if(data==-1){
+    data=1;
+    if($1!=NULL){
+      char *cen=zStrdup($1);
+      my_service->name=(char*)malloc((strlen(cen)-1)*sizeof(char*));
+      cen[strlen(cen)-1]=0;
+      cen+=1;
+      sprintf(my_service->name,"%s",cen);
+      cen-=1;
+      free(cen);
+      my_service->content=NULL;
+      my_service->metadata=NULL;
+      my_service->inputs=NULL;
+      my_service->outputs=NULL;
+    }
+  } else {
+    if(current_data==1){
+      if(my_service->content!=NULL && current_element->name!=NULL){
+	if(my_service->inputs==NULL){
+	  my_service->inputs=dupElements(current_element);
+	  my_service->inputs->next=NULL;
+	  tmp_count++;
+	}
+	else{
+	  addToElements(&my_service->inputs,current_element);
+	}
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"(%s %d)FREE current_element (after adding to allread existing inputs)",__FILE__,__LINE__);
+	dumpElements(current_element);
+	fprintf(stderr,"(%s %d)FREE current_element (after adding to allread existing inputs)",__FILE__,__LINE__);
+	dumpElements(my_service->inputs);
+#endif
+	freeElements(&current_element);
+	free(current_element);
+	current_element=NULL;
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"(DATAINPUTS - 489) ALLOCATE current_element\n");
+#endif
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=NULL;
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->next=NULL;
+      }
+      if(current_element->name==NULL){
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"NAME IN %s (current - %s)\n",
+		$1,current_element->name);
+#endif
+	wait_inputs=true;
+#ifdef DEBUG_SERVICE_CONF
+	fprintf(stderr,"(DATAINPUTS - 501) SET NAME OF current_element\n");
+#endif
+	if($1!=NULL){ 
+	  char *cen=zStrdup($1);
+	  current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char*));
+	  cen[strlen(cen)-1]=0;
+	  cen+=1;
+	  sprintf(current_element->name,"%s",cen);
+	  cen-=1;
+	  free(cen);
+#ifdef DEBUG_SERVICE_CONF
+	  fprintf(stderr,"NAME IN %s (current - %s)\n",$1,current_element->name);
+#endif
+	  current_element->content=NULL;
+	  current_element->metadata=NULL;
+	  current_element->format=NULL;
+	  current_element->defaults=NULL;
+	  current_element->supported=NULL;
+	  current_element->next=NULL;
+#ifdef DEBUG_SERVICE_CONF
+	  fprintf(stderr,"NAME IN %s (current - %s)\n",$1,current_element->name);
+#endif
+	}
+      }
+    }
+    else
+      if(current_data==2){ 
+	wait_outputs=1;
+	if(wait_inputs){
+	  if(current_element!=NULL && current_element->name!=NULL){
+	    if(my_service->outputs==NULL){
+	      my_service->outputs=dupElements(current_element);
+	      my_service->outputs->next=NULL;
+	    }
+	    else{
+#ifdef DEBUG_SERVICE_CONF
+	      fprintf(stderr,"LAST NAME IN %s (current - %s)\n",$1,current_element->name);
+#endif
+	      addToElements(&my_service->outputs,current_element);
+	    }
+#ifdef DEBUG_SERVICE_CONF
+	    dumpElements(current_element);
+	    fprintf(stderr,"(DATAOUTPUTS) FREE current_element %s %i\n",__FILE__,__LINE__);
+#endif
+	    freeElements(&current_element);
+	    free(current_element);
+	    current_element=NULL;
+#ifdef DEBUG_SERVICE_CONF
+	    fprintf(stderr,"(DATAOUTPUTS -%d) ALLOCATE current_element %s \n",__LINE__,__FILE__);
+#endif
+	    current_element=(elements*)malloc(ELEMENTS_SIZE);
+	    current_element->name=NULL;
+	    current_element->content=NULL;
+	    current_element->metadata=NULL;
+	    current_element->format=NULL;
+	    current_element->defaults=NULL;
+	    current_element->supported=NULL;
+	    current_element->next=NULL;
+	  }
+	  if(current_element->name==NULL){
+#ifdef DEBUG_SERVICE_CONF
+	    fprintf(stderr,"NAME OUT %s\n",$1);
+	    fprintf(stderr,"(DATAOUTPUTS - %d) SET NAME OF current_element\n",__LINE__);
+#endif
+	    if($1!=NULL){ 
+	      char *cen=zStrdup($1);
+	      current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char));
+	      cen[strlen(cen)-1]=0;
+	      cen+=1;
+	      sprintf(current_element->name,"%s",cen);
+	      cen-=1;
+	      free(cen);
+	      current_element->content=NULL;
+	      current_element->metadata=NULL;
+	      current_element->format=NULL;
+	      current_element->defaults=NULL;
+	      current_element->supported=NULL;
+	      current_element->next=NULL;
+	    }
+	  }
+
+	  current_content=NULL;
+	}
+	else
+	  if(current_element!=NULL && current_element->name!=NULL){
+	    if(my_service->outputs==NULL)
+	      my_service->outputs=dupElements(current_element);
+	    else
+	      addToElements(&my_service->outputs,current_element);
+#ifdef DEBUG_SERVICE_CONF
+	    fprintf(stderr,"ADD TO OUTPUTS Elements\n");
+	    dupElements(current_element);
+#endif
+	    freeElements(&current_element);
+	    free(current_element);
+	    current_element=NULL;
+	    current_element=(elements*)malloc(ELEMENTS_SIZE);
+	    char *cen=zStrdup($1);
+	    current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char));
+	    cen[strlen(cen)-1]=0;
+	    cen+=1;
+	    sprintf(current_element->name,"%s",cen);
+	    cen-=1;
+	    free(cen);
+	    current_element->content=NULL;
+	    current_element->metadata=NULL;
+	    current_element->format=NULL;
+	    current_element->defaults=NULL;
+	    current_element->supported=NULL;
+	    current_element->next=NULL;
+	  }
+	  else{
+#ifdef DEBUG_SERVICE_CONF
+	    fprintf(stderr,"NAME OUT %s\n",$1);
+	    fprintf(stderr,"(DATAOUTPUTS - %d) SET NAME OF current_element %s\n",__LINE__,$1);
+#endif
+	    if($1!=NULL){ 
+	      char *cen=zStrdup($1);
+	      current_element->name=(char*)malloc((strlen(cen))*sizeof(char*));
+	      cen[strlen(cen)-1]=0;
+#ifdef DEBUG
+	      fprintf(stderr,"tmp %s\n",cen);
+#endif
+	      cen+=1;
+	      sprintf(current_element->name,"%s",cen);
+	      cen-=1;
+	      free(cen);
+	      current_element->content=NULL;
+	      current_element->metadata=NULL;
+	      current_element->format=NULL;
+	      current_element->defaults=NULL;
+	      current_element->supported=NULL;
+	      current_element->next=NULL;
+	    }
+	  }
+	wait_inputs=false;
+	wait_outputs=1;
+	//wait_outputs=true;
+      }
+  }
+ }
+ ;
+
+%%
+
+/**
+ * Print on stderr the message and the line number of the error which occured.
+ * 
+ * @param s the error message
+ */
+void srerror(const char *s)
+{
+  if(debug)
+    fprintf(stderr,"\nligne %d : %s\n",srlineno,s);
+}
+
+/**
+ * Parse a ZCFG file and fill the service structure.
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param file the fullpath to the ZCFG file
+ * @param service the service structure to fill
+ * @return 0 on success, -1 on failure
+ */
+int getServiceFromFile(maps* conf,const char* file,service** service){
+  if(current_content!=NULL){
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"(STARTING)FREE current_element\n");
+#endif
+  if(current_element!=NULL){
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  my_service=NULL;
+
+  wait_maincontent=true;
+  wait_mainmetadata=false;
+  wait_metadata=false;
+  wait_inputs=false;
+  wait_defaults=false;
+  wait_supporteds=false;
+  wait_outputs=-1;
+  wait_data=false;
+  data=-1;
+  previous_data=1;
+  current_data=0;
+  
+  my_service=*service;
+
+  srin = fopen(file,"r");
+  if (srin==NULL){
+    setMapInMaps(conf,"lenv","message","file not found");
+    return -1;
+  }
+
+  int resultatYYParse = srparse() ;
+
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"RESULT: %d %d\n",resultatYYParse,wait_outputs);
+  dumpElements(current_element);
+#endif
+  if(wait_outputs && current_element!=NULL && current_element->name!=NULL){
+    if(my_service->outputs==NULL){  
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"(DATAOUTPUTS - %d) DUP current_element\n",__LINE__);
+#endif
+      my_service->outputs=dupElements(current_element);
+      my_service->outputs->next=NULL;
+    }
+    else{
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"(DATAOUTPUTS - %d) COPY current_element\n",__LINE__);
+#endif
+      addToElements(&my_service->outputs,current_element);
+    }
+#ifdef DEBUG_SERVICE_CONF
+    fprintf(stderr,"(DATAOUTPUTS - %d) FREE current_element\n",__LINE__);
+#endif
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+#ifdef DEBUG_SERVICE_CONF
+    fprintf(stderr,"(DATAOUTPUTS - %d) FREE current_element\n",__LINE__);
+#endif
+  }
+  if(current_element!=NULL){
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  int contentOnly=false;
+  if(current_content!=NULL){
+    if(my_service->content==NULL){
+      addMapToMap(&my_service->content,current_content);
+      contentOnly=true;
+      wait_maincontent=false;
+    }
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+  fclose(srin);
+#ifdef DEBUG_SERVICE_CONF
+  dumpService(my_service);
+#endif
+  if(wait_maincontent==true || (contentOnly==false && ((!wait_outputs && current_data==2 && my_service->outputs==NULL) || my_service==NULL || my_service->name==NULL || my_service->content==NULL))){
+    setMapInMaps(conf,"lenv","message",srlval.chaine);
+#ifndef WIN32
+    srlex_destroy();
+#endif
+    return -1;
+  }
+  else
+    *service=my_service;
+
+#ifndef WIN32
+  srlex_destroy();
+#endif
+  return resultatYYParse;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.c	(revision 672)
@@ -0,0 +1,735 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "fcgi_stdio.h"
+#include "service_internal.h"
+#ifdef USE_MS
+#include "service_internal_ms.h"
+#else
+#include "cpl_vsi.h"
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE -1
+#endif
+
+#define ERROR_MSG_MAX_LENGTH 1024
+#ifndef RELY_ON_DB
+#include <dirent.h>
+
+/**
+ * Read the sid file attached of a service if any
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the reported status char* (temporary/final result)
+ */
+char* getStatusId(maps* conf,char* pid){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char* fbkpid =
+    (char *)
+    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
+  sprintf (fbkpid, "%s/%s.sid", r_inputs->value, pid);
+  FILE* f0 = fopen (fbkpid, "r");
+  if(f0!=NULL){
+    long flen;
+    char *fcontent;
+    fseek (f0, 0, SEEK_END);
+    flen = ftell (f0);
+    fseek (f0, 0, SEEK_SET);
+    fcontent = (char *) malloc ((flen + 1) * sizeof (char));
+    fread(fcontent,flen,1,f0);
+    fcontent[flen]=0;
+    fclose(f0);
+    return fcontent;
+  }else
+    return NULL;
+}
+
+/**
+ * Acquire the global lock
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @return a semid 
+ */
+semid acquireLock(maps* conf){
+  semid lockid;
+  int itn=0;
+ toRetry1:
+  lockid=getShmLockId(conf,1);
+  if(
+#ifdef WIN32
+     lockid==NULL
+#else
+     lockid<0
+#endif
+     ){
+#ifdef WIN32
+    return NULL
+#else
+    return -1;
+#endif
+  }
+  if(lockShm(lockid)<0){
+    if(itn<ZOO_LOCK_MAX_RETRY){
+      itn++;
+      goto toRetry1;
+    }else
+#ifdef WIN32
+    return NULL
+#else
+    return -1;
+#endif
+  }else
+    return lockid;
+}
+
+/**
+ * Read the cache file of a running service 
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the reported status char* (temporary/final result)
+ */
+char* _getStatusFile(maps* conf,char* pid){
+  map* tmpTmap = getMapFromMaps (conf, "main", "tmpPath");
+
+  struct dirent *dp;
+  DIR *dirp = opendir(tmpTmap->value);
+  char fileName[1024];
+  int hasFile=-1;
+  if(dirp!=NULL){
+    char tmp[128];
+    sprintf(tmp,"_%s.xml",pid);
+    while ((dp = readdir(dirp)) != NULL){
+#ifdef DEBUG
+      fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
+#endif
+      if(strstr(dp->d_name,"final_")==0 && strstr(dp->d_name,tmp)!=0){
+	sprintf(fileName,"%s/%s",tmpTmap->value,dp->d_name);
+	hasFile=1;
+	break;
+      }
+    }
+  }
+  if(hasFile>0){
+    semid lockid;
+    char* stat=getStatusId(conf,pid);
+    if(stat!=NULL){
+      setMapInMaps(conf,"lenv","lid",stat);
+      lockid=acquireLock(conf);
+      if(lockid<0)
+	return NULL;
+    }
+
+    FILE* f0 = fopen (fileName, "r");
+    if(f0!=NULL){
+      fseek (f0, 0, SEEK_END);
+      long flen = ftell (f0);
+      fseek (f0, 0, SEEK_SET);
+      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
+      fread(tmps1,flen,1,f0);
+      tmps1[flen]=0;
+      fclose(f0);
+      if(stat!=NULL){
+	unlockShm(lockid);
+	free(stat);
+      }
+
+      return tmps1;
+    }
+    else{
+      if(stat!=NULL){
+	unlockShm(lockid);
+	free(stat);
+      }
+      return NULL;
+    }
+  }
+  else
+    return NULL;
+}
+
+/**
+ * Get the ongoing status of a running service 
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the reported status char* (MESSAGE|POURCENTAGE)
+ */
+char* _getStatus(maps* conf,char* lid){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  char* fbkpid =
+    (char *)
+    malloc ((strlen (r_inputs->value) + strlen (lid) + 9) * sizeof (char));
+  sprintf (fbkpid, "%s/%s.status", r_inputs->value, lid);
+  FILE* f0 = fopen (fbkpid, "r");
+  if(f0!=NULL){
+    semid lockid;
+    char* stat;
+    long flen;
+    stat=getStatusId(conf,lid);
+    if(stat!=NULL){
+      setMapInMaps(conf,"lenv","lid",stat);
+      lockid=acquireLock(conf);
+      if(lockid<0)
+	return NULL;
+    }
+    fseek (f0, 0, SEEK_END);
+    flen = ftell (f0);
+    if(flen>0){
+      char *fcontent;
+      fseek (f0, 0, SEEK_SET);
+      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
+      fread(fcontent,flen,1,f0);
+      fcontent[flen]=0;
+      fclose(f0);
+      free(fbkpid);
+      if(stat!=NULL){
+	removeShmLock(conf,1);
+	free(stat);
+      }
+      return fcontent;
+    }
+    fclose(f0);
+    free(fbkpid);
+    if(stat!=NULL){
+      removeShmLock(conf,1);
+      free(stat);
+    }
+    return NULL;
+  }else{
+    free(fbkpid);
+    char* stat=getStatusId(conf,lid);
+    setMapInMaps(conf,"lenv","lid",stat);
+    removeShmLock(conf,1);
+    return NULL;
+  }
+}
+
+/**
+ * Stop handling status repport.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ */
+void unhandleStatus(maps *conf){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  map* usid = getMapFromMaps (conf, "lenv", "usid");
+  char* fbkpid =
+    (char *) malloc ((strlen (r_inputs->value) + strlen (usid->value) + 9) 
+		     * sizeof (char));
+  sprintf (fbkpid, "%s/%s.status", r_inputs->value, usid->value);
+  unlink(fbkpid);
+  free(fbkpid);
+}
+
+/**
+ * Update the current status of the running service.
+ *
+ * @see acquireLock, lockShm
+ * @param conf the map containing the setting of the main.cfg file
+ * @return 0 on success, -2 if shmget failed, -1 if shmat failed
+ */
+int _updateStatus(maps *conf){
+  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  map* sid = getMapFromMaps (conf, "lenv", "usid");
+  char* fbkpid =
+    (char *)
+    malloc ((strlen (r_inputs->value) + strlen (sid->value) + 9) * sizeof (char));
+  sprintf (fbkpid, "%s/%s.status", r_inputs->value, sid->value);
+  map* status=getMapFromMaps(conf,"lenv","status");
+  map* msg=getMapFromMaps(conf,"lenv","message");
+  if(status!=NULL && msg!=NULL &&
+     status->value!=NULL && msg->value!=NULL && 
+     strlen(status->value)>0 && strlen(msg->value)>1){
+    semid lockid;
+    char* stat=getStatusId(conf,sid->value);
+    if(stat!=NULL){
+      lockid=acquireLock(conf);
+      if(lockid<0)
+	return ZOO_LOCK_ACQUIRE_FAILED;
+    }
+    FILE* fstatus=fopen(fbkpid,"w");
+    if(fstatus!=NULL){
+      fprintf(fstatus,"%s|%s",status->value,msg->value);
+      fflush(fstatus);
+      fclose(fstatus);
+    }
+    if(stat!=NULL){
+      unlockShm(lockid);
+      free(stat);
+    }
+  }
+  return 0;
+}
+
+#endif
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <fcgi_stdio.h>
+#include <stdio.h>
+#include <conio.h>
+#include <tchar.h>
+
+#define SHMEMSIZE 4096
+
+size_t getKeyValue(maps* conf, char* key, size_t length){
+  if(conf==NULL) {
+    strncpy(key, "700666", length);
+    return strlen(key);
+  }
+  
+  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
+  if(tmpMap==NULL)
+	tmpMap=getMapFromMaps(conf,"lenv","osid");
+
+  if(tmpMap!=NULL){
+	snprintf(key, length, "zoo_sem_%s", tmpMap->value);      
+  }
+  else {
+	strncpy(key, "-1", length);  
+  }
+  return strlen(key);
+}
+
+
+semid getShmLockId(maps* conf, int nsems){
+    semid sem_id;
+    char key[MAX_PATH];
+    getKeyValue(conf, key, MAX_PATH);
+    
+    sem_id = CreateSemaphore( NULL, nsems, nsems+1, key);
+    if(sem_id==NULL){
+#ifdef DEBUG
+      fprintf(stderr,"Semaphore failed to create: %s\n", getLastErrorMessage());
+#endif
+      return NULL;
+    }
+#ifdef DEBUG
+    fprintf(stderr,"%s Accessed !\n",key);
+#endif
+
+    return sem_id;
+}
+
+int removeShmLock(maps* conf, int nsems){
+  semid sem_id=getShmLockId(conf,1);
+  if (CloseHandle(sem_id) == 0) {
+#ifdef DEBUG
+    fprintf(stderr,"Unable to remove semaphore: %s\n", getLastErrorMessage());
+#endif
+    return -1;
+  }
+#ifdef DEBUG
+  fprintf(stderr,"%d Removed !\n",sem_id);
+#endif
+  return 0;
+}
+
+int lockShm(semid id){
+  DWORD dwWaitResult=WaitForSingleObject(id,INFINITE);
+  switch (dwWaitResult){
+    case WAIT_OBJECT_0:
+      return 0;
+      break;
+    case WAIT_TIMEOUT:
+      return -1;
+      break;
+    default:
+      return -2;
+      break;
+  }
+  return 0;
+}
+
+int unlockShm(semid id){
+  if(!ReleaseSemaphore(id,1,NULL)){
+    return -1;
+  }
+  return 0;
+}
+
+static LPVOID lpvMemG = NULL;      // pointer to shared memory
+static HANDLE hMapObjectG = NULL;  // handle to file mapping
+
+
+char* getStatus(int pid){
+  char *lpszBuf=(char*) malloc(SHMEMSIZE*sizeof(char));
+  int i=0;
+  LPWSTR lpszTmp=NULL;
+  LPVOID lpvMem = NULL;
+  HANDLE hMapObject = NULL;
+  BOOL fIgnore,fInit;
+  char tmp[1024];
+  sprintf(tmp,"%d",pid);
+  if(hMapObject==NULL)
+    hMapObject = CreateFileMapping( 
+				   INVALID_HANDLE_VALUE,   // use paging file
+				   NULL,                   // default security attributes
+				   PAGE_READWRITE,         // read/write access
+				   0,                      // size: high 32-bits
+				   4096,                   // size: low 32-bits
+				   TEXT(tmp));   // name of map object
+  if (hMapObject == NULL){
+#ifdef DEBUG
+    fprintf(stderr,"ERROR on line %d\n",__LINE__);
+#endif
+    return "-1";
+  }
+  if((GetLastError() != ERROR_ALREADY_EXISTS)){
+#ifdef DEBUG
+    fprintf(stderr,"ERROR on line %d\n",__LINE__);
+    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
+#endif
+    fIgnore = UnmapViewOfFile(lpvMem); 
+    fIgnore = CloseHandle(hMapObject);
+    return "-1";
+  }
+  fInit=TRUE;
+  if(lpvMem==NULL)
+    lpvMem = MapViewOfFile( 
+			   hMapObject,     // object to map view of
+			   FILE_MAP_READ,  // read/write access
+			   0,              // high offset:  map from
+			   0,              // low offset:   beginning
+			   0);             // default: map entire file
+  if (lpvMem == NULL){
+#ifdef DEBUG
+    fprintf(stderr,"READING STRING S %d\n",__LINE__);
+    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
+#endif
+    return "-1"; 
+  }
+  lpszTmp = (LPWSTR) lpvMem;
+  while (*lpszTmp){
+    lpszBuf[i] = (char)*lpszTmp;
+    *lpszTmp++; 
+    lpszBuf[i+1] = '\0'; 
+    i++;
+  }
+  return (char*)lpszBuf;
+}
+
+#else
+/**
+ * Number of time to try to access a semaphores set
+ * @see getShmLockId
+ */
+#define MAX_RETRIES 10
+
+#ifndef __APPLE__
+/**
+ * arg for semctl system calls. 
+ */
+union semun {
+  int val; //!< value for SETVAL 
+  struct semid_ds *buf; //!< buffer for IPC_STAT & IPC_SET
+  ushort *array; //!< array for GETALL & SETALL
+};
+#endif
+
+/**
+ * Set in the pre-allocated key the zoo_sem_[OSID] string 
+ * where [OSID] is the lid (if any) or osid value from the [lenv] section.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ */
+int getKeyValue(maps* conf){
+  if(conf==NULL)
+     return 700666;
+  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
+  if(tmpMap==NULL)
+    tmpMap=getMapFromMaps(conf,"lenv","osid");
+  int key=-1;
+  if(tmpMap!=NULL)
+    key=atoi(tmpMap->value);
+  return key;
+}
+
+/**
+ * Try to create or access a semaphore set.
+ *
+ * @see getKeyValue
+ * @param conf the map containing the setting of the main.cfg file
+ * @param nsems number of semaphores
+ * @return a semaphores set indentifier on success, -1 in other case
+ */
+int getShmLockId(maps* conf, int nsems){
+    int i;
+    union semun arg;
+    struct semid_ds buf;
+    struct sembuf sb;
+    semid sem_id;
+    int key=getKeyValue(conf);
+    
+    sem_id = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666);
+
+    if (sem_id >= 0) { /* we got it first */
+        sb.sem_op = 1; 
+	sb.sem_flg = 0;
+	arg.val=1;
+        for(sb.sem_num = 0; sb.sem_num < nsems; sb.sem_num++) { 
+            /* do a semop() to "free" the semaphores. */
+            /* this sets the sem_otime field, as needed below. */
+            if (semop(sem_id, &sb, 1) == -1) {
+                int e = errno;
+                semctl(sem_id, 0, IPC_RMID); /* clean up */
+                errno = e;
+                return -1; /* error, check errno */
+            }
+        }
+    } else if (errno == EEXIST) { /* someone else got it first */
+        int ready = 0;
+
+        sem_id = semget(key, nsems, 0); /* get the id */
+        if (sem_id < 0) return sem_id; /* error, check errno */
+
+        /* wait for other process to initialize the semaphore: */
+        arg.buf = &buf;
+        for(i = 0; i < MAX_RETRIES && !ready; i++) {
+            semctl(sem_id, nsems-1, IPC_STAT, arg);
+            if (arg.buf->sem_otime != 0) {
+#ifdef DEBUG
+	      fprintf(stderr,"Semaphore acquired ...\n");
+#endif
+	      ready = 1;
+            } else {
+#ifdef DEBUG
+	      fprintf(stderr,"Retry to access the semaphore later ...\n");
+#endif
+	      zSleep(1);
+            }
+        }
+	errno = ZOO_LOCK_ACQUIRE_FAILED;
+        if (!ready) {
+#ifdef DEBUG
+	  fprintf(stderr,"Unable to access the semaphore ...\n");
+#endif
+	  errno = ETIME;
+	  return -1;
+        }
+    } else {
+        return sem_id; /* error, check errno */
+    }
+#ifdef DEBUG
+    fprintf(stderr,"%d Created !\n",sem_id);
+#endif
+    return sem_id;
+}
+
+/**
+ * Try to remove a semaphore set.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ * @param nsems number of semaphores
+ * @return 0 if the semaphore can be removed, -1 in other case.
+ */
+int removeShmLock(maps* conf, int nsems){
+  union semun arg;
+  int sem_id=getShmLockId(conf,nsems);
+  if (semctl(sem_id, 0, IPC_RMID, arg) == -1) {
+#ifdef DEBUG
+    perror("semctl remove");
+#endif
+    return -1;
+  }
+#ifdef DEBUG
+  fprintf(stderr,"Semaphore removed!\n");
+#endif
+  return 0;
+}
+
+/**
+ * Lock a semaphore set.
+ *
+ * @param id the semaphores set indetifier
+ * @return 0 if the semaphore can be locked, -1 in other case.
+ */
+int lockShm(int id){
+  struct sembuf sb;
+  sb.sem_num = 0;
+  sb.sem_op = -1;  /* set to allocate resource */
+  sb.sem_flg = SEM_UNDO;
+  if (semop(id, &sb, 1) == -1){
+#ifdef DEBUG
+    perror("semop lock");
+#endif
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * unLock a semaphore set.
+ *
+ * @param id the semaphores set indetifier
+ * @return 0 if the semaphore can be locked, -1 in other case.
+ */
+int unlockShm(int id){
+  struct sembuf sb;
+  sb.sem_num = 0;
+  sb.sem_op = 1;  /* free resource */
+  sb.sem_flg = SEM_UNDO;
+  if (semop(id, &sb, 1) == -1) {
+#ifdef DEBUG
+    perror("semop unlock");
+#endif
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * Get the current status of the running service.
+ *
+ * @see getKeyValue, getShmLockId, lockShm
+ * @param pid the semaphores 
+ * @return 0 on success, -2 if shmget failed, -1 if shmat failed
+ */
+char* getStatus(int pid){
+  int shmid;
+  key_t key;
+  void *shm;
+  key=pid;
+  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
+#ifdef DEBUG
+    fprintf(stderr,"shmget failed in getStatus\n");
+#endif
+  }else{
+    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
+#ifdef DEBUG
+      fprintf(stderr,"shmat failed in getStatus\n");
+#endif
+    }else{
+      char *ret=strdup((char*)shm);
+      shmdt((void *)shm);
+      return ret;
+    }
+  }
+  return (char*)"-1";
+}
+
+#endif
+
+/**
+ * Update the status of an ongoing service 
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param percentCompleted percentage of completude of execution of the service
+ * @param message information about the current step executed
+ * @return the value of _updateStatus
+ * @see _updateStatus
+ */
+int updateStatus( maps* conf, const int percentCompleted, const char* message ){
+  char tmp[4];
+  snprintf(tmp,4,"%d",percentCompleted);
+  setMapInMaps( conf, "lenv", "status", tmp );
+  setMapInMaps( conf, "lenv", "message", message);
+  return _updateStatus( conf );
+}
+
+/**
+ * Access an input value 
+ *
+ * @param inputs the maps to search for the input value
+ * @param parameterName the input name to fetch the value
+ * @param numberOfBytes the resulting size of the value to add (for binary
+ *  values), -1 for basic char* data
+ * @return a pointer to the input value if found, NULL in other case.
+ */
+char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
+  map* res=getMapFromMaps(inputs,parameterName,"value");
+  if(res!=NULL){
+    map* size=getMapFromMaps(inputs,parameterName,"size");
+    if(size!=NULL){
+      *numberOfBytes=(size_t)atoi(size->value);
+      return res->value;
+    }else{
+      *numberOfBytes=strlen(res->value);
+      return res->value;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Read a file using the GDAL VSI API 
+ *
+ * @param conf the maps containing the settings of the main.cfg file
+ * @param dataSource the datasource name to read
+ * @warning make sure to free ressources returned by this function
+ */
+char *readVSIFile(maps* conf,const char* dataSource){
+    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
+    VSIStatBuf file_status;
+    VSIStat(dataSource, &file_status);
+    if(fichier==NULL){
+      char tmp[1024];
+      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %lld.",
+	      dataSource,file_status.st_size);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return NULL;
+    }
+    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
+    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
+    res1[file_status.st_size-1]=0;
+    VSIFCloseL(fichier);
+    VSIUnlink(dataSource);
+    return res1;
+}
+
+/**
+ * Set an output value 
+ *
+ * @param outputs the maps to define the output value
+ * @param parameterName the output name to set the value
+ * @param data the value to set
+ * @param numberOfBytes size of the value to add (for binary values), -1 for
+ *  basic char* data
+ * @return 0
+ */
+int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
+  if(numberOfBytes==-1){
+    setMapInMaps(outputs,parameterName,"value",data);
+  }else{
+    char size[1024];
+    map* tmp=getMapFromMaps(outputs,parameterName,"value");
+    if(tmp==NULL){
+      setMapInMaps(outputs,parameterName,"value","");
+      tmp=getMapFromMaps(outputs,parameterName,"value");
+    }
+    free(tmp->value);
+    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
+    memcpy(tmp->value,data,numberOfBytes);
+    sprintf(size,"%lu",numberOfBytes);
+    setMapInMaps(outputs,parameterName,"size",size);
+  }
+  return 0;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal.h	(revision 672)
@@ -0,0 +1,130 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2013 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_H
+#define ZOO_SERVICE_INTERNAL_H 1
+
+#pragma once 
+
+/**
+ * The default service url (overriden by serverAddress)
+ */
+#define DEFAULT_SERVICE_URL "http://www.zoo-project.org/"
+/**
+ * The time size
+ */
+#define TIME_SIZE 40
+
+#include <libintl.h>
+#include <locale.h>
+/**
+ * ZOO-Kernel internal messages translation function
+ */
+#define _(String) dgettext ("zoo-kernel",String)
+/**
+ * ZOO-Services messages translation function
+ */
+#define _ss(String) dgettext ("zoo-services",String)
+
+/**
+ * ZOO-Kernel was unable to create a lock
+ */
+#define ZOO_LOCK_CREATE_FAILED -4
+/**
+ * ZOO-Kernel was unable to acquire a lock
+ */
+#define ZOO_LOCK_ACQUIRE_FAILED -5
+/**
+ * ZOO-Kernel was unable to release a lock
+ */
+#define ZOO_LOCK_RELEASE_FAILED -6
+/**
+ * Number of time the ZOO-Kernel will try to acquire lock
+ */
+#define ZOO_LOCK_MAX_RETRY 10
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "cgic.h"
+#ifndef WIN32
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#else
+#include <direct.h>
+#endif
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#ifndef USE_RUBY
+#include <unistd.h>
+#endif
+#ifndef WIN32
+#include <xlocale.h>
+#endif
+
+#include "service.h"
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+
+#include <CoreServices/CoreServices.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  char *readVSIFile(maps*,const char*);
+  int  setOutputValue( maps*, const char*, char*, size_t);
+  char* getInputValue( maps*,const char*,size_t*);
+
+  void unhandleStatus(maps*);
+  int _updateStatus(maps*);
+  char* _getStatus(maps*,char*);
+  char* _getStatusFile(maps*,char*);
+  char* getStatus(int);
+  char* getStatusId(maps*,char*);
+
+  int updateStatus( maps*,const int,const char*);
+  int removeShmLock(maps*, int);
+  /**
+   * Cross platform type used for Lock identifier
+   */
+#ifndef WIN32
+#define semid int
+#else
+#define semid HANDLE
+#endif
+  semid acquireLock(maps*);
+  semid getShmLockId(maps*,int);
+  int lockShm(semid);
+  int unlockShm(semid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.c	(revision 672)
@@ -0,0 +1,732 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2013 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service_internal_java.h"
+#include "response_print.h"
+
+/**
+ * Load a JAVA class then run the static public method corresponding to the 
+ * service by passing the conf, inputs and outputs parameters by reference.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param real_inputs the maps containing the inputs
+ * @param real_outputs the maps containing the outputs
+ */
+int zoo_java_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+  maps* m=*main_conf;
+  maps* inputs=*real_inputs;
+  maps* outputs=*real_outputs;
+  char ntmp[1024];
+  getcwd(ntmp,1024);
+  map* tmp=getMap(request,"metapath");
+  char *classpath;
+  char *oclasspath;
+  int res=SERVICE_FAILED;
+  char *cclasspath=getenv("CLASSPATH");
+  if(tmp!=NULL){
+    if(cclasspath!=NULL){
+      classpath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+strlen(cclasspath)+4)*sizeof(char));
+      oclasspath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+strlen(cclasspath)+22)*sizeof(char));
+#ifndef WIN32
+      sprintf(classpath,"%s/%s/:%s",ntmp,tmp->value,cclasspath);
+#else
+      sprintf(classpath,"%s/%s/;%s",ntmp,tmp->value,cclasspath);
+#endif
+    }
+    else{
+      classpath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+3)*sizeof(char));
+      oclasspath=(char*) malloc((strlen(ntmp)+strlen(tmp->value)+21)*sizeof(char));
+      sprintf(classpath,"%s/%s/",ntmp,tmp->value);
+    }
+  }else{
+    if(cclasspath!=NULL){
+      classpath=(char*) malloc((strlen(ntmp)+strlen(cclasspath)+3)*sizeof(char));
+      oclasspath=(char*) malloc((strlen(ntmp)+strlen(cclasspath)+21)*sizeof(char));
+#ifndef WIN32
+      sprintf(classpath,"%s/:%s",ntmp,cclasspath);
+#else
+      sprintf(classpath,"%s/;%s",ntmp,cclasspath);
+#endif
+    }
+    else{
+      classpath=(char*) malloc((strlen(ntmp)+2)*sizeof(char));
+      oclasspath=(char*) malloc((strlen(ntmp)+20)*sizeof(char));
+      sprintf(classpath,"%s/",ntmp);
+    }
+
+  }
+  sprintf(oclasspath,"-Djava.class.path=%s",classpath);
+
+#ifdef DEBUG
+  fprintf(stderr,"CLASSPATH=%s\n",classpath);
+  fprintf(stderr,"(%s)\n",oclasspath);
+#endif
+
+  int nb=1;
+  int nbc0=0;
+  maps* javaXXMap=getMaps(*main_conf,"javaxx");
+  if(javaXXMap!=NULL){
+    nbc0+=count(javaXXMap->content);
+  }
+  int nbc1=0;
+  maps* javaXMap=getMaps(*main_conf,"javax");
+  if(javaXMap!=NULL){
+    nbc1+=count(javaXMap->content);
+  }
+#ifdef WIN32
+  nb=2+nbc0+nbc1;
+  JavaVMOption options[nb];
+#else
+  JavaVMOption options[nb+nbc0+nbc1];
+#endif
+  JavaVMInitArgs vm_args;
+  JavaVM *jvm;
+  JNIEnv *env;
+  long result;
+  jmethodID pmid;
+  jclass cls;
+#ifdef JAVA7
+  jobject cls_gr;
+#else
+  jclass cls_gr;
+#endif
+  int i,start;
+  map *cursorxx=NULL;
+  if(javaXXMap!=NULL)
+    cursorxx=javaXXMap->content;
+  map *cursorx=NULL;
+  if(javaXMap!=NULL)
+    cursorx=javaXMap->content;
+  options[0].optionString = oclasspath;
+#ifdef WIN32
+  start=2;
+  options[1].optionString = "-Xmx512m";
+#else
+  start=1;
+#endif
+  for(i=0;i<nbc0;i++){
+    char *tmp=parseJVMXXOption(cursorxx);
+    options[start+i].optionString = tmp;
+    free(tmp);
+    cursorxx=cursorxx->next;
+  }
+  for(;i<nbc1+nbc0;i++){
+    char *tmp=parseJVMXOption(cursorx);
+    options[start+i].optionString = tmp;
+    free(tmp);
+    cursorx=cursorx->next;
+  }
+
+  JNI_GetDefaultJavaVMInitArgs(&vm_args);
+  vm_args.version = JNI_VERSION_1_6;
+  vm_args.options = options;
+  vm_args.nOptions = start+nbc0+nbc1;
+  vm_args.ignoreUnrecognized = JNI_TRUE;
+
+  result = JNI_CreateJavaVM(&jvm,(void **)&env, &vm_args);
+  if(result == JNI_ERR ) {
+    fprintf(stderr,"Error invoking the JVM");
+    return -1;
+  }
+#ifdef DEBUG
+  else
+    fprintf(stderr,"JAVA VM Started\n");
+#endif
+
+  tmp=getMap(s->content,"serviceProvider");
+#ifdef JAVA7
+  cls = env->FindClass(tmp->value);
+  cls_gr = env->NewGlobalRef(cls);
+#else
+  cls = (*env)->FindClass(env,tmp->value);
+  cls_gr = (*env)->NewGlobalRef(env, cls);
+#endif
+  if( cls == NULL ) {
+    displayStack(env,*main_conf);
+#ifdef JAVA7
+    (*jvm).DestroyJavaVM();
+#else
+    (*jvm)->DestroyJavaVM(jvm);
+#endif
+    return -1;
+  }
+#ifdef DEBUG
+  else{
+    fprintf(stderr,"%s loaded\n",tmp->value);
+  }
+#endif
+
+  if (cls != NULL) {
+#ifdef JAVA7
+    (*env).ExceptionClear();
+    pmid=(*env).GetStaticMethodID(cls, s->name, "(Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;)I");
+#else
+    (*env)->ExceptionClear(env);
+    pmid=(*env)->GetStaticMethodID(env,cls_gr, s->name, "(Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;)I");
+#endif
+    if (pmid!=0){
+#ifdef DEBUG
+      fprintf(stderr,"Function successfully loaded\n");
+#endif
+      jclass scHashMapClass,scHashMap_class;
+      jmethodID scHashMap_constructor;
+#ifdef JAVA7
+      scHashMapClass = (*env).FindClass("java/util/HashMap");
+      scHashMap_class = (jclass)(*env).NewGlobalRef(scHashMapClass);
+      scHashMap_constructor = (*env).GetMethodID(scHashMap_class, "<init>", "()V");
+#else
+      scHashMapClass = (*env)->FindClass(env, "java/util/HashMap");
+      scHashMap_class = (*env)->NewGlobalRef(env, scHashMapClass);
+      scHashMap_constructor = (*env)->GetMethodID(env, scHashMap_class, "<init>", "()V");
+#endif
+      /**
+       * The 3 standard parameter for each services
+       */
+      jobject arg1=HashMap_FromMaps(env,m,scHashMapClass,scHashMap_class,scHashMap_constructor);
+      jobject arg2=HashMap_FromMaps(env,inputs,scHashMapClass,scHashMap_class,scHashMap_constructor);
+      jobject arg3=HashMap_FromMaps(env,outputs,scHashMapClass,scHashMap_class,scHashMap_constructor);
+      jint pValue=0;
+
+#ifdef JAVA7
+      pValue=(*env).CallStaticIntMethod(cls,pmid,arg1,arg2,arg3);
+#else
+      pValue=(*env)->CallStaticIntMethod(env,cls,pmid,arg1,arg2,arg3);
+#endif
+      if (pValue != (jint)NULL){
+	res=pValue;
+	m=mapsFromHashMap(env,arg1,scHashMapClass);
+	*main_conf=m;
+	outputs=mapsFromHashMap(env,arg3,scHashMapClass);
+	*real_outputs=outputs;
+
+#ifdef DEBUG
+	fprintf(stderr,"Result of call: %i\n", pValue);
+	dumpMaps(inputs);
+	dumpMaps(outputs);
+#endif
+      }else{
+	displayStack(env,*main_conf);
+#ifdef JAVA7
+	(*jvm).DestroyJavaVM();
+#else
+	(*jvm)->DestroyJavaVM(jvm);
+#endif
+	return -1;
+      }
+    }
+    else{
+      displayStack(env,*main_conf);
+#ifdef JAVA7
+      (*jvm).DestroyJavaVM();
+#else
+      (*jvm)->DestroyJavaVM(jvm);
+#endif
+      return -1;
+    }
+  }
+#ifdef JAVA7
+      (*jvm).DestroyJavaVM();
+#else
+  (*jvm)->DestroyJavaVM(jvm);
+#endif
+  return res;
+}
+
+/**
+ * Error handling: display stack trace in an ExceptionReport Document
+ *
+ * @param env the JNI environment pointer
+ * @param main_conf the conf maps containing the main.cfg settings
+ */
+void displayStack(JNIEnv *env,maps* main_conf){
+  map *tmpm=getMapFromMaps(main_conf,"main","tmpPath");
+  char tmps[1024];
+  sprintf(tmps,"%s/%d.ztmp",tmpm->value,getpid());
+  FILE* new_stdout=fopen(tmps,"wb+");
+  if(new_stdout==NULL){
+    map* err=createMap("text","Unable to run your service, no debug informations can be provided (please verify privileges on tmpPath)");
+    addToMap(err,"code","InternalError");
+    printExceptionReportResponse(main_conf,err);
+    freeMap(&err);
+    free(err);
+    return;
+  }
+  fflush(stderr);
+  dup2(fileno(new_stdout),fileno(stderr));
+  fprintf(stderr,"Unable to run your java process properly: ");
+  fflush(stderr);
+#ifdef JAVA7
+  (*env).ExceptionDescribe();
+#else
+  (*env)->ExceptionDescribe(env);
+#endif
+  fflush(new_stdout);
+  fseek(new_stdout, 0, SEEK_END);
+  long flen=ftell(new_stdout);
+  fseek(new_stdout, 0, SEEK_SET);
+  char *tmps1=(char*)malloc((flen+1)*sizeof(char));
+  fread(tmps1,flen,1,new_stdout);
+  fclose(new_stdout);
+  tmps1[flen]=0;
+  map* err=createMap("text",tmps1);
+  addToMap(err,"code","InternalError");
+  printExceptionReportResponse(main_conf,err);
+  freeMap(&err);
+  free(err);
+}
+
+/**
+ * Create a string containing the JVM -XX:* option for a given map
+ * Depending on the map' name:
+ *  - in case the value is minus then the result will be : -XX:-name
+ *  - in case the value is plus then the result will be : -XX:+name
+ *  - in other cases the result will be : -XX:name=value
+ *
+ * @param m the map containing the option
+ * @return a char* containing the valide JVM option (-XX:*)
+ */
+char *parseJVMXXOption(map* m){
+  char *res=(char*)malloc((strlen(m->name)+strlen(m->value)+5)*sizeof(char));
+  if(strncasecmp(m->value,"minus",5)==0)
+    sprintf(res,"-XX:-%s",m->name);
+  else if(strncasecmp(m->value,"plus",5)==0)
+    sprintf(res,"-XX:+%s",m->name);
+  else
+    sprintf(res,"-XX:%s=%s",m->name,m->value);
+  return res;
+}
+
+/**
+ * Create a string containing the JVM -X** option for a given map.
+ * The result will be in the following format: -Xnamevalue
+ *
+ * @param m the map containing the option
+ * @return a char* containing the valide JVM option (-X**)
+ */
+char *parseJVMXOption(map* m){
+  char *res=(char*)malloc((strlen(m->name)+strlen(m->value)+5)*sizeof(char));
+  sprintf(res,"-X%s%s",m->name,m->value);
+  return res;
+}
+
+/**
+ * Convert a maps to a JAVA HashMap<String,HashMap<String,String>>
+ *
+ * @param env the JNI environment pointer
+ * @param t the maps to convert
+ * @param scHashMapClass the HashMap class
+ * @param scHashMap_class the HashMap class
+ * @param scHashMap_constructor the pointer to the hashMap constructor method
+ * @return a created JAVA HashMap containing the converted maps
+ * @warning make sure to free ressources returned by this function
+ */
+jobject HashMap_FromMaps(JNIEnv *env,maps* t,jclass scHashMapClass,jclass scHashMap_class,jmethodID scHashMap_constructor){
+  jobject scObject,scObject1;
+  if(scHashMap_constructor!=NULL){
+#ifdef JAVA7
+    scObject = (*env).NewObject(scHashMap_class, scHashMap_constructor);
+#else
+    scObject = (*env)->NewObject(env, scHashMap_class, scHashMap_constructor);
+#endif
+    jmethodID put_mid = 0;
+
+#ifdef JAVA7
+    put_mid = (*env).GetMethodID(scHashMapClass, "put",
+				  "(Ljava/lang/Object;Ljava/lang/Object;)"
+				  "Ljava/lang/Object;");
+#else
+    put_mid = (*env)->GetMethodID(env,scHashMapClass, "put",
+				  "(Ljava/lang/Object;Ljava/lang/Object;)"
+				  "Ljava/lang/Object;");
+#endif
+    maps* tmp=t;
+    while(tmp!=NULL){
+      map* tmap=getMapType(tmp->content);
+      map* tmp1=tmp->content;
+#ifdef JAVA7
+      scObject1 = (*env).NewObject(scHashMap_class, scHashMap_constructor);
+#else
+      scObject1 = (*env)->NewObject(env, scHashMap_class, scHashMap_constructor);
+#endif
+      map* sizeV=getMap(tmp1,"size");
+      map* isArray=getMap(tmp1,"isArray");
+      map* alen=getMap(tmp1,"length");
+      while(tmp1!=NULL){
+	if(strcmp(tmp1->name,"value")==0){
+	  if(isArray==NULL){
+	    if(sizeV!=NULL && strcmp(tmp1->name,"value")==0){
+#ifdef JAVA7
+	      jbyteArray tmpData=(*env).NewByteArray(atoi(sizeV->value));
+	      (*env).SetByteArrayRegion(tmpData,0,atoi(sizeV->value),(const jbyte *)tmp1->value);
+	      (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), tmpData);
+#else
+	      jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sizeV->value));
+	      (*env)->SetByteArrayRegion(env,tmpData,0,atoi(sizeV->value),tmp1->value);
+	      (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), tmpData);
+#endif
+	    }else
+#ifdef JAVA7
+	      (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), (*env).NewStringUTF(tmp1->value));
+#else
+	      (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
+#endif
+	  }
+	  else{
+	    int alen1=atoi(alen->value);
+	    fprintf(stderr,"LENGTH %d \n",alen1);
+	    
+	    jclass scArrayListClass,scArrayList_class;
+	    jmethodID scArrayList_constructor;
+	    jobject scObject2;
+#ifdef JAVA7
+	    scArrayListClass = (*env).FindClass("java/util/ArrayList");
+	    scArrayList_class = (jclass)(*env).NewGlobalRef(scArrayListClass);
+	    scArrayList_constructor = (*env).GetMethodID(scArrayList_class, "<init>", "()V");
+	    jmethodID add_mid = 0;
+	    scObject2 = (*env).NewObject(scArrayList_class, scArrayList_constructor);
+
+	    add_mid = (*env).GetMethodID(scArrayListClass,
+					  "add","(Ljava/lang/Object;)Z");
+#else
+	    scArrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
+	    scArrayList_class = (*env)->NewGlobalRef(env, scArrayListClass);
+	    scArrayList_constructor = (*env)->GetMethodID(env, scArrayList_class, "<init>", "()V");
+	    jmethodID add_mid = 0;
+	    scObject2 = (*env)->NewObject(env, scArrayList_class, scArrayList_constructor);
+
+	    add_mid = (*env)->GetMethodID(env,scArrayListClass,
+					  "add","(Ljava/lang/Object;)Z");
+#endif	    
+	    int i;
+	    
+	    for(i=0;i<alen1;i++){
+	      map* vMap=getMapArray(tmp->content,"value",i);	    
+	      map* sMap=getMapArray(tmp->content,"size",i);
+	      map* mMap=getMapArray(tmp->content,tmap->value,i);
+	      
+	      if(sMap!=NULL && vMap!=NULL && strncmp(vMap->name,"value",5)==0){
+#ifdef JAVA7
+		jbyteArray tmpData=(*env).NewByteArray(atoi(sMap->value));
+		(*env).SetByteArrayRegion(tmpData,0,atoi(sMap->value),(const jbyte *)vMap->value);
+		(*env).CallObjectMethod(scObject2, add_mid, tmpData);
+#else
+		jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sMap->value));
+		(*env)->SetByteArrayRegion(env,tmpData,0,atoi(sMap->value),vMap->value);
+		(*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
+#endif
+	      }else{
+#ifdef JAVA7
+		jobject tmpData=(*env).NewStringUTF(vMap->value);
+		(*env).CallObjectMethod(scObject2, add_mid, tmpData);
+#else
+		jobject tmpData=(*env)->NewStringUTF(env,vMap->value);
+		(*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
+#endif
+	      }
+	      
+	    }
+
+#ifdef JAVA7
+	    (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), scObject2);
+#else	    
+	    (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), scObject2);
+#endif
+
+	  }
+	}
+	else
+#ifdef JAVA7
+	  (*env).CallObjectMethod(scObject1, put_mid, (*env).NewStringUTF(tmp1->name), (*env).NewStringUTF(tmp1->value));
+#else
+	  (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
+#endif
+	tmp1=tmp1->next;
+      }
+#ifdef JAVA7
+      (*env).CallObjectMethod(scObject, put_mid, (*env).NewStringUTF(tmp->name), scObject1);
+#else
+      (*env)->CallObjectMethod(env,scObject, put_mid, (*env)->NewStringUTF(env,tmp->name), scObject1);
+#endif
+      tmp=tmp->next;
+    }
+    return scObject;
+  }
+  else
+    return NULL;
+}
+
+/**
+ * Convert a JAVA HashMap<String,HashMap<String,String>> to a maps
+ *
+ * @param env the JNI environment pointer
+ * @param t the HashMap 
+ * @param scHashMapClass the hashMap class
+ * @return a created maps containing the converted HashMap
+ * @warning make sure to free ressources returned by this function
+ */
+maps* mapsFromHashMap(JNIEnv *env,jobject t,jclass scHashMapClass){
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap start\n");
+#endif
+  /**
+   * What need to be done (in java).
+   * Set set = hm.entrySet();
+   * Iterator i = set.iterator();
+   * while(i.hasNext()){
+   *   Map.Entry me = (Map.Entry)i.next();
+   *   System.out.println(me.getKey() + " : " + me.getValue() );
+   * }
+   */
+  jclass scSetClass,scIteratorClass,scMapEntryClass;
+  jmethodID entrySet_mid,containsKey_mid,get_mid,iterator_mid,hasNext_mid,next_mid,getKey_mid,getValue_mid;
+  if(scHashMapClass==NULL){
+#ifdef DEBUG
+    fprintf(stderr,"Unable to load java.util.HashMap\n");
+#endif
+    return NULL;
+  }
+#ifdef JAVA7
+  entrySet_mid = (*env).GetMethodID(scHashMapClass, "entrySet", "()Ljava/util/Set;"); 
+  containsKey_mid = (*env).GetMethodID(scHashMapClass, "containsKey", "(Ljava/lang/Object;)Z");
+  get_mid = (*env).GetMethodID(scHashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); 
+#else
+  entrySet_mid = (*env)->GetMethodID(env, scHashMapClass, "entrySet", "()Ljava/util/Set;"); 
+  containsKey_mid = (*env)->GetMethodID(env, scHashMapClass, "containsKey", "(Ljava/lang/Object;)Z");
+  get_mid = (*env)->GetMethodID(env, scHashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); 
+#endif
+
+  if(containsKey_mid==0){
+#ifdef DEBUG
+    fprintf(stderr,"unable to load containsKey from HashMap object (%d) \n",entrySet_mid);
+#endif
+    return NULL;
+  }
+  if(get_mid==0){
+#ifdef DEBUG
+    fprintf(stderr,"unable to load get from HashMap object (%d) \n",entrySet_mid);
+#endif
+    return NULL;
+  }
+  if(entrySet_mid==0){
+#ifdef DEBUG
+    fprintf(stderr,"unable to load entrySet from HashMap object (%d) \n",entrySet_mid);
+#endif
+    return NULL;
+  }
+#ifdef DEBUG
+  else
+    fprintf(stderr,"entrySet loaded from HashMap object (%d) \n",entrySet_mid);
+#endif
+
+#ifdef JAVA7
+  scSetClass = (*env).FindClass("java/util/Set");
+  iterator_mid = (*env).GetMethodID(scSetClass, "iterator", "()Ljava/util/Iterator;"); 
+#else
+  scSetClass = (*env)->FindClass(env, "java/util/Set");
+  iterator_mid = (*env)->GetMethodID(env, scSetClass, "iterator", "()Ljava/util/Iterator;"); 
+#endif
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap 1 (%d) \n",iterator_mid);
+#endif
+
+#ifdef JAVA7
+  scIteratorClass = (*env).FindClass("java/util/Iterator");
+  hasNext_mid = (*env).GetMethodID(scIteratorClass, "hasNext", "()Z");
+#else
+  scIteratorClass = (*env)->FindClass(env, "java/util/Iterator");
+  hasNext_mid = (*env)->GetMethodID(env, scIteratorClass, "hasNext", "()Z");
+#endif
+
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap 2 (%d)\n",hasNext_mid);
+#endif
+
+#ifdef JAVA7
+  next_mid = (*env).GetMethodID(scIteratorClass, "next", "()Ljava/lang/Object;");
+#else
+  next_mid = (*env)->GetMethodID(env, scIteratorClass, "next", "()Ljava/lang/Object;");
+#endif
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap 3 (%d)\n",next_mid);
+#endif
+
+#ifdef JAVA7
+  scMapEntryClass = (*env).FindClass("java/util/Map$Entry");
+  getKey_mid = (*env).GetMethodID(scMapEntryClass, "getKey", "()Ljava/lang/Object;");
+#else
+  scMapEntryClass = (*env)->FindClass(env, "java/util/Map$Entry");
+  getKey_mid = (*env)->GetMethodID(env, scMapEntryClass, "getKey", "()Ljava/lang/Object;");
+#endif
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap 4 (%d)\n",getKey_mid);
+#endif
+#ifdef JAVA7
+  getValue_mid = (*env).GetMethodID(scMapEntryClass, "getValue", "()Ljava/lang/Object;");
+#else
+  getValue_mid = (*env)->GetMethodID(env, scMapEntryClass, "getValue", "()Ljava/lang/Object;");
+#endif
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap 5 (%d)\n",getValue_mid);
+#endif
+
+#ifdef JAVA7
+  jobject final_set=(*env).CallObjectMethod(t,entrySet_mid);
+  jobject final_iterator=(*env).CallObjectMethod(final_set,iterator_mid);
+#else
+  jobject final_set=(*env)->CallObjectMethod(env,t,entrySet_mid);
+  jobject final_iterator=(*env)->CallObjectMethod(env,final_set,iterator_mid);
+#endif
+
+  maps* final_res=NULL;
+  map* res=NULL;
+#ifdef JAVA7
+  while((*env).CallBooleanMethod(final_iterator,hasNext_mid)){
+    jobject tmp=(*env).CallObjectMethod(final_iterator,next_mid);
+
+    jobject imap=(*env).CallObjectMethod(tmp,getValue_mid);
+    jobject set=(*env).CallObjectMethod(imap,entrySet_mid);
+    jobject iterator=(*env).CallObjectMethod(set,iterator_mid);
+
+#else
+  while((*env)->CallBooleanMethod(env,final_iterator,hasNext_mid)){
+    jobject tmp=(*env)->CallObjectMethod(env,final_iterator,next_mid);
+
+    jobject imap=(*env)->CallObjectMethod(env,tmp,getValue_mid);
+    jobject set=(*env)->CallObjectMethod(env,imap,entrySet_mid);
+    jobject iterator=(*env)->CallObjectMethod(env,set,iterator_mid);
+
+#endif
+    int size=-1;
+#ifdef JAVA7
+    if((*env).CallBooleanMethod(imap,containsKey_mid,(*env).NewStringUTF("size"))){
+      jobject sizeV=(*env).CallObjectMethod(imap, get_mid,(*env).NewStringUTF("size"));
+      const char* sizeVS=(*env).GetStringUTFChars((jstring)sizeV, NULL);
+#else
+    if((*env)->CallBooleanMethod(env,imap,containsKey_mid,(*env)->NewStringUTF(env,"size"))){
+      jobject sizeV=(*env)->CallObjectMethod(env, imap, get_mid,(*env)->NewStringUTF(env,"size"));
+      const char* sizeVS=(*env)->GetStringUTFChars(env, sizeV, NULL);
+#endif
+      size=atoi(sizeVS);
+      fprintf(stderr,"SIZE : %s\n",sizeVS);
+#ifdef JAVA7
+      (*env).ReleaseStringUTFChars((jstring)sizeV, sizeVS);
+#else
+      (*env)->ReleaseStringUTFChars(env, sizeV, sizeVS);
+#endif
+    }
+    
+#ifdef JAVA7
+    while((*env).CallBooleanMethod(iterator,hasNext_mid)){
+      jobject tmp1=(*env).CallObjectMethod(iterator,next_mid);
+      jobject jk=(*env).CallObjectMethod(tmp1,getKey_mid);
+      jobject jv=(*env).CallObjectMethod(tmp1,getValue_mid);
+
+      const char* jkd=(*env).GetStringUTFChars((jstring)jk, NULL);
+#else
+    while((*env)->CallBooleanMethod(env,iterator,hasNext_mid)){
+      jobject tmp1=(*env)->CallObjectMethod(env,iterator,next_mid);
+      jobject jk=(*env)->CallObjectMethod(env,tmp1,getKey_mid);
+      jobject jv=(*env)->CallObjectMethod(env,tmp1,getValue_mid);
+
+      const char* jkd=(*env)->GetStringUTFChars(env, jk, NULL);
+#endif
+      if(size>=0 && strcmp(jkd,"value")==0){
+#ifdef JAVA7
+	jobject value=(jobject)(*env).GetByteArrayElements((jbyteArray)jv, NULL);
+#else
+	jobject value=(*env)->GetByteArrayElements(env, jv, NULL);
+#endif
+	if(res==NULL){
+	  res=createMap(jkd,"");
+	}else{
+	  addToMap(res,jkd,"");
+	}
+	map* tmpR=getMap(res,"value");
+	free(tmpR->value);
+	tmpR->value=(char*)malloc((size+1)*sizeof(char));
+	memmove(tmpR->value,value,size*sizeof(char));
+	tmpR->value[size]=0;
+	char tmp[128];
+	sprintf(tmp,"%d",size);
+	addToMap(res,"size",tmp);
+      }
+      else{
+#ifdef JAVA7
+	const char* jvd=(*env).GetStringUTFChars((jstring)jv, NULL);
+#else
+	const char* jvd=(*env)->GetStringUTFChars(env, jv, NULL);
+#endif
+	if(res==NULL){
+	  res=createMap(jkd,jvd);
+	}else{
+	  addToMap(res,jkd,jvd);
+	}
+#ifdef JAVA7
+	(*env).ReleaseStringUTFChars((jstring)jv, jvd);
+#else
+	(*env)->ReleaseStringUTFChars(env, jv, jvd);
+#endif
+      }
+
+#ifdef JAVA7
+      (*env).ReleaseStringUTFChars((jstring)jk, jkd);
+#else
+      (*env)->ReleaseStringUTFChars(env, jk, jkd);
+#endif
+
+    }
+#ifdef JAVA7
+    jobject jk=(*env).CallObjectMethod(tmp,getKey_mid);
+#else
+    jobject jk=(*env)->CallObjectMethod(env,tmp,getKey_mid);
+#endif
+    maps* cmap=(maps*)malloc(sizeof(maps));
+#ifdef JAVA7
+    cmap->name=(char*)(*env).GetStringUTFChars((jstring)jk, NULL);
+#else
+    cmap->name=(*env)->GetStringUTFChars(env, jk, NULL);
+#endif
+#ifdef DEBUG
+    fprintf(stderr," / %s \n",cmap->name);
+#endif
+    cmap->content=res;
+    cmap->next=NULL;
+    if(final_res==NULL)
+      final_res=dupMaps(&cmap);
+    else
+      addMapsToMaps(&final_res,cmap);
+    freeMaps(&cmap);
+    free(cmap);
+    cmap=NULL;
+    res=NULL;
+  }
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromHashMap end\n");
+#endif
+
+  return final_res;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_java.h	(revision 672)
@@ -0,0 +1,52 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_JAVA_H
+#define ZOO_SERVICE_INTERNAL_JAVA_H 1
+
+#pragma once 
+
+#include "service.h"
+#include "service_internal.h"
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  jobject HashMap_FromMaps(JNIEnv*,maps*,jclass,jclass,jmethodID);
+  
+  maps* mapsFromHashMap(JNIEnv*,jobject,jclass);
+  
+  void displayStack(JNIEnv*,maps*);
+
+  char *parseJVMXXOption(map*);
+
+  char *parseJVMXOption(map*);
+
+  int zoo_java_support(maps**,map*,service*,maps**,maps**);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.c	(revision 672)
@@ -0,0 +1,985 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2012 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service_internal_js.h"
+#include "response_print.h"
+
+#ifndef JSCLASS_GLOBAL_FLAGS
+#define JSCLSAS_GLOBAL_FLAGS 0
+#endif
+
+static char dbg[1024];
+
+/**
+ * The function used as alert from the JavaScript environment (ZOO-API)
+ *
+ * @param cx the JavaScript context
+ * @param argc the number of parameters
+ * @param argv1 the parameter values
+ * @return true
+ */
+JSBool
+JSAlert(JSContext *cx, uintN argc, jsval *argv1)
+{
+  jsval *argv = JS_ARGV(cx,argv1);
+  int i=0;
+  JS_MaybeGC(cx);
+  for(i=0;i<argc;i++){
+    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
+    char *tmp=JS_EncodeString(cx,jsmsg);
+    fprintf(stderr,"[ZOO-API:JS] %s\n",tmp);
+    free(tmp);
+  }
+  JS_MaybeGC(cx);
+  
+  return JS_TRUE;
+}
+
+/**
+ * The function used as importScript from the JavaScript environment (ZOO-API)
+ * 
+ * @param cx the JavaScript context
+ * @param argc the number of parameters
+ * @param argv1 the parameter values
+ * @return true
+ */
+JSBool 
+JSLoadScripts(JSContext *cx, uintN argc, jsval *argv1)
+{
+  JS_MaybeGC(cx);
+
+  char ntmp[1024];
+  getcwd(ntmp,1024);
+
+  jsval *argv = JS_ARGV(cx,argv1);
+  int i=0;
+  JS_MaybeGC(cx);
+  for(i=0;i<argc;i++){
+    char *filename = JSValToChar(cx,&argv[i]);
+    char *api0=(char*)malloc((strlen(ntmp)+strlen(filename)+2)*sizeof(char));
+    sprintf(api0,"%s/%s",ntmp,filename);
+#ifdef JS_DEBUG
+    fprintf(stderr,"Trying to load %s\n",api0);
+    fflush(stderr);
+#endif
+    JSObject *api_script1=loadZooApiFile(cx,JS_GetGlobalObject(cx),api0);
+    free(api0);
+  }
+  JS_MaybeGC(cx);
+  JS_SET_RVAL(cx, argv1, JSVAL_VOID);
+  
+  return JS_TRUE;
+}
+
+/**
+ * Load a JavaScript file then run the function corresponding to the service by
+ * passing the conf, inputs and outputs parameters by value as JavaScript
+ * Objects.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param inputs the maps containing the inputs
+ * @param outputs the maps containing the outputs
+ * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1 
+ *  if the service failed to load or throw error at runtime.
+ */
+int zoo_js_support(maps** main_conf,map* request,service* s,maps **inputs,maps **outputs)
+{
+  /*maps* main=*main_conf;
+  maps* _inputs=*inputs;
+  maps* _outputs=*outputs;*/
+
+  /* The class of the global object. */
+  JSClass global_class= {
+    "global", JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+  };
+
+  /* JS variables. */
+  JSRuntime *rt;
+  JSContext *cx;
+  JSObject  *global;
+
+  /* Create a JS runtime. */
+  rt = JS_NewRuntime(8L * 1024L * 1024L);
+  if (rt == NULL)
+    return 1;
+  
+  /* Create a context. */
+  cx = JS_NewContext(rt,8192);
+  if (cx == NULL){
+    return 1;
+  }
+  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
+  JS_SetVersion(cx, JSVERSION_LATEST);
+  JS_SetErrorReporter(cx, reportError);
+
+  /* Create the global object. */
+  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
+
+  /* Populate the global object with the standard globals,
+     like Object and Array. */
+  if (!JS_InitStandardClasses(cx, global)){
+    return 1;
+  }
+
+  /* Define specific function and global variable to share with JS runtime
+   */
+  jsval tmp=INT_TO_JSVAL(3);
+  if (!JS_SetProperty(cx, global, "SERVICE_SUCCEEDED", &tmp))
+    return 1;
+  tmp=INT_TO_JSVAL(4);
+  if (!JS_SetProperty(cx, global, "SERVICE_FAILED", &tmp))
+    return 1;
+  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
+    return 1;
+  if (!JS_DefineFunction(cx, global, "ZOOTranslate", JSTranslate, 4, 0))
+    return 1;
+  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
+    return 1;
+  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
+    return 1;  
+  if (!JS_DefineFunction(cx, global, "importScripts", JSLoadScripts, 1, 0))
+    return 1;
+
+  /**
+   * Add private context object
+   */
+  void* cxPrivate = request;
+  JS_SetContextPrivate(cx,cxPrivate);
+
+  map* tmpm1=getMap(request,"metapath");
+  char ntmp[1024];
+  getcwd(ntmp,1024);
+
+  /**
+   * Load the first part of the ZOO-API
+   */
+  char *api0=(char*)malloc((strlen(ntmp)+17)*sizeof(char));
+  sprintf(api0,"%s/ZOO-proj4js.js",ntmp);
+#ifdef JS_DEBUG
+  fprintf(stderr,"Trying to load %s\n",api0);
+#endif
+  JSObject *api_script1=loadZooApiFile(cx,global,api0);
+  free(api0);
+  fflush(stderr);
+
+  char *api1=(char*)malloc((strlen(ntmp)+13)*sizeof(char));
+  sprintf(api1,"%s/ZOO-api.js",ntmp);
+#ifdef JS_DEBUG
+  fprintf(stderr,"Trying to load %s\n",api1);
+#endif
+  JSObject *api_script2=loadZooApiFile(cx,global,api1);
+  free(api1);
+  fflush(stderr);
+
+  /* Your application code here. This may include JSAPI calls
+     to create your own custom JS objects and run scripts. */
+  //maps* out=*outputs;
+  int res=SERVICE_FAILED;
+  //maps* mc=*main_conf;
+  map* tmpm2=getMap(s->content,"serviceProvider");
+
+  char *filename=(char*)malloc(strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3);
+  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
+  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
+#ifdef JS_DEBUG
+  fprintf(stderr,"FILENAME %s\n",filename);
+#endif
+  struct stat file_status;
+  stat(filename, &file_status);
+  //char *source=(char*)malloc(file_status.st_size);
+  //uint16 lineno;
+  jsval rval;
+  JSBool ok ;
+  JSObject *script = JS_CompileFile(cx, global, filename);
+  if(script!=NULL){
+    (void)JS_ExecuteScript(cx, global, script, &rval);
+  }
+  else{
+    char tmp1[1024];
+    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
+    free(filename);
+    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
+    JS_MaybeGC(cx);
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+    return -1;
+  }
+  
+
+  /* Call a function in obj's scope. */
+  jsval argv[3];
+  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
+  argv[0] = OBJECT_TO_JSVAL(jsargv1);
+  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
+  argv[1] = OBJECT_TO_JSVAL(jsargv2);
+  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
+  argv[2] = OBJECT_TO_JSVAL(jsargv3);
+  jsval rval1=JSVAL_NULL;
+#ifdef JS_DEBUG
+  fprintf(stderr, "object %p\n", (void *) argv[2]);
+#endif
+
+  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
+
+#ifdef JS_DEBUG
+  fprintf(stderr, "object %p\n", (void *) argv[2]);
+#endif
+
+  JSObject *d;
+  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
+#ifdef JS_DEBUG
+    fprintf(stderr,"Function run sucessfully !\n");
+#endif
+    /* Should get a number back from the service function call. */
+    ok = JS_ValueToObject(cx, rval1, &d);
+  }else{
+    /* Unable to run JS function */
+    char tmp1[1024];
+    if(strlen(dbg)==0)
+      sprintf(dbg,"No result was found after the function call");
+    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
+#ifdef JS_DEBUG
+    fprintf(stderr,"%s",tmp1);
+#endif
+    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
+    free(filename);
+    JS_MaybeGC(cx);
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
+    return -1;
+  }
+
+  //jsval t=OBJECT_TO_JSVAL(d);
+  if(JS_IsArrayObject(cx,d)){
+#ifdef JS_DEBUG
+    fprintf(stderr,"An array was returned !\n");
+#endif
+    jsuint	 len;
+    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
+#ifdef JS_DEBUG
+      fprintf(stderr,"outputs array is empty\n");
+#endif
+    }
+    jsval tmp1;
+    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
+    res=JSVAL_TO_INT(tmp1);
+#ifdef JS_DEBUG
+    fprintf(stderr," * %d * \n",res);
+#endif
+    if(res==SERVICE_SUCCEEDED){
+      jsval tmp2;
+      JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
+      if(hasElement==JS_TRUE){
+	freeMaps(outputs);
+	free(*outputs);
+	*outputs=mapsFromJSObject(cx,tmp2);
+      }
+    }else{
+      jsval tmp3;
+      JSBool hasConf=JS_GetElement(cx,d,1,&tmp3);
+      if(hasConf==JS_TRUE){
+	freeMaps(main_conf);
+	free(*main_conf);
+	*main_conf=mapsFromJSObject(cx,tmp3);
+      }
+    }
+
+  }
+  else{
+#ifdef JS_DEBUG
+    fprintf(stderr,"The service didn't return an array !\n");
+#endif
+    /**
+     * Extract result
+     */
+    jsval tmp1;
+    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
+    res=JSVAL_TO_INT(tmp1);
+
+#ifdef JS_DEBUG
+    fprintf(stderr," * %d * \n",res);
+#endif
+    /**
+     * Extract outputs when available.
+     */
+    jsval tmp2;
+    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
+    if(!JSVAL_IS_VOID(tmp2) && hasElement==JS_TRUE){
+      freeMaps(outputs);
+      free(*outputs);    
+      *outputs=mapsFromJSObject(cx,tmp2);
+    }
+    JS_MaybeGC(cx);
+#ifdef JS_DEBUG
+    if(JSVAL_IS_VOID(tmp2))
+      fprintf(stderr,"No outputs property returned\n");
+    else{
+      if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
+	fprintf(stderr,"outputs is an array as expected\n");
+      else
+	fprintf(stderr,"outputs is not an array as expected\n");
+    }
+    JS_MaybeGC(cx);
+#endif
+
+    /**
+     * Extract conf when available.
+     */
+    jsval tmp3;
+    JSBool hasConf=JS_GetProperty(cx,d,"conf",&tmp3);
+    if(!JSVAL_IS_VOID(tmp3) && hasConf==JS_TRUE){
+      freeMaps(main_conf);
+      free(*main_conf);
+      *main_conf=mapsFromJSObject(cx,tmp3);
+    }
+    JS_MaybeGC(cx);
+
+#ifdef JS_DEBUG
+    dumpMaps(*outputs);
+#endif
+  }
+  /* Cleanup. */
+  JS_MaybeGC(cx);
+  JS_DestroyContext(cx);
+  JS_DestroyRuntime(rt);
+  JS_ShutDown();
+  free(filename);
+#ifdef JS_DEBUG
+  fprintf(stderr,"Returned value %d\n",res);
+#endif
+  return res;
+}
+
+/**
+ * Load a JavaScript file
+ *
+ * @param cx the JavaScript context
+ * @param global the global JavaScript object (not used)
+ * @param filename the file name to load
+ * @return a JavaScript Object on success, NULL if an errro occured
+ */
+JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
+  struct stat api_status;
+  int s=stat(filename, &api_status);
+  if(s==0){
+    jsval rval;
+    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
+    if(script!=NULL){
+      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
+#ifdef JS_DEBUG
+      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
+#endif
+      return script;
+    }
+#ifdef JS_DEBUG
+    else
+      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
+#endif
+  }
+#ifdef JS_DEBUG
+  else
+    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
+#endif
+  return NULL;
+}
+
+/**
+ * Convert a maps to a JavaScript Object
+ *
+ * @param cx the JavaScript context
+ * @param t the maps to convert
+ * @return a new JavaScript Object
+ */
+JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
+  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
+  if(res==NULL)
+    fprintf(stderr,"Array Object is NULL!\n");
+  maps* tmp=t;
+  while(tmp!=NULL){
+    JSObject *pval=JSObject_FromMap(cx,tmp->content);
+    jsval pvalj=OBJECT_TO_JSVAL(pval);
+    JS_SetProperty(cx, res, tmp->name, &pvalj);
+#ifdef JS_DEBUG
+    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
+#endif
+    tmp=tmp->next;
+  }  
+  return res;
+}
+
+/**
+ * Convert a map to a JavaScript Object
+ *
+ * @param cx the JavaScript context
+ * @param t the map to convert
+ * @return a new JavaScript Object
+ */
+JSObject* JSObject_FromMap(JSContext *cx,map* t){
+  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
+  map* tmpm=t;
+  map* isArray=getMap(t,"isArray");
+  map* isBinary=getMap(t,"size");
+  map* tmap=getMapType(t);
+#ifdef JS_DEBUG
+  if(tmap==NULL)
+    fprintf(stderr,"tmap is null !\n");
+  else
+    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
+#endif
+  while(isArray==NULL && tmpm!=NULL){
+    jsval jsstr;
+    if((isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0))
+      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
+    else
+      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
+    JS_SetProperty(cx, res, tmpm->name,&jsstr);
+#ifdef JS_DEBUG
+    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
+#endif
+    tmpm=tmpm->next;
+  }
+  if(isArray!=NULL){
+    map* len=getMap(t,"length");
+    int cnt=atoi(len->value);
+    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
+    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
+    map *tmpm1,*tmpm2;
+    int i=0;
+    for(i=0;i<cnt;i++){
+      tmpm1=getMapArray(t,"value",i);
+      tmpm2=getMapArray(t,tmap->name,i);
+      if(tmpm1!=NULL){
+	jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
+	JS_SetElement( cx, values, i, &jsstr );
+      }
+      if(tmpm2!=NULL){
+	jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
+	JS_SetElement( cx, mvalues, i, &jsstr );
+      }
+    }
+    jsval jvalues=OBJECT_TO_JSVAL(values);
+    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
+    JS_SetProperty(cx, res,"value",&jvalues);
+    JS_SetProperty(cx, res,tmap->name,&jmvalues);
+  }
+  return res;
+}
+
+/**
+ * Convert a JavaScript Object to a maps
+ *
+ * @param cx the JavaScript context
+ * @param t the JavaScript Object to convert
+ * @return a new maps containing the JavaScript Object
+ */
+maps* mapsFromJSObject(JSContext *cx,jsval t){
+  maps *res=NULL;
+  maps *tres=NULL;
+  jsint oi=0;
+  JSObject* tt=JSVAL_TO_OBJECT(t);
+  if(JS_IsArrayObject(cx,tt)){
+#ifdef JS_DEBUG
+    fprintf(stderr,"Is finally an array !\n");
+#endif
+  }
+  else{
+#ifdef JS_DEBUG
+    fprintf(stderr,"Is not an array !\n");
+#endif
+    JSIdArray *idp=JS_Enumerate(cx,tt);
+    if(idp!=NULL) {
+      int index;
+      jsdouble argNum;
+#ifdef JS_DEBUG
+      fprintf(stderr,"Properties length :  %d \n",idp->length);
+#endif
+      
+      for (index=0,argNum=idp->length;index<argNum;index++) { 
+	jsval id = idp->vector[index];
+	jsval vp;
+	JS_IdToValue(cx,id,&vp);
+	char *tmp;
+	JSString *jsmsg;
+	size_t len1;
+	jsmsg = JS_ValueToString(cx,vp);
+	len1 = JS_GetStringLength(jsmsg);
+	
+	tmp=JS_EncodeString(cx,jsmsg);
+	tres=(maps*)malloc(MAPS_SIZE);
+	tres->name=zStrdup(tmp);
+	tres->content=NULL;
+	tres->next=NULL;
+
+	jsval nvp=JSVAL_NULL;
+	if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
+#ifdef JS_DEBUG
+	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
+#endif
+	}
+	free(tmp);
+	JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
+	JS_ValueToObject(cx,nvp,&nvp1);
+	jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
+	if(JSVAL_IS_OBJECT(nvp1j)){
+	  tres->content=mapFromJSObject(cx,nvp1j);
+	}
+
+	if(res==NULL)
+	  res=dupMaps(&tres);
+	else
+	  addMapsToMaps(&res,tres);
+	freeMaps(&tres);
+	free(tres);
+	tres=NULL;
+		
+      }
+      JS_DestroyIdArray(cx,idp);
+    }
+  }
+
+  jsuint len;
+  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
+#ifdef JS_DEBUG
+  if(hasLen==JS_FALSE){
+    fprintf(stderr,"outputs array is empty\n");
+  }
+  fprintf(stderr,"outputs array length : %d\n",len);
+#endif
+  for(oi=0;hasLen && oi < len;oi++){
+#ifdef JS_DEBUG
+    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
+#endif
+    jsval tmp1;
+    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
+    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
+    JSIdArray *idp=JS_Enumerate(cx,otmp1);
+    if(idp!=NULL) {
+      int index;
+      jsdouble argNum;
+#ifdef JS_DEBUG
+      fprintf(stderr,"Properties length :  %d \n",idp->length);
+#endif
+      tres=(maps*)malloc(MAPS_SIZE);
+      tres->name=NULL;
+      tres->content=NULL;
+      tres->next=NULL;
+
+      for (index=0,argNum=idp->length;index<argNum;index++) { 
+	jsval id = idp->vector[index];
+	jsval vp;
+	JS_IdToValue(cx,id,&vp);
+	char *tmp;
+	JSString *jsmsg;
+	size_t len1;
+	jsmsg = JS_ValueToString(cx,vp);
+	len1 = JS_GetStringLength(jsmsg);
+	tmp=JS_EncodeString(cx,jsmsg);
+#ifdef JS_DEBUG
+	fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
+#endif
+	jsval nvp=JSVAL_NULL;
+	if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
+#ifdef JS_DEBUG
+	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
+#endif
+	}
+	free(tmp);
+	if(JSVAL_IS_OBJECT(nvp)){
+#ifdef JS_DEBUG
+	  fprintf(stderr,"JSVAL NVP IS OBJECT\n");
+#endif
+	}
+
+	JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
+	JS_ValueToObject(cx,nvp,&nvp1);
+	jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
+	if(JSVAL_IS_OBJECT(nvp1j)){
+	  JSString *jsmsg1;
+	  char *tmp1, *tmp2;
+	  JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
+	  jsmsg1 = JS_ValueToString(cx,nvp1j);
+	  len1 = JS_GetStringLength(jsmsg1);
+	  tmp1=JS_EncodeString(cx,jsmsg1);
+	  tmp2=JS_EncodeString(cx,jsmsg);
+#ifdef JS_DEBUG
+	  fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
+#endif
+	  if(strcasecmp(tmp1,"[object Object]")==0){
+	    tres->name=zStrdup(tmp2);
+	    tres->content=mapFromJSObject(cx,nvp1j);
+	  }
+	  else
+	    if(strcasecmp(tmp2,"name")==0){
+	      tres->name=zStrdup(tmp1);
+	    }
+	    else{
+	      if(tres->content==NULL)
+		tres->content=createMap(tmp2,tmp1);
+	      else
+		addToMap(tres->content,tmp2,tmp1);
+	    }
+	  free(tmp1);
+	  free(tmp2);
+	}
+#ifdef JS_DEBUG
+	else
+	  fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
+#endif
+      }
+#ifdef JS_DEBUG
+      dumpMaps(tres);
+#endif
+      if(res==NULL)
+	res=dupMaps(&tres);
+      else
+	addMapsToMaps(&res,tres);
+      freeMaps(&tres);
+      free(tres);
+      tres=NULL;
+      JS_DestroyIdArray(cx,idp);
+    }
+  }
+#ifdef JS_DEBUG
+  dumpMaps(res);
+#endif
+  return res;
+}
+
+/**
+ * Convert a JavaScript Object to a map
+ *
+ * @param cx the JavaScript context
+ * @param t the JavaScript Object to convert
+ * @return a new map containing the JavaScript Object
+ */
+map* mapFromJSObject(JSContext *cx,jsval t){
+  map *res=NULL;
+  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
+#ifdef JS_DEBUG
+  fprintf(stderr,"Properties %p\n",(void*)t);
+#endif
+  if(idp!=NULL) {
+    int index;
+    jsdouble argNum;
+#ifdef JS_DEBUG
+    fprintf(stderr,"Properties length :  %d \n",idp->length);
+#endif
+    for (index=0,argNum=idp->length;index<argNum;index++) { 
+      jsval id = idp->vector[index];
+      jsval vp;
+      JS_IdToValue(cx,id,&vp);
+      char *tmp, *tmp1;
+      JSString *jsmsg,*jsmsg1;
+      size_t len,len1;
+      jsmsg = JS_ValueToString(cx,vp);
+      len = JS_GetStringLength(jsmsg);
+      jsval nvp;
+      tmp=JS_EncodeString(cx,jsmsg);
+      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
+      jsmsg1 = JS_ValueToString(cx,nvp);
+      len1 = JS_GetStringLength(jsmsg1);
+      tmp1=JS_EncodeString(cx,jsmsg1);
+#ifdef JS_DEBUG
+      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
+#endif
+      if(res!=NULL){
+#ifdef JS_DEBUG
+	fprintf(stderr,"%s - %s\n",tmp,tmp1);
+#endif
+	addToMap(res,tmp,tmp1);
+      }
+      else{
+	res=createMap(tmp,tmp1);
+	res->next=NULL;
+      }
+      free(tmp);
+      free(tmp1);
+#ifdef JS_DEBUG
+      dumpMap(res);
+#endif
+    }
+    JS_DestroyIdArray(cx,idp);
+  }
+#ifdef JS_DEBUG
+  dumpMap(res);
+#endif
+  return res;
+}
+
+/**
+ * Print debug information messages on stderr
+ *
+ * @param cx the JavaScript context
+ * @param message the error message
+ * @param report the JavaScript Error Report
+ */
+void reportError(JSContext *cx, const char *message, JSErrorReport *report)
+{
+  sprintf(dbg,"%s:%u:%s\n",
+	  report->filename ? report->filename : "<no filename>",
+	  (unsigned int) report->lineno,
+	  message);
+#ifdef JS_DEBUG
+  fprintf(stderr,"%s",dbg);
+#endif
+  fflush(stderr);
+}
+
+/**
+ * Convert a JavaScript value to a char*
+ *
+ * @param context the JavaScript context
+ * @param arg the JavaScript value
+ * @return a new char*
+ * @warning be sure to free the ressources returned by this function
+ */
+char* JSValToChar(JSContext* context, jsval* arg) {
+  char *c;
+  char *tmp;
+  JSString *jsmsg;
+  size_t len;
+  int i;
+  if(!JSVAL_IS_STRING(*arg)) {
+    return NULL;
+  }
+  jsmsg = JS_ValueToString(context,*arg);
+  len = JS_GetStringLength(jsmsg);
+  tmp = JS_EncodeString(context,jsmsg);
+  c = (char*)malloc((len+1)*sizeof(char));
+  c[len] = '\0';
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"%d \n",len);
+#endif
+  for(i = 0;i < len;i++) {
+    c[i] = tmp[i];
+    c[i+1] = 0;
+  }
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"%s \n",c);
+#endif
+  return c;
+}
+
+/**
+ * Set the HTTP header of a request
+ *
+ * @param handle the HINTERNET handle
+ * @param cx the JavaScript context
+ * @param header the JavaScript Array containing the headers to send
+ * @return the HINTERNET handle
+ */
+HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
+  jsuint length=0;
+  jsint i=0;
+  char *tmp1;
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"setHeader\n");
+#endif
+  if(JS_IsArrayObject(cx,header)){
+#ifdef ULINET_DEBUG
+    fprintf(stderr,"header is an array\n");
+#endif
+    JS_GetArrayLength(cx,header,&length);
+#ifdef ULINET_DEBUG
+    fprintf(stderr,"header is an array of %d elements\n",length);
+#endif
+    handle->ihandle[handle->nb].header=NULL;
+    for(i=0;i<length;i++){
+      jsval tmp;
+      JS_GetElement(cx,header,i,&tmp);
+      tmp1=JSValToChar(cx,&tmp);
+#ifdef ULINET_DEBUG
+      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
+      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
+#endif
+      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
+      free(tmp1);
+    }
+  }
+  else{
+    fprintf(stderr,"not an array !!!!!!!\n");
+  }
+  return *handle;
+}
+
+/**
+ * The function used as ZOOTranslate from the JavaScript environment.
+ * Use the ZOO-Services messages translation function from the Python
+ * environment (ZOO-API)
+ *
+ * @param cx the JavaScript context
+ * @param argc the number of parameters
+ * @param argv1 the parameter values
+ * @return true
+ */
+JSBool
+JSTranslate(JSContext *cx, uintN argc, jsval *argv1)
+{
+  jsval *argv = JS_ARGV(cx,argv1);
+  char *str=JSValToChar(cx,&argv[0]);
+  char *tmpValue=_ss(str);
+  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));  
+  JS_MaybeGC(cx);
+  return JS_TRUE;
+}
+
+/**
+ * The function used as ZOORequest from the JavaScript environment (ZOO-API)
+ *
+ * @param cx the JavaScript context
+ * @param argc the number of parameters
+ * @param argv1 the parameter values
+ * @return true
+ * @see setHeader
+ */
+JSBool
+JSRequest(JSContext *cx, uintN argc, jsval *argv1)
+{
+  jsval *argv = JS_ARGV(cx,argv1);
+  HINTERNET hInternet;
+  JSObject *header;
+  char *url;
+  char *method;
+  char* tmpValue;
+  size_t dwRead;
+  JS_MaybeGC(cx);
+  hInternet=InternetOpen("ZooWPSClient\0",
+			 INTERNET_OPEN_TYPE_PRECONFIG,
+			 NULL,NULL, 0);
+  if(!CHECK_INET_HANDLE(hInternet))
+    return JS_FALSE;
+  if(argc>=2){
+    method=JSValToChar(cx,&argv[0]);
+    url=JSValToChar(cx,&argv[1]);
+  }
+  else{
+    method=zStrdup("GET");
+    url=JSValToChar(cx,argv);
+  }
+  hInternet.waitingRequests[hInternet.nb]=strdup(url);
+  if(argc==4){
+    char *body;
+    body=JSValToChar(cx,&argv[2]);
+    header=JSVAL_TO_OBJECT(argv[3]);
+#ifdef ULINET_DEBUG
+    fprintf(stderr,"URL (%s) \nBODY (%s)\n",url,body);
+#endif
+    if(JS_IsArrayObject(cx,header))
+      setHeader(&hInternet,cx,header);
+#ifdef ULINET_DEBUG
+    fprintf(stderr,"BODY (%s)\n",body);
+#endif
+    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
+		    INTERNET_FLAG_NO_CACHE_WRITE,0);    
+    processDownloads(&hInternet);
+    free(body);
+  }else{
+    if(argc==3){
+      char *body=JSValToChar(cx,&argv[2]);
+      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
+		      INTERNET_FLAG_NO_CACHE_WRITE,0);
+      processDownloads(&hInternet);
+      free(body);
+    }else{
+      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
+		      INTERNET_FLAG_NO_CACHE_WRITE,0);
+      processDownloads(&hInternet);
+    }
+  }
+  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
+  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
+#endif
+  if(dwRead==0){
+    JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,"Unable to access the file.",strlen("Unable to access the file."))));
+    return JS_TRUE;
+  }
+
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
+#endif
+  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));
+  free(url);
+  if(argc>=2)
+    free(method);
+  InternetCloseHandle(&hInternet);
+  JS_MaybeGC(cx);
+  return JS_TRUE;
+}
+
+/**
+ * The function used as ZOOUpdateStatus from the JavaScript environment
+ * (ZOO-API).
+ *
+ * @param cx the JavaScript context
+ * @param argc the number of parameters
+ * @param argv1 the parameter values
+ * @return true
+ * @see setHeader,_updateStatus
+ */
+JSBool
+JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
+{
+  jsval *argv = JS_ARGV(cx,argv1);
+  JS_MaybeGC(cx);
+  int istatus=0;
+  char *status=NULL;
+  maps *conf;
+  if(argc>2){
+#ifdef JS_DEBUG
+    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
+#endif
+    return JS_FALSE;
+  }
+  conf=mapsFromJSObject(cx,argv[0]);
+  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
+    char tmpStatus[4];
+    sprintf(tmpStatus,"%i",istatus);
+    tmpStatus[3]=0;
+    status=strdup(tmpStatus);
+  }
+  if(getMapFromMaps(conf,"lenv","status")!=NULL){
+    if(status!=NULL){
+      setMapInMaps(conf,"lenv","status",status);
+      free(status);
+    }
+    else
+      setMapInMaps(conf,"lenv","status","15");
+    _updateStatus(conf);
+  }
+  freeMaps(&conf);
+  free(conf);
+  JS_MaybeGC(cx);
+  return JS_TRUE;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_js.h	(revision 672)
@@ -0,0 +1,62 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_JS_H
+#define ZOO_SERVICE_INTERNAL_JS_H 1
+
+#pragma once 
+#ifdef WIN32
+#include <wchar.h>
+#endif
+#include "service.h"
+#include "service_internal.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "ulinet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  char* JSValToChar(JSContext*, jsval*);
+  JSObject* JSObject_FromMaps(JSContext *,maps*);
+  JSObject* JSObject_FromMap(JSContext *,map*);
+  maps* mapsFromJSObject(JSContext *,jsval);
+  map* mapFromJSObject(JSContext *,jsval);
+  JSBool JSTranslate(JSContext*, uintN, jsval*);
+  JSBool JSRequest(JSContext*, uintN, jsval*);
+  JSBool JSUpdateStatus(JSContext*,uintN,jsval *);
+
+  void reportError(JSContext *cx, const char *message, JSErrorReport *report);
+  
+  int zoo_js_support(maps**,map*,service*,maps **,maps **);
+
+  JSObject *loadZooApiFile(JSContext*,JSObject*,char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.c	(revision 672)
@@ -0,0 +1,1173 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2010-2011 Fondazione Edmund Mach. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * Cross platform definition of layerObj->class
+ */
+#ifndef WIN32
+#define CLASS class
+#else
+#define CLASS _class
+#endif
+#include "service_internal_ms.h"
+#include "server_internal.h"
+#include "response_print.h"
+
+/**
+ * Get a list of configuration keys having a corresponding mandatory ows_*.
+ * Map composed by a main.cfg maps name as key and the corresponding 
+ * MapServer Mafile Metadata name to use
+ * see doc from here :
+ *  - http://mapserver.org/ogc/wms_server.html
+ *  - http://mapserver.org/ogc/wfs_server.html
+ *  - http://mapserver.org/ogc/wcs_server.html
+ *
+ * @return a new map containing a table linking a name of a configuration key
+ * to a corresponding mandatory ows_* keyword (ie. "fees" => "ows_fees").
+ */
+map* getCorrespondance(){
+  map* res=createMap("encoding","ows_encoding");
+  addToMap(res,"abstract","ows_abstract");
+  addToMap(res,"title","ows_title");
+  addToMap(res,"keywords","ows_keywordlist");
+  addToMap(res,"fees","ows_fees");
+  addToMap(res,"accessConstraints","ows_accessconstraints");
+  addToMap(res,"providerName","ows_attribution_title");
+  addToMap(res,"providerSite","ows_service_onlineresource");
+  addToMap(res,"individualName","ows_contactperson");
+  addToMap(res,"positionName","ows_contactposition");
+  addToMap(res,"providerName","ows_contactorganization");
+  addToMap(res,"role","ows_role");
+  addToMap(res,"addressType","ows_addresstype");
+  addToMap(res,"addressCity","ows_city");
+  addToMap(res,"addressDeliveryPoint","ows_address");
+  addToMap(res,"addressPostalCode","ows_postcode");
+  addToMap(res,"addressAdministrativeArea","ows_stateorprovince");
+  addToMap(res,"addressCountry","ows_country");
+  addToMap(res,"phoneVoice","ows_contactvoicetelephone");
+  addToMap(res,"phoneFacsimile","ows_contactfacsimiletelephone");
+  addToMap(res,"addressElectronicMailAddress","ows_contactelectronicmailaddress");
+  // Missing Madatory Informations
+  addToMap(res,"hoursOfService","ows_hoursofservice");
+  addToMap(res,"contactInstructions","ows_contactinstructions");
+  return res;
+}
+
+/**
+ * Add width and height keys to an output maps containing the maximum width
+ * and height for displaying the full data extent.
+ * Restriction to an image having a size of 640x480 (width * height)
+ *
+ * @param output 
+ * @param minx the lower left x coordinate
+ * @param miny the lower left y coordinate
+ * @param maxx the upper right x coordinate
+ * @param maxy the upper right y coordinate
+ */
+void setMapSize(maps* output,double minx,double miny,double maxx,double maxy){
+  double maxWidth=640;
+  double maxHeight=480;
+  double deltaX=maxx-minx;
+  double deltaY=maxy-miny;
+  double qWidth;
+  qWidth=maxWidth/deltaX;
+  double qHeight;
+  qHeight=maxHeight/deltaY;
+#ifdef DEBUGMS
+  fprintf(stderr,"deltaX : %.15f \ndeltaY : %.15f\n",deltaX,deltaY);
+  fprintf(stderr,"qWidth : %.15f \nqHeight : %.15f\n",qWidth,qHeight);
+#endif
+
+  double width=deltaX*qWidth;
+  double height=height=deltaY*qWidth;
+  if(deltaX<deltaY){
+    width=deltaX*qHeight;
+    height=deltaY*qHeight;
+  }
+  if(height<0)
+    height=-height;
+  if(width<0)
+    width=-width;
+  char sWidth[1024];
+  char sHeight[1024];
+  sprintf(sWidth,"%.3f",width);
+  sprintf(sHeight,"%.3f",height);
+#ifdef DEBUGMS
+  fprintf(stderr,"sWidth : %.15f \nsHeight : %.15f\n",sWidth,sHeight);
+#endif
+  if(output!=NULL){
+    addToMap(output->content,"width",sWidth);
+    addToMap(output->content,"height",sHeight);
+  }
+}
+
+/**
+ * Add a Reference key to an output containing the WMFS/WFS/WCS request for
+ * accessing service result
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param tmpI the specific output maps to add the Reference key
+ */
+void setReferenceUrl(maps* m,maps* tmpI){
+  outputMapfile(m,tmpI);
+  map *msUrl=getMapFromMaps(m,"main","mapserverAddress");
+  if(msUrl==NULL){
+    errorException (m, _("Unable to find any mapserverAddress defined in the main.cfg file"),
+		    "InternalError", NULL);
+    exit(-1);
+  }
+  map *msOgcVersion=getMapFromMaps(m,"main","msOgcVersion");
+  map *dataPath=getMapFromMaps(m,"main","dataPath");
+  map *sid=getMapFromMaps(m,"lenv","usid");
+  map* format=getMap(tmpI->content,"mimeType");
+  map* rformat=getMap(tmpI->content,"requestedMimeType");
+  map* width=getMap(tmpI->content,"width");
+  map* height=getMap(tmpI->content,"height");
+  map* protoMap=getMap(tmpI->content,"msOgc");
+  map* versionMap=getMap(tmpI->content,"msOgcVersion");
+  char options[3][5][25]={
+    {"WMS","1.3.0","GetMap","layers=%s","wms_extent"},
+    {"WFS","1.1.0","GetFeature","typename=%s","wcs_extent"},
+    {"WCS","1.1.0","GetCoverage","coverage=%s","wcs_extent"}
+  };
+  int proto=0;
+  if(rformat==NULL){
+    rformat=getMap(tmpI->content,"mimeType");
+  }
+  if(strncasecmp(rformat->value,"text/xml",8)==0)
+    proto=1;
+  if(strncasecmp(rformat->value,"image/tiff",10)==0)
+    proto=2;
+  if(protoMap!=NULL){
+    if(strncasecmp(protoMap->value,"WMS",3)==0)
+      proto=0;
+    else{
+      if(strncasecmp(protoMap->value,"WFS",3)==0)
+	proto=1;
+      else 
+	proto=2;
+    }
+  }
+  char *protoVersion=options[proto][1];
+  if(proto==1){
+    if(msOgcVersion!=NULL)
+      protoVersion=msOgcVersion->value;
+    if(versionMap!=NULL)
+      protoVersion=versionMap->value;
+  }
+
+  map* extent=getMap(tmpI->content,options[proto][4]);
+  map* crs=getMap(tmpI->content,"crs");
+  int hasCRS=1;
+  if(crs==NULL){
+    crs=getMapFromMaps(m,"main","crs");
+    if(crs==NULL){
+      crs=createMap("crs","epsg:4326");
+      hasCRS=0;
+    }
+  }
+  char layers[128];
+  sprintf(layers,options[proto][3],tmpI->name);
+
+  char* webService_url=(char*)malloc((strlen(msUrl->value)+strlen(format->value)+strlen(tmpI->name)+strlen(width->value)+strlen(height->value)+strlen(extent->value)+256)*sizeof(char));
+
+  if(proto>0){
+    sprintf(webService_url,
+	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+  }
+  else{
+    sprintf(webService_url,
+	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&width=%s&height=%s&format=%s&bbox=%s&crs=%s",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    width->value,
+	    height->value,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+  }
+  if(hasCRS==0){
+    freeMap(&crs);
+    free(crs);
+  }
+  addToMap(tmpI->content,"Reference",webService_url);
+  free(webService_url);
+}
+
+/**
+ * Set projection for a layer in a MAPFILE using Authority Code and Name if
+ * available or fallback to proj4 definition if available or fallback to
+ * default EPSG:4326
+ *
+ * @param output the output maps
+ * @param m the opened mapObj
+ * @param myLayer the layerObj
+ * @param pszProjection a char* containing the SRS definition in WKT format
+ */
+void setSrsInformations(maps* output,mapObj* m,layerObj* myLayer,
+			char* pszProjection){
+  OGRSpatialReferenceH  hSRS;
+  map* msSrs=NULL;
+  hSRS = OSRNewSpatialReference(NULL);
+  if( pszProjection!=NULL && strlen(pszProjection)>1){
+    if(OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ){
+      char *proj4Str=NULL;
+      if(OSRGetAuthorityName(hSRS,NULL)!=NULL && 
+	 OSRGetAuthorityCode(hSRS,NULL)!=NULL){
+	char tmpSrs[20];
+	sprintf(tmpSrs,"%s:%s",
+		OSRGetAuthorityName(hSRS,NULL),OSRGetAuthorityCode(hSRS,NULL));
+	msLoadProjectionStringEPSG(&m->projection,tmpSrs);
+	msLoadProjectionStringEPSG(&myLayer->projection,tmpSrs);
+	
+	char tmpSrss[256];
+	sprintf(tmpSrss,"EPSG:4326 EPSG:900913 %s",tmpSrs);
+	
+	msInsertHashTable(&(m->web.metadata), "ows_srs", tmpSrss);
+	msInsertHashTable(&(myLayer->metadata), "ows_srs", tmpSrss);
+	
+#ifdef DEBUGMS
+	fprintf(stderr,"isGeo %b\n\n",OSRIsGeographic(hSRS)==TRUE);
+#endif
+	if(output!=NULL){
+	  if(OSRIsGeographic(hSRS)==TRUE)
+	    addToMap(output->content,"crs_isGeographic","true");
+	  else
+	    addToMap(output->content,"crs_isGeographic","false");
+	  addToMap(output->content,"crs",tmpSrs);
+	}
+      }
+      else{
+	OSRExportToProj4(hSRS,&proj4Str);
+	if(proj4Str!=NULL && strlen(proj4Str)>0){
+#ifdef DEBUGMS
+	  fprintf(stderr,"PROJ (%s)\n",proj4Str);
+#endif
+	  msLoadProjectionString(&(m->projection),proj4Str);
+	  msLoadProjectionString(&(myLayer->projection),proj4Str);
+	  if(output!=NULL){ 
+	    if(OSRIsGeographic(hSRS)==TRUE)
+	      addToMap(output->content,"crs_isGeographic","true");
+	    else
+	      addToMap(output->content,"crs_isGeographic","false");
+	  }
+	  free(proj4Str);
+	}
+	else{
+	  msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
+	  msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
+	  if(output!=NULL){
+	    addToMap(output->content,"crs_isGeographic","true");
+	  }
+	}
+	if(output!=NULL){
+	  addToMap(output->content,"crs","EPSG:4326");
+	  addToMap(output->content,"real_extent","true");
+	}
+	msInsertHashTable(&(m->web.metadata),"ows_srs", "EPSG:4326 EPSG:900913");
+	msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913");
+      }
+    }
+  }
+  else{
+    if(output!=NULL){
+      msSrs=getMap(output->content,"msSrs");
+    }
+    if(msSrs!=NULL){
+      msLoadProjectionStringEPSG(&m->projection,msSrs->value);
+      msLoadProjectionStringEPSG(&myLayer->projection,msSrs->value);
+      char tmpSrs[128];
+      sprintf(tmpSrs,"%s EPSG:4326 EPSG:900913",msSrs->value);
+      msInsertHashTable(&(m->web.metadata),"ows_srs",tmpSrs);
+      msInsertHashTable(&(myLayer->metadata),"ows_srs",tmpSrs);
+    }else{
+      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
+      msLoadProjectionStringEPSG(&myLayer->projection,"EPSG:4326");
+      msInsertHashTable(&(m->web.metadata),"ows_srs","EPSG:4326 EPSG:900913");
+      msInsertHashTable(&(myLayer->metadata),"ows_srs","EPSG:4326 EPSG:900913");
+    }
+    if(output!=NULL){
+      addToMap(output->content,"crs",msSrs->value);
+      addToMap(output->content,"crs_isGeographic","true");
+    }
+  }
+
+  OSRDestroySpatialReference( hSRS );
+}
+
+/**
+ * Set the MAPFILE extent, the the ows_extent for the layer, add wms_extent and
+ * wfs_extent to the output maps and call setMapSize.
+ *
+ * @param output the specific output
+ * @param m the mapObj
+ * @param myLayer the layerObj
+ * @param minX the lower left x coordinate
+ * @param minY the lower left y coordinate
+ * @param maxX the upper right x coordinate
+ * @param maxY the upper right y coordinate
+ * @see setMapSize
+ */
+void setMsExtent(maps* output,mapObj* m,layerObj* myLayer,
+		 double minX,double minY,double maxX,double maxY){
+  msMapSetExtent(m,minX,minY,maxX,maxY);
+#ifdef DEBUGMS
+  fprintf(stderr,"Extent %.15f %.15f %.15f %.15f\n",minX,minY,maxX,maxY);
+#endif
+  char tmpExtent[1024];
+  sprintf(tmpExtent,"%.15f %.15f %.15f %.15f",minX,minY,maxX,maxY);
+#ifdef DEBUGMS
+  fprintf(stderr,"Extent %s\n",tmpExtent);
+#endif
+  msInsertHashTable(&(myLayer->metadata), "ows_extent", tmpExtent);
+  
+  if(output!=NULL){
+    map* test=getMap(output->content,"real_extent");
+    if(test!=NULL){
+      pointObj min, max;
+      projectionObj tempSrs;
+      min.x = m->extent.minx;
+      min.y = m->extent.miny;
+      max.x = m->extent.maxx;
+      max.y = m->extent.maxy;
+      char tmpSrsStr[1024];
+      msInitProjection(&tempSrs);
+      msLoadProjectionStringEPSG(&tempSrs,"EPSG:4326");
+
+      msProjectPoint(&(m->projection),&tempSrs,&min);
+      msProjectPoint(&m->projection,&tempSrs,&max);
+      
+      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
+      map* isGeo=getMap(output->content,"crs_isGeographic");
+#ifdef DEBUGMS
+      fprintf(stderr,"isGeo = %s\n",isGeo->value);
+#endif
+      if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
+        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
+      addToMap(output->content,"wms_extent",tmpExtent);
+      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
+      addToMap(output->content,"wcs_extent",tmpExtent);
+    }else{
+      sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
+      map* isGeo=getMap(output->content,"crs_isGeographic");
+      if(isGeo!=NULL){
+#ifdef DEBUGMS
+	fprintf(stderr,"isGeo = %s\n",isGeo->value);
+#endif
+	if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
+	  sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
+      }
+      addToMap(output->content,"wms_extent",tmpExtent); 
+      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
+      addToMap(output->content,"wcs_extent",tmpExtent);
+    }
+  }
+
+  setMapSize(output,minX,minY,maxX,maxY);
+}
+
+/**
+ * Try to open a vector output and define the corresponding layer in the MAPFILE
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param output the specific output maps
+ * @param m the mapObj
+ */
+int tryOgr(maps* conf,maps* output,mapObj* m){
+
+  map* tmpMap=getMap(output->content,"storage");
+  char *pszDataSource=tmpMap->value;
+
+  /**
+   * Try to open the DataSource using OGR
+   */
+  OGRRegisterAll();
+  /**
+   * Try to load the file as ZIP
+   */
+
+  OGRDataSourceH poDS1 = NULL;
+  OGRSFDriverH *poDriver1 = NULL;
+  char *dsName=(char*)malloc((8+strlen(pszDataSource)+1)*sizeof(char));
+  char *odsName=zStrdup(pszDataSource);
+  char *sdsName=zStrdup(pszDataSource);
+  char *demo=".data";
+  sdsName[strlen(sdsName)-(strlen(demo)-1)]='d';
+  sdsName[strlen(sdsName)-(strlen(demo)-2)]='i';
+  sdsName[strlen(sdsName)-(strlen(demo)-3)]='r';
+  sdsName[strlen(sdsName)-(strlen(demo)-4)]=0;
+
+  odsName[strlen(odsName)-(strlen(demo)-1)]='z';
+  odsName[strlen(odsName)-(strlen(demo)-2)]='i';
+  odsName[strlen(odsName)-(strlen(demo)-3)]='p';
+  odsName[strlen(odsName)-(strlen(demo)-4)]=0;
+  sprintf(dsName,"/vsizip/%s",odsName);
+
+#ifdef DEBUGMS
+  fprintf(stderr,"Try loading %s, %s, %s\n",dsName,odsName,dsName);
+#endif
+
+  FILE* file = fopen(pszDataSource, "rb");
+  FILE* fileZ = fopen(odsName, "wb");
+  free(odsName);
+  fseek(file, 0, SEEK_END);
+  unsigned long fileLen=ftell(file);
+  fseek(file, 0, SEEK_SET);
+  char *buffer=(char *)malloc(fileLen+1);
+  fread(buffer, fileLen, 1, file);
+  fwrite(buffer,fileLen, 1, fileZ);
+  fclose(file);
+  fclose(fileZ);
+  free(buffer);
+#ifdef DEBUGMS
+  fprintf(stderr,"Try loading %s",dsName);
+#endif
+  poDS1 = OGROpen( dsName, FALSE, poDriver1 );
+  if( poDS1 == NULL ){
+    fprintf(stderr,"Unable to access the DataSource as ZIP File\n");
+    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
+    OGR_DS_Destroy(poDS1);
+  }else{
+#ifdef DEBUGMS
+    fprintf(stderr,"The DataSource is a  ZIP File\n");
+#endif
+    char** demo=VSIReadDir(dsName);
+    int i=0;
+    zMkdir(sdsName
+#ifndef WIN32
+		,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH 
+#endif
+		);
+    while(demo[i]!=NULL){
+#ifdef DEBUGMS
+      fprintf(stderr,"ZIP File content : %s\n",demo[i]);
+#endif
+      char *tmpDs=(char*)malloc((strlen(dsName)+strlen(demo[i])+2)*sizeof(char));
+      sprintf(tmpDs,"%s/%s",dsName,demo[i]);
+      fprintf(stderr,"read : %s\n",tmpDs);
+      
+      VSILFILE* vsif=VSIFOpenL(tmpDs,"rb");
+#ifdef DEBUGMS
+      fprintf(stderr,"open : %s\n",tmpDs);
+#endif
+      VSIFSeekL(vsif,0,SEEK_END);
+      vsi_l_offset size=VSIFTellL(vsif);
+#ifdef DEBUGMS
+      fprintf(stderr,"size : %d\n",size);
+#endif
+      VSIFSeekL(vsif,0,SEEK_SET);
+      char *vsifcontent=(char*) malloc(((int)size+1)*sizeof(char));
+      VSIFReadL(vsifcontent,1,(size_t)size,vsif);
+      char *fpath=(char*) malloc((strlen(sdsName)+strlen(demo[1])+2)*sizeof(char));
+      sprintf(fpath,"%s/%s",sdsName,demo[i]);
+      int f=zOpen(fpath,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+      zWrite(f,vsifcontent,(int)size);
+      close(f);
+      chmod(fpath,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH);
+      char* tmpP=strstr(fpath,".shp");
+      if(tmpP==NULL)
+	tmpP=strstr(fpath,".SHP");
+      if(tmpP!=NULL){
+#ifdef DEBUGMS
+	fprintf(stderr,"*** DEBUG %s\n",strstr(tmpP,"."));
+#endif
+	if( strcmp(tmpP,".shp")==0 || strcmp(tmpP,".SHP")==0 ){
+	  tmpMap=getMap(output->content,"storage");
+	  free(tmpMap->value);
+	  tmpMap->value=(char*) malloc((strlen(fpath)+1)*sizeof(char));
+	  sprintf(tmpMap->value,"%s",fpath);
+	  pszDataSource=tmpMap->value;
+#ifdef DEBUGMS
+	  fprintf(stderr,"*** DEBUG %s\n",pszDataSource);
+#endif
+	}
+      }
+      VSIFCloseL(vsif);
+      i++;
+    }
+  }
+  free(sdsName);
+  free(dsName);
+
+  OGRDataSourceH poDS = NULL;
+  OGRSFDriverH *poDriver = NULL;
+  poDS = OGROpen( pszDataSource, FALSE, poDriver );
+  if( poDS == NULL ){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to access the DataSource %s\n",pszDataSource);
+#endif
+    setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
+    OGR_DS_Destroy(poDS);
+    OGRCleanupAll();
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to access the DataSource, exit! \n"); 
+#endif
+    return -1;
+  }
+
+  int iLayer = 0;
+  for( iLayer=0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++ ){
+    OGRLayerH poLayer = OGR_DS_GetLayer(poDS,iLayer);
+
+    if( poLayer == NULL ){
+#ifdef DEBUGMS
+      fprintf(stderr,"Unable to access the DataSource Layer \n");
+#endif
+      setMapInMaps(conf,"lenv","message","Unable to open datasource in read only mode");
+      return -1;
+    }
+
+    /**
+     * Add a new layer set name, data
+     */
+    if(msGrowMapLayers(m)==NULL){
+      return -1;
+    }
+    if(initLayer((m->layers[m->numlayers]), m) == -1){
+      return -1;
+    }
+
+    layerObj* myLayer=m->layers[m->numlayers];
+#ifdef DEBUGMS
+    dumpMaps(output);
+#endif
+    myLayer->name = zStrdup(output->name);
+    myLayer->tileitem=NULL;
+    myLayer->data = zStrdup(OGR_L_GetName(poLayer));
+    myLayer->connection = zStrdup(pszDataSource);
+    myLayer->index = m->numlayers;
+    myLayer->dump = MS_TRUE;
+    myLayer->status = MS_ON;
+    msConnectLayer(myLayer,MS_OGR,pszDataSource);
+
+    /**
+     * Detect the Geometry Type or use Polygon
+     */
+    if(OGR_L_GetGeomType(poLayer) != wkbUnknown){
+      switch(OGR_L_GetGeomType(poLayer)){
+      case wkbPoint:
+      case wkbMultiPoint:
+      case wkbPoint25D:
+      case wkbMultiPoint25D:
+#ifdef DEBUGMS
+	fprintf(stderr,"POINT DataSource Layer \n");
+#endif
+	myLayer->type = MS_LAYER_POINT;
+	break;
+      case wkbLineString :
+      case wkbMultiLineString :
+      case wkbLineString25D:
+      case wkbMultiLineString25D:
+#ifdef DEBUGMS
+	fprintf(stderr,"LINE DataSource Layer \n");
+#endif
+	myLayer->type = MS_LAYER_LINE;
+	break;
+      case wkbPolygon:
+      case wkbMultiPolygon:
+      case wkbPolygon25D:
+      case wkbMultiPolygon25D:
+#ifdef DEBUGMS
+	fprintf(stderr,"POLYGON DataSource Layer \n");
+#endif
+	myLayer->type = MS_LAYER_POLYGON;
+	break;
+      default:
+	myLayer->type = MS_LAYER_POLYGON;
+	break;
+      }
+    }else
+      myLayer->type = MS_LAYER_POLYGON;
+
+    /**
+     * Detect spatial reference or use WGS84
+     */
+    OGRSpatialReferenceH srs=OGR_L_GetSpatialRef(poLayer);
+    if(srs!=NULL){
+      char *wkt=NULL;
+      OSRExportToWkt(srs,&wkt);
+      setSrsInformations(output,m,myLayer,wkt);
+      free(wkt);
+    }
+    else{
+      addToMap(output->content,"crs","EPSG:4326");
+      addToMap(output->content,"crs_isGeographic","true");
+      msLoadProjectionStringEPSG(&m->projection,"EPSG:4326");
+      msInsertHashTable(&(m->web.metadata), "ows_srs", "EPSG:4326 EPSG:900913");
+      msInsertHashTable(&(myLayer->metadata), "ows_srs", "EPSG:4326 EPSG:900913");
+    }
+
+    OGREnvelope oExt;
+    if (OGR_L_GetExtent(poLayer,&oExt, TRUE) == OGRERR_NONE){
+      setMsExtent(output,m,myLayer,oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY);
+    }
+  
+    /**
+     * Detect the FID column or use the first attribute field as FID
+     */
+    char *fid=(char*)OGR_L_GetFIDColumn(poLayer);
+    if(strlen(fid)==0){
+      OGRFeatureDefnH def=OGR_L_GetLayerDefn(poLayer);
+      int fIndex=0;
+      for(fIndex=0;fIndex<OGR_FD_GetFieldCount(def);fIndex++){
+	OGRFieldDefnH fdef=OGR_FD_GetFieldDefn(def,fIndex);
+	fid=(char*)OGR_Fld_GetNameRef(fdef);
+	break;
+      }
+    }
+    msInsertHashTable(&(myLayer->metadata), "gml_featureid", fid);
+    msInsertHashTable(&(myLayer->metadata), "gml_include_items", "all");
+    msInsertHashTable(&(myLayer->metadata), "ows_name", output->name);
+    map* tmpMap=getMap(output->content,"title");
+    if(tmpMap!=NULL)
+      msInsertHashTable(&(myLayer->metadata), "ows_title", tmpMap->value);
+    else
+      msInsertHashTable(&(myLayer->metadata), "ows_title", "Default Title");
+    
+    if(msGrowLayerClasses(myLayer) == NULL)
+      return -1;
+    if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
+      return -1;
+    myLayer->CLASS[myLayer->numclasses]->type = myLayer->type;
+    if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
+      return -1;
+    if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
+      return -1;
+    /**
+     * Apply msStyle else fallback to the default style
+     */
+    tmpMap=getMap(output->content,"msStyle");
+    if(tmpMap!=NULL)
+      msUpdateStyleFromString(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles],tmpMap->value,0);
+    else{
+      /**
+       * Set style
+       */
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=125;
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=125;
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=255;
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.red=80;
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.green=80;
+      myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinecolor.blue=80;
+      
+      /**
+       * Set specific style depending on type
+       */
+      if(myLayer->type == MS_LAYER_POLYGON)
+	myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
+      if(myLayer->type == MS_LAYER_LINE){
+	myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->width=3;
+	myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->outlinewidth=1.5;
+      }
+      if(myLayer->type == MS_LAYER_POINT){
+	myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->symbol=1;
+	myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->size=15;
+      }
+      
+    }
+    myLayer->CLASS[myLayer->numclasses]->numstyles++;
+    myLayer->numclasses++;
+    
+    m->layerorder[m->numlayers] = m->numlayers;
+    m->numlayers++;
+
+  }
+
+  OGR_DS_Destroy(poDS);
+  OGRCleanupAll();
+
+  return 1;
+}
+
+/**
+ * Try to open a raster output and define the corresponding layer in the MAPFILE
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param output the specific output maps
+ * @param m the mapObj
+ */
+int tryGdal(maps* conf,maps* output,mapObj* m){
+  map* tmpMap=getMap(output->content,"storage");
+  char *pszFilename=tmpMap->value;
+  GDALDatasetH hDataset;
+  GDALRasterBandH hBand;
+  double adfGeoTransform[6];
+  int i, iBand;
+  
+  /**
+   * Try to open the DataSource using GDAL
+   */
+  GDALAllRegister();
+  hDataset = GDALOpen( pszFilename, GA_ReadOnly );
+  if( hDataset == NULL ){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to access the DataSource %s \n",pszFilename);
+#endif
+    setMapInMaps(conf,"lenv","message","gdalinfo failed - unable to open");
+    GDALDestroyDriverManager();
+    return -1;
+  }
+#ifdef DEBUGMS
+  fprintf(stderr,"Accessing the DataSource %s %d\n",pszFilename,__LINE__);
+#endif
+
+  /**
+   * Add a new layer set name, data
+   */
+  if(msGrowMapLayers(m)==NULL){
+    return -1;
+  }
+  if(initLayer((m->layers[m->numlayers]), m) == -1){
+    return -1;
+  }
+  m->layers[m->numlayers]->index=m->numlayers;
+
+  layerObj* myLayer=m->layers[m->numlayers];
+  myLayer->name = zStrdup(output->name);
+  myLayer->tileitem=NULL;
+  myLayer->data = zStrdup(pszFilename);
+  myLayer->index = m->numlayers;
+  myLayer->dump = MS_TRUE;
+  myLayer->status = MS_ON;
+  myLayer->type = MS_LAYER_RASTER;
+
+  char *title=output->name;
+  tmpMap=getMap(output->content,"title");
+  if(tmpMap!=NULL)
+    title=tmpMap->value;
+  char *abstract=output->name;
+  tmpMap=getMap(output->content,"abstract");
+  if(tmpMap!=NULL)
+    abstract=tmpMap->value;
+
+  msInsertHashTable(&(myLayer->metadata), "ows_label", title);
+  msInsertHashTable(&(myLayer->metadata), "ows_title", title);
+  msInsertHashTable(&(myLayer->metadata), "ows_abstract", abstract);
+  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_name", output->name);
+  msInsertHashTable(&(myLayer->metadata), "ows_rangeset_label", title);
+
+  /**
+   * Set Map Size to the raster size
+   */
+  m->width=GDALGetRasterXSize( hDataset );
+  m->height=GDALGetRasterYSize( hDataset );
+  
+  /**
+   * Set projection using Authority Code and Name if available or fallback to 
+   * proj4 definition if available or fallback to default EPSG:4326
+   */
+  const char *tRef=GDALGetProjectionRef( hDataset );
+  if( tRef != NULL && strlen(tRef)>0 ){
+    char *pszProjection;
+    pszProjection = (char *) GDALGetProjectionRef( hDataset );
+#ifdef DEBUGMS
+    fprintf(stderr,"Accessing the DataSource %s\n",GDALGetProjectionRef( hDataset ));
+#endif
+    setSrsInformations(output,m,myLayer,pszProjection);
+  }else{
+    fprintf(stderr,"NO SRS FOUND ! %s\n",GDALGetProjectionRef( hDataset ));    
+  }
+
+
+  /**
+   * Set extent
+   */
+  if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){
+    if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ){
+
+      double minX = adfGeoTransform[0]
+	+ adfGeoTransform[2] * GDALGetRasterYSize(hDataset);
+      double minY = adfGeoTransform[3]
+	+ adfGeoTransform[5] * GDALGetRasterYSize(hDataset);
+
+      double maxX = adfGeoTransform[0]
+	+ adfGeoTransform[1] * GDALGetRasterXSize(hDataset);
+      double maxY = adfGeoTransform[3]
+	+ adfGeoTransform[4] * GDALGetRasterXSize(hDataset);
+
+       setMsExtent(output,m,myLayer,minX,minY,maxX,maxY);
+
+    }
+  }
+
+  /**
+   * Extract information about available bands to set the bandcount and the
+   * processing directive
+   */
+  char nBands[2];
+  int nBandsI=GDALGetRasterCount( hDataset );
+  sprintf(nBands,"%d",GDALGetRasterCount( hDataset ));
+  msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
+  if(nBandsI>=3)
+    msLayerAddProcessing(myLayer,"BANDS=1,2,3");
+  else if(nBandsI>=2)
+    msLayerAddProcessing(myLayer,"BANDS=1,2");
+  else
+    msLayerAddProcessing(myLayer,"BANDS=1");
+
+  /**
+   * Name available Bands
+   */
+  char lBands[6];
+  char *nameBands=NULL;
+  for( iBand = 0; iBand < nBandsI; iBand++ ){
+    sprintf(lBands,"Band%d",iBand+1);
+    if(nameBands==NULL){
+      nameBands=(char*)malloc((strlen(lBands)+1)*sizeof(char));
+      sprintf(nameBands,"%s",lBands);
+    }else{
+      if(iBand<4){
+	char *tmpS=zStrdup(nameBands);
+	nameBands=(char*)realloc(nameBands,(strlen(nameBands)+strlen(lBands)+1)*sizeof(char));
+	sprintf(nameBands,"%s %s",tmpS,lBands);
+	free(tmpS);
+      }
+    }
+  }
+  msInsertHashTable(&(myLayer->metadata), "ows_bandnames", nameBands);
+  
+  /**
+   * Loops over metadata informations to setup specific informations
+   */
+  for( iBand = 0; iBand < nBandsI; iBand++ ){
+    //int         bGotNodata;//, bSuccess;
+    double      adfCMinMax[2]/*, dfNoData*/;
+    //int         nBlockXSize, nBlockYSize, nMaskFlags;
+    //double      /*dfMean, dfStdDev*/;
+    hBand = GDALGetRasterBand( hDataset, iBand+1 );
+
+    CPLErrorReset();
+    GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax );
+    char tmpN[21];
+    sprintf(tmpN,"Band%d",iBand+1);
+    if (CPLGetLastErrorType() == CE_None){
+      char tmpMm[100];
+      sprintf(tmpMm,"%.3f %.3f",adfCMinMax[0],adfCMinMax[1]);
+      char tmpI[21];
+      sprintf(tmpI,"%s_interval",tmpN);
+      msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
+
+      map* test=getMap(output->content,"msClassify");
+      if(test!=NULL && strncasecmp(test->value,"true",4)==0){
+	/**
+	 * Classify one band raster pixel value using regular interval
+	 */
+	int _tmpColors[10][3]={
+	  {102,153,204},
+	  {51,102,153},
+	  {102,102,204},
+	  {51,204,0},
+	  {153,255,102},
+	  {204,255,102},
+	  {102,204,153},
+	  {255,69,64},
+	  {255,192,115},
+	  {255,201,115}
+	};
+	  
+	if(nBandsI==1){
+	  double delta=adfCMinMax[1]-adfCMinMax[0];
+	  double interval=delta/10;
+	  double cstep=adfCMinMax[0];
+	  for(i=0;i<10;i++){
+	    /**
+	     * Create a new class
+	     */
+	    if(msGrowLayerClasses(myLayer) == NULL)
+	      return -1;
+	    if(initClass((myLayer->CLASS[myLayer->numclasses])) == -1)
+	      return -1;
+	    myLayer->CLASS[myLayer->numclasses]->type = myLayer->type;
+	    if(msGrowClassStyles(myLayer->CLASS[myLayer->numclasses]) == NULL)
+	      return -1;
+	    if(initStyle(myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]) == -1)
+	      return -1;
+	    
+	    /**
+	     * Set class name
+	     */
+	    char className[7];
+	    sprintf(className,"class%d",i);
+	    myLayer->CLASS[myLayer->numclasses]->name=zStrdup(className);
+	    
+	    /**
+	     * Set expression
+	     */
+	    char expression[1024];
+	    if(i+1<10)
+	      sprintf(expression,"([pixel]>=%.3f AND [pixel]<%.3f)",cstep,cstep+interval);
+	    else
+	      sprintf(expression,"([pixel]>=%.3f AND [pixel]<=%.3f)",cstep,cstep+interval);
+	    msLoadExpressionString(&myLayer->CLASS[myLayer->numclasses]->expression,expression);
+	    
+	    /**
+	     * Set color
+	     */
+	    myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.red=_tmpColors[i][0];
+	    myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.green=_tmpColors[i][1];
+	    myLayer->CLASS[myLayer->numclasses]->styles[myLayer->CLASS[myLayer->numclasses]->numstyles]->color.blue=_tmpColors[i][2];
+	    cstep+=interval;
+	    myLayer->CLASS[myLayer->numclasses]->numstyles++;
+	    myLayer->numclasses++;
+	    
+	  }
+	  
+	  char tmpMm[100];
+	  sprintf(tmpMm,"%.3f %.3f",adfCMinMax[0],adfCMinMax[1]);
+	  
+	}
+      }
+    }
+    if( strlen(GDALGetRasterUnitType(hBand)) > 0 ){
+      char tmpU[21];
+      sprintf(tmpU,"%s_band_uom",tmpN);
+      msInsertHashTable(&(myLayer->metadata), tmpU, GDALGetRasterUnitType(hBand));
+    }
+
+  }
+
+  m->layerorder[m->numlayers] = m->numlayers;
+  m->numlayers++;
+  GDALClose( hDataset );
+  GDALDestroyDriverManager();
+  CPLCleanupTLS();
+  return 1;
+}
+
+/**
+ * Create a MapFile for WMS, WFS or WCS Service output
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param outputs a specific output maps
+ */
+void outputMapfile(maps* conf,maps* outputs){
+
+  /**
+   * First store the value on disk
+   */
+  map* mime=getMap(outputs->content,"mimeType");
+  char *ext="data";
+  if(mime!=NULL)
+    if(strncasecmp(mime->value,"application/json",16)==0)
+      ext="json";
+
+  map* tmpMap=getMapFromMaps(conf,"main","dataPath");
+  map* sidMap=getMapFromMaps(conf,"lenv","usid");
+  char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
+  sprintf(pszDataSource,"%s/ZOO_DATA_%s_%s.%s",tmpMap->value,outputs->name,sidMap->value,ext); 
+  int f=zOpen(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+  map *gfile=getMap(outputs->content,"generated_file");
+  if(gfile!=NULL){
+    readGeneratedFile(conf,outputs->content,gfile->value);	    
+  }
+  map* sizeMap=getMap(outputs->content,"size");
+  map* vData=getMap(outputs->content,"value");
+  if(sizeMap!=NULL){
+    zWrite(f,vData->value,atoi(sizeMap->value)*sizeof(char));
+  }
+  else{
+    zWrite(f,vData->value,(strlen(vData->value)+1)*sizeof(char));
+  }
+  close(f);
+  addToMap(outputs->content,"storage",pszDataSource);
+  free(pszDataSource);
+
+  /*
+   * Create an empty map, set name, default size and extent
+   */
+  mapObj *myMap=msNewMapObj();
+  free(myMap->name);
+  myMap->name=zStrdup("ZOO-Project_WXS_Server");
+  msMapSetSize(myMap,2048,2048);
+  msMapSetExtent(myMap,-1,-1,1,1);
+  
+  /*
+   * Set imagepath and imageurl using tmpPath and tmpUrl from main.cfg
+   */
+  map *tmp1=getMapFromMaps(conf,"main","tmpPath");
+  myMap->web.imagepath=zStrdup(tmp1->value);
+  tmp1=getMapFromMaps(conf,"main","tmpUrl");
+  myMap->web.imageurl=zStrdup(tmp1->value);
+  
+  /*
+   * Define supported output formats
+   */
+  outputFormatObj *o1=msCreateDefaultOutputFormat(NULL,"AGG/PNG","png");
+  o1->imagemode=MS_IMAGEMODE_RGBA;
+  o1->transparent=MS_TRUE;
+  o1->inmapfile=MS_TRUE;
+  msAppendOutputFormat(myMap,msCloneOutputFormat(o1));
+  msFreeOutputFormat(o1);
+
+#ifdef USE_KML
+  outputFormatObj *o2=msCreateDefaultOutputFormat(NULL,"KML","kml");
+  o2->inmapfile=MS_TRUE;  
+  msAppendOutputFormat(myMap,msCloneOutputFormat(o2));
+  msFreeOutputFormat(o2);
+#endif
+
+  outputFormatObj *o3=msCreateDefaultOutputFormat(NULL,"GDAL/GTiff","tiff");
+  if(!o3)
+    fprintf(stderr,"Unable to initialize GDAL driver !\n");
+  else{
+    o3->imagemode=MS_IMAGEMODE_BYTE;
+    o3->inmapfile=MS_TRUE;  
+    msAppendOutputFormat(myMap,msCloneOutputFormat(o3));
+    msFreeOutputFormat(o3);
+  }
+
+  outputFormatObj *o4=msCreateDefaultOutputFormat(NULL,"GDAL/AAIGRID","grd");
+  if(!o4)
+    fprintf(stderr,"Unable to initialize GDAL driver !\n");
+  else{
+    o4->imagemode=MS_IMAGEMODE_INT16;
+    o4->inmapfile=MS_TRUE;  
+    msAppendOutputFormat(myMap,msCloneOutputFormat(o4));
+    msFreeOutputFormat(o4);
+  }
+
+#ifdef USE_CAIRO
+  outputFormatObj *o5=msCreateDefaultOutputFormat(NULL,"CAIRO/PNG","cairopng");
+  if(!o5)
+    fprintf(stderr,"Unable to initialize CAIRO driver !\n");
+  else{
+    o5->imagemode=MS_IMAGEMODE_RGBA;
+    o5->transparent=MS_TRUE;
+    o5->inmapfile=MS_TRUE;
+    msAppendOutputFormat(myMap,msCloneOutputFormat(o5));
+    msFreeOutputFormat(o5);
+  }
+#endif
+
+  /*
+   * Set default projection to EPSG:4326
+   */
+  msLoadProjectionStringEPSG(&myMap->projection,"EPSG:4326");
+  myMap->transparent=1;
+
+  /**
+   * Set metadata extracted from main.cfg file maps
+   */
+  maps* cursor=conf;
+  map* correspondance=getCorrespondance();
+  while(cursor!=NULL){
+    map* _cursor=cursor->content;
+    map* vMap;
+    while(_cursor!=NULL){
+      if((vMap=getMap(correspondance,_cursor->name))!=NULL){
+	if (msInsertHashTable(&(myMap->web.metadata), vMap->value, _cursor->value) == NULL){
+#ifdef DEBUGMS
+	  fprintf(stderr,"Unable to add metadata");
+#endif
+	  return;
+	}
+      }
+      _cursor=_cursor->next;
+    }
+    cursor=cursor->next;
+  }
+  freeMap(&correspondance);
+  free(correspondance);
+
+  /*
+   * Set mapserver PROJ_LIB/GDAL_DATA or any other config parameter from 
+   * the main.cfg [mapserver] section if any
+   */
+  maps *tmp3=getMaps(conf,"mapserver");
+  if(tmp3!=NULL){
+    map* tmp4=tmp3->content;
+    while(tmp4!=NULL){
+      msSetConfigOption(myMap,tmp4->name,tmp4->value);
+      tmp4=tmp4->next;
+    }
+  }
+
+  /**
+   * Set a ows_rootlayer_title,  
+   */
+  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_name", "ZOO_Project_Layer") == NULL){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to add metadata");
+#endif
+    return;
+  }
+  if (msInsertHashTable(&(myMap->web.metadata), "ows_rootlayer_title", "ZOO_Project_Layer") == NULL){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to add metadata");
+#endif
+    return;
+  }
+
+  /**
+   * Enable all the WXS requests using ows_enable_request
+   * see http://mapserver.org/trunk/development/rfc/ms-rfc-67.html
+   */
+  if (msInsertHashTable(&(myMap->web.metadata), "ows_enable_request", "*") == NULL){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to add metadata");
+#endif
+    return;
+  }
+  msInsertHashTable(&(myMap->web.metadata), "ows_srs", "EPSG:4326");
+
+  if(tryOgr(conf,outputs,myMap)<0)
+    if(tryGdal(conf,outputs,myMap)<0)
+      return ;
+
+  tmp1=getMapFromMaps(conf,"main","dataPath");
+  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
+  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
+  msInitSymbolSet(&myMap->symbolset);
+  myMap->symbolset.filename=zStrdup(tmpPath);
+  free(tmpPath);
+
+  map* sid=getMapFromMaps(conf,"lenv","usid");
+  char *mapPath=
+    (char*)malloc((7+strlen(sid->value)+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
+  sprintf(mapPath,"%s/%s_%s.map",tmp1->value,outputs->name,sid->value);
+  msSaveMap(myMap,mapPath);
+  free(mapPath);
+  msGDALCleanup();
+  msFreeMap(myMap);
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ms.h	(revision 672)
@@ -0,0 +1,62 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2010  Fondazione Edmund Mach. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef ZOO_SERVICE_INTERNAL_MS_H
+#define ZOO_SERVICE_INTERNAL_MS_H 1
+
+#include <sys/stat.h>
+#include "service_internal.h"
+#include "service.h"
+#include "cpl_conv.h"
+#include "cpl_multiproc.h"
+#include "ogr_api.h"
+#include "gdal.h"
+#include "ogr_srs_api.h"
+#include "ulinet.h"
+#ifdef WIN32
+#include <unistd.h>
+#endif
+
+#include <mapserver.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  map* getCorrespondance();
+  void setMapSize(maps* output,double minx,double miny,double maxy,double maxx);
+  void setReferenceUrl(maps* m,maps* tmpI);
+
+  void setSrsInformations(maps* output,mapObj* m,layerObj* myLayer, char* pszProjection);
+  
+  void setMsExtent(maps* output,mapObj* m,layerObj* myLayer,
+		   double minX,double minY,double maxX,double maxY);
+  int tryOgr(maps* conf,maps* output,mapObj* m);
+  
+  int tryGdal(maps* conf,maps* output,mapObj* m);
+  void outputMapfile(maps* conf,maps* outputs);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+ 
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.c	(revision 672)
@@ -0,0 +1,483 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * See Ref: http://hg.orfeo-toolbox.org/OTB/ Copyright
+ * Some parts of this code are derived from ITK. See ITKCopyright.txt for 
+ * details.
+ */
+
+#include "service_internal_otb.h"
+#include "response_print.h"
+#include "server_internal.h"
+
+using namespace otb::Wrapper;
+
+/**
+ * Global OTB counter 
+ */
+int otbCounter=0;
+
+/**
+ * The ZooWatcher list
+ */
+WatcherListType m_WatcherList;
+/**
+ * A pointer to the conf maps containing the main.cfg settings
+ */
+maps* m_Conf;
+
+/**
+ * The command to create a ZooWatcher and add it to the global m_WatcherList
+ */
+class MyCommand : public itk::Command
+{
+ public:
+  itkNewMacro( MyCommand );
+ public:
+
+  /**
+   * The method that defines the action to be taken by the command. 
+   *
+   * @param caller an itk::Object pointer
+   * @param event an itk::EventObject pointer
+   */
+  void Execute(itk::Object *caller, const itk::EventObject & event)
+  {
+    Execute( (const itk::Object *)caller, event);
+  }
+ 
+  /**
+   * The method that defines the action to be taken by the command. 
+   * Create a new ZooWatcher instance then add it to the m_WatcherList.
+   *
+   * @param caller a const itk::Object pointer
+   * @param event an itk::EventObject pointer
+   * @see ZooWatcher,ZooWatcher::SetConf
+   */
+  void Execute(const itk::Object *caller, const itk::EventObject & event)
+  {
+    const AddProcessToWatchEvent* eventToWatch = dynamic_cast< const AddProcessToWatchEvent*> ( &event );
+    std::string m_CurrentDescription = eventToWatch->GetProcessDescription();
+    ZooWatcher * watch = new ZooWatcher(eventToWatch->GetProcess(),
+					eventToWatch->GetProcessDescription());
+    watch->SetConf(&m_Conf);
+    m_WatcherList.push_back(watch);
+  }
+
+};
+
+/**
+ * Replace all occurence of from by to in a str string
+ *
+ * @param str the string to transform
+ * @param from the string to replace
+ * @param to the string used as replacement
+ * @return the resulting string 
+ */
+std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
+    size_t start_pos = 0;
+    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
+        str.replace(start_pos, from.length(), to);
+        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+    }
+    return str;
+}
+
+/**
+ * Load and run an OTB Application corresponding to the service by using inputs parameters.
+ * Define the m_Conf 
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param real_inputs the maps containing the inputs
+ * @param real_outputs the maps containing the outputs
+ */
+int zoo_otb_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+  maps* m=*main_conf;
+  maps* inputs=*real_inputs;
+  maps* outputs=*real_outputs;
+  map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
+  char *ntmp=tmp0->value;
+  map* tmp=NULL;
+  int res=-1;
+  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
+  if (list.size() == 0){
+    map* tmps=createMap("text","No OTB Application found.");
+    addToMap(tmps,"code","InternalError");
+    printExceptionReportResponse(m,tmps);
+    freeMap(&tmps);
+    free(tmps);
+    res=-1;
+    return res;
+  }
+  else{
+    dumpMapsValuesToFiles(main_conf,real_inputs);
+    for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it){
+      if(s->name==*it){
+	Application::Pointer m_Application=ApplicationRegistry::CreateApplication(*it);
+	if (m_Application.IsNull()){
+	  char tmpS[1024];
+	  sprintf(tmpS, "The OTB Application %s cannot be loaded.", (*it).c_str());
+	  map* tmps=createMap("text",tmpS);
+	  addToMap(tmps,"code","InternalError");
+	  printExceptionReportResponse(m,tmps);
+	  freeMap(&tmps);
+	  free(tmps);
+	  res=-1;
+	}else{
+	  // Create Observer on AddProcessToWatchEvent
+	  m_Conf=m;
+	  MyCommand::Pointer myCommand = MyCommand::New();
+	  m_Application->AddObserver(AddProcessToWatchEvent(), myCommand);
+	  char tmpS[1024];
+	  const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
+	  for (unsigned int i = 0; i < appKeyList.size(); i++){
+	    const std::string paramKey(appKeyList[i]);
+	    Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
+	    ParameterType type = m_Application->GetParameterType(paramKey);
+	    if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"){
+	      map* test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
+	      if(test==NULL){
+		test=getMapFromMaps(inputs,paramKey.c_str(),"inRequest");
+		map* tmpPath=getMapFromMaps(m,"main","tmpPath");
+		map* tmpSid=getMapFromMaps(m,"lenv","usid");
+		char tmp[1024];
+		map* tmpVal=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
+		maps* tmpMaps=getMaps(outputs,paramKey.c_str());
+		if(tmpMaps!=NULL && test!=NULL && test->value!=NULL && strncasecmp(test->value,"true",4)==0){
+		  test=getMapFromMaps(inputs,paramKey.c_str(),"value");
+		  if(type == ParameterType_OutputImage){
+		    ImagePixelType outPixType = ImagePixelType_float;
+		    if (strncasecmp(test->value,"uint8",5)==0)
+		      outPixType = ImagePixelType_uint8;
+		    else if (strncasecmp(test->value,"int16",5)==0)
+		      outPixType = ImagePixelType_int16;
+		    else if (strncasecmp(test->value,"uint16",6)==0)
+		      outPixType = ImagePixelType_uint16;
+		    else if (strncasecmp(test->value,"int32",5)==0)
+		      outPixType = ImagePixelType_int32;
+		    else if (strncasecmp(test->value,"uint32",6)==0)
+		      outPixType = ImagePixelType_uint32;
+		    else if (strncasecmp(test->value,"double",6)==0)
+		      outPixType = ImagePixelType_double;
+		    const char* ext="tiff";
+		    if(tmpVal!=NULL){
+		      if(strncasecmp(tmpVal->value,"image/jp2",9)==0)
+			 ext="j2k";
+		      else
+			if(strncasecmp(tmpVal->value,"image/png",9)==0)
+			 ext="png";
+			else
+			  if(strncasecmp(tmpVal->value,"image/jpeg",10)==0)
+			    ext="jpeg";
+		    }
+		    sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
+		    otbCounter++;
+		    m_Application->SetParameterString(paramKey, tmp);
+		    setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
+		    dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType);
+		  }
+		  else{   	 	 
+		    if(test!=NULL && test->value!=NULL)  	 	 
+		      m_Application->SetParameterString(paramKey, test->value);  	 	 
+		  } 
+		}else{
+		  if(type == ParameterType_OutputVectorData){
+		      char* ext="json";
+		      if(tmpVal!=NULL){
+			if(strncasecmp(tmpVal->value,"text/xml",8)==0)
+			ext="gml";
+		      else
+			if(strncasecmp(tmpVal->value,"applicaton/json",15)==0)
+			  ext="json";
+			else
+			  if(strncasecmp(tmpVal->value,"application/zip",14)==0)
+			    ext="shp";
+			  else
+			    if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
+			      ext="kml";
+		      }
+		      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
+		      otbCounter++;
+		      m_Application->SetParameterString(paramKey, tmp);
+		      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
+		  }
+		  else
+		    if(type == ParameterType_OutputFilename){
+		      char* ext="txt";
+		      if(tmpVal!=NULL){
+			if(strncasecmp(tmpVal->value,"text/xml",8)==0)
+			  ext="xml";
+			else
+			  if(strncasecmp(tmpVal->value,"text/csv",15)==0)
+			    ext="csv";
+			  else
+			    if(strncasecmp(tmpVal->value,"application/zip",14)==0)
+			      ext="shp";
+			    else
+			      if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kml+xml",36)==0)
+				ext="kml";
+			      else
+				if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kmz",32)==0){
+				  ext="kmz";
+				  sprintf(tmp,"%s/%s_%d_%sxt.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
+				  m_Application->SetParameterString(paramKey, tmp);
+				  setMapInMaps(outputs,paramKey.c_str(),"expected_generated_file",tmp);
+				}
+
+		      }
+		      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
+		      otbCounter++;
+		      m_Application->SetParameterString(paramKey, tmp);
+		      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
+		    }
+		    else{
+		      test=getMapFromMaps(inputs,paramKey.c_str(),"value");
+		      if(test!=NULL && type!=ParameterType_ListView){
+			m_Application->SetParameterString(paramKey, test->value);
+		      }
+		      else
+			if(type==ParameterType_ListView){
+			  std::vector<std::string> values;
+			  values.push_back(test->value);
+			  map* tmpLength=getMapFromMaps(inputs,paramKey.c_str(),"length");
+			  if(tmpLength!=NULL){
+			    int len=atoi(tmpLength->value);
+			    for(int k=1;k<len;k++){
+			      char tmp[15];
+			      sprintf(tmp,"cache_file_%d",k);
+			      map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
+			      if(tmpVal!=NULL){
+				values.push_back(tmpVal->value);
+			      }
+			    }
+			  }
+			  dynamic_cast<ListViewParameter *> (param.GetPointer())->SetSelectedItems(values);
+			}
+		    }
+		}
+	      }else{
+		if(type == ParameterType_InputImageList){
+		  std::vector<std::string> values;
+		  values.push_back(test->value);
+		  map* tmpPath=getMapFromMaps(inputs,paramKey.c_str(),"length");
+		  if(tmpPath!=NULL){
+		    int len=atoi(tmpPath->value);
+		    for(int k=1;k<len;k++){
+		      char tmp[15];
+		      sprintf(tmp,"cache_file_%d",k);
+		      map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
+		      if(tmpVal!=NULL){
+			values.push_back(tmpVal->value);
+		      }
+		    }
+		  }
+		  dynamic_cast<InputImageListParameter *> (param.GetPointer())->SetListFromFileName(values);
+		}
+		else
+		  if(type == ParameterType_InputVectorData || type == ParameterType_InputFilename){
+		    map* tmpPath=getMapFromMaps(m,"main","tmpPath");
+		    map* tmpSid=getMapFromMaps(m,"lenv","sid");
+		    char tmp[1024];
+		    map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),"mimeType");
+		    char* ext="json";
+		    if(tmpVal!=NULL){
+		      if(strncasecmp(tmpVal->value,"application/zip",14)==0){
+			char *tmpName=(char*)malloc((strlen(test->value)+9)*sizeof(char));
+			std::string test0(test->value);
+			if(test0.find(".zca")!=std::string::npos){
+			  symlink(test->value,ReplaceAll(test->value,".zca",".zip").c_str());
+			  sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".zca",".zip").c_str());
+			}else
+			  sprintf(tmpName,"/vsizip/%s",test->value);
+			char **files=VSIReadDir(tmpName);
+			int nFiles = CSLCount( files );
+			char *tmpSSName=(char*)malloc((strlen(tmpPath->value)+strlen(paramKey.c_str())+strlen(tmpSid->value)+9)*sizeof(char));
+			sprintf(tmpSSName,"%s/Input_%s_%s",tmpPath->value,paramKey.c_str(),tmpSid->value);
+			mkdir(tmpSSName,0777);
+			    
+			for(int kk=0;kk<nFiles;kk++){
+			  char *tmpSName=(char*)malloc((strlen(tmpName)+strlen(files[kk])+2)*sizeof(char));
+			  sprintf(tmpSName,"%s/%s",tmpName,files[kk]);
+			  VSILFILE* fmain=VSIFOpenL(tmpSName, "rb");
+			  if(fmain!=NULL){
+			    VSIFSeekL(fmain,0,SEEK_END);
+			    long count=VSIFTellL(fmain);
+			    VSIRewindL(fmain);
+
+			    char *content=(char*) malloc((count+1)*sizeof(char));  
+			    VSIFReadL(content,1,count*sizeof(char),fmain);
+			  
+			    char *tmpSSSName=(char*)malloc((strlen(tmpSSName)+strlen(files[kk])+2)*sizeof(char));
+			    sprintf(tmpSSSName,"%s/%s",tmpSSName,files[kk]);
+			    
+			    FILE* fx=fopen(tmpSSSName, "wb");
+			    fwrite(content,1,count,fx);
+			    fclose(fx);
+			    VSIFCloseL(fmain);
+			    free(content);
+			    std::string test1(tmpSSSName);
+			    if(test1.find(".shp")!=std::string::npos){
+			      setMapInMaps(inputs,paramKey.c_str(),"cache_file",tmpSSSName);
+			      test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
+			    }
+			    free(tmpSSSName);
+			  }
+			  free(tmpSName);
+			}
+			free(tmpSSName);
+			free(tmpName);
+		      }
+		    }
+		    
+		    m_Application->SetParameterString(paramKey, test->value);
+		  }
+		  else
+		    if(type == ParameterType_InputImage
+		       || type == ParameterType_ComplexInputImage || type == ParameterType_InputVectorData
+		       || type == ParameterType_InputFilename){
+		      m_Application->SetParameterString(paramKey, test->value);
+		  }
+	      }
+	    }
+	    param->SetUserValue(true);
+	    m_Application->UpdateParameters();
+	  }
+
+	  try{
+	    if( m_Application->ExecuteAndWriteOutput() == 0 ){
+	      std::vector< std::pair<std::string, std::string> > paramList;
+	      paramList = m_Application->GetOutputParametersSumUp();
+	      if(paramList.size()>0)
+		for( unsigned int i=0; i<paramList.size(); i++){
+		  setMapInMaps(outputs,paramList[i].first.c_str(),"value",paramList[i].second.c_str());
+		}
+	      else{
+		const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true);
+		for (unsigned int i = 0; i < appKeyList.size(); i++){
+		  const std::string paramKey(appKeyList[i]);
+		  std::vector<std::string> values;
+		  Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
+		  ParameterType type = m_Application->GetParameterType(paramKey);
+		  if (type != ParameterType_Group && paramKey!="inxml" && paramKey!="outxml"
+		      && (type == ParameterType_OutputImage || type == ParameterType_OutputFilename
+			  || type == ParameterType_OutputVectorData ) ){
+		    if(type == ParameterType_OutputImage || type == ParameterType_OutputFilename || type == ParameterType_OutputVectorData){
+		      map* test=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
+		      if(test!=NULL && strncasecmp(test->value,"application/zip",15)==0){
+			
+			test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
+			char tmpName[1024];
+			sprintf(tmpName,"/vsizip/%s",ReplaceAll(test->value,".shp",".zip").c_str());
+			VSILFILE* fmain=VSIFOpenL(tmpName, "w");
+			FILE * file;
+			char *tmp;
+			char tmpSName[1024];
+			long count;
+			
+			char *exts[4];
+			exts[0]=".shp";
+			exts[1]=".shx";
+			exts[2]=".dbf";
+			exts[3]=".prj";
+			for(int c=0;c<4;c++){
+			  sprintf(tmpSName,"%s/result%s",tmpName,exts[c]);
+			  
+			  file=fopen(ReplaceAll(test->value,".shp",exts[c]).c_str(),"rb");
+			  if(file!=NULL){
+			    fseek(file, 0, SEEK_END);
+			    count = ftell(file);
+			    rewind(file);
+			    
+			    tmp=(char*) malloc((count+1)*sizeof(char));  
+			    fread(tmp,1,count*sizeof(char),file);
+			    
+			    VSILFILE* fx=VSIFOpenL(tmpSName, "wb");
+			    VSIFWriteL(tmp,1,count,fx);
+			    VSIFCloseL(fx);
+			    fclose(file);
+			    free(tmp);
+			  }
+			}
+			
+			VSIFCloseL(fmain);
+			
+			FILE* file1=fopen(ReplaceAll(test->value,".shp",".zip").c_str(), "rb");
+			fseek(file1, 0, SEEK_END);
+			count=ftell(file1);
+			rewind(file1);
+			
+			tmp=(char*) malloc((count+1)*sizeof(char));  
+			fread(tmp,1,count*sizeof(char),file1);
+			
+			file=fopen(ReplaceAll(test->value,".shp",".zip").c_str(),"wb");
+			fwrite(tmp,1,count,file);
+			fclose(file);
+			free(tmp);
+			fclose(file1);
+			setMapInMaps(inputs,paramKey.c_str(),"generated_file",ReplaceAll(test->value,".shp",".zip").c_str());
+		      }
+		      test=getMapFromMaps(inputs,paramKey.c_str(),"generated_file");
+
+		      if(test!=NULL){
+			setMapInMaps(outputs,paramKey.c_str(),"generated_file",test->value);
+		      }
+
+		    }
+		  }
+		}
+	      }
+	      res=3;
+	      break;
+	    }
+	    else{
+	      sprintf(tmpS, "The OTB Application %s cannot be run.", s->name);
+	      setMapInMaps(m,"lenv","message",tmpS);
+	      res=SERVICE_FAILED;
+	    }
+	  }
+	  catch(std::exception& err){
+	    setMapInMaps(m,"lenv","message",err.what());
+	    return SERVICE_FAILED;
+	    
+	  }
+	  catch(...){
+	    setMapInMaps(m,"lenv","message","An unknown exception has been raised during application execution");
+	    res=SERVICE_FAILED;
+	  }
+	  break;
+	}
+      }
+    }
+  }
+
+  for (unsigned int i = 0; i < m_WatcherList.size(); i++){
+    m_WatcherList[i]->FreeConf();
+    delete m_WatcherList[i];
+    m_WatcherList[i] = NULL;
+  }
+  m_WatcherList.clear();
+
+  return res;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_otb.h	(revision 672)
@@ -0,0 +1,53 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_OTB_H
+#define ZOO_SERVICE_INTERNAL_OTB_H 1
+
+#pragma once 
+
+#include "otbWrapperApplication.h"
+#include "otbWrapperApplicationRegistry.h"
+#include "otbWrapperInputImageListParameter.h"
+#include "otbWrapperListViewParameter.h"
+#include "otbWrapperAddProcessToWatchEvent.h"
+#include "otbZooWatcher.h"
+#include "service_internal.h"
+#include "service.h"
+#include "cgic.h"
+#ifdef WIN32
+#include <windows.h>
+#include <direct.h>
+#endif
+#include <vector>
+#include <string>
+
+/**
+ * A vector to store the ZooWatcher
+ */
+typedef std::vector<ZooWatcher *> WatcherListType;
+
+int zoo_otb_support(maps**,map*,service*,maps**,maps**);
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.c	(revision 672)
@@ -0,0 +1,201 @@
+/**
+ * Author : David SAGGIORATO
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service_internal_perl.h"
+
+
+static PerlInterpreter *my_perl;
+
+
+void xs_init(pTHX)
+{
+	char *file = __FILE__;
+	dXSUB_SYS;
+	
+	/* DynaLoader is a special case */
+	newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+}
+
+
+
+int map_to_hash(map * m, HV ** hash_map) {
+	HV * tmp = *hash_map;
+	map * tmp_m = m;
+	do {
+		//printf("map name %s  value %s \n",m->name,m->value);
+
+		if ( NULL == hv_store( tmp, tmp_m->name, strlen(tmp_m->name), sv_2mortal(newSVpv(tmp_m->value, strlen(tmp_m->value))), 0) ) {
+			return 1;
+			}
+		tmp_m = tmp_m->next;
+		}
+	while (tmp_m != NULL);
+	return 0;
+}
+
+int maps_to_hash( maps* m, HV ** hash_maps){
+	HV * tmp = *hash_maps;
+	if (m != NULL) {
+		//printf("maps name %s \n",m->name);
+		HV* hash_m = (HV *)sv_2mortal((SV *)newHV());
+		if (map_to_hash(m->content,&hash_m) != 0){
+			return 1;
+		}
+		
+		if ( NULL == hv_store( tmp, m->name, strlen(m->name),sv_2mortal(newRV_inc((SV *)hash_m)), 0) ) {
+			return 1;
+		}	
+		return maps_to_hash(m->next,hash_maps);
+	}
+	return 0;
+}
+
+int hash_to_map(HV * hh,map ** m){
+	hv_iterinit(hh);
+	*m = (map *)malloc(MAP_SIZE);
+	if (*m == NULL){
+		// erreur d'allocation memoire
+		return 1;
+	}
+	map * tmp = *m;
+	HE * he = hv_iternext(hh);
+	while (he != NULL){
+		//fprintf(stderr,"key : %s  value : %s \n",HeKEY(he),(char *)SvRV(HeVAL(he)));
+		tmp->name = HeKEY(he);
+		tmp->value = (char *)SvRV(HeVAL(he));
+		he = hv_iternext(hh);
+		if(he != NULL){
+			tmp->next = (map *)malloc(MAP_SIZE);
+			if (tmp->next == NULL){
+				//erreur allocation memoire
+				return 1;
+			}
+			tmp=tmp->next;
+		}
+		else {
+			tmp->next = NULL;
+		}
+
+	}
+
+	return 1;
+}
+	
+int hash_to_maps(HV * hh,maps** m){
+	hv_iterinit(hh);
+	*m = (maps *)malloc(MAPS_SIZE);
+	maps * tmp = *m;
+	HE * he = hv_iternext(hh);
+	map *mm;
+	while (he != NULL) {
+		//fprintf(stderr,"key ===> %s \n",HeKEY(he));
+		tmp->name = HeKEY(he);
+		hash_to_map((HV *) SvRV(HeVAL(he)),&mm);
+		tmp->content = mm;
+		he = hv_iternext(hh);
+		if (he != NULL){
+			tmp->next = (maps *)malloc(MAPS_SIZE);
+			tmp= tmp->next;
+		}
+		else {
+			tmp->next = NULL;
+		}		
+	}
+	return 1;
+}
+	
+int zoo_perl_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+	maps* m=*main_conf;
+ 	maps* inputs=*real_inputs;
+	maps* outputs=*real_outputs;
+  	int res=SERVICE_FAILED;
+  	map * tmp=getMap(s->content,"serviceProvide");
+
+	char *my_argv[] = { "", tmp->value };
+	if ((my_perl = perl_alloc()) == NULL){
+		fprintf(stderr,"no memmory");
+		exit(1);
+	}
+	perl_construct( my_perl );
+	perl_parse(my_perl, xs_init, 2, my_argv, (char **)NULL);
+	perl_run(my_perl);
+	
+
+	HV* h_main_conf = (HV *)sv_2mortal((SV *)newHV());
+	HV* h_real_inputs = (HV *)sv_2mortal((SV *)newHV());
+	HV* h_real_outputs = (HV *)sv_2mortal((SV *)newHV());
+	maps_to_hash(m,&h_main_conf);
+	maps_to_hash(inputs,&h_real_inputs);
+	maps_to_hash(outputs,&h_real_outputs);
+	dSP;
+    	ENTER;
+    	SAVETMPS;
+    	PUSHMARK(SP);
+	XPUSHs(sv_2mortal(newRV_inc((SV *)h_main_conf)));
+	XPUSHs(sv_2mortal(newRV_inc((SV *)h_real_inputs)));
+	XPUSHs(sv_2mortal(newRV_inc((SV *)h_real_outputs)));
+	PUTBACK;
+	call_pv(s->name, G_SCALAR);
+	SPAGAIN;
+	res = POPi;
+	hash_to_maps(h_real_outputs,real_outputs);
+	//dumpMaps(*real_outputs);
+	PUTBACK;
+    	FREETMPS;
+    	LEAVE;
+	return SERVICE_SUCCEEDED;
+}
+
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_perl.h	(revision 672)
@@ -0,0 +1,64 @@
+/**
+ * Author : David SAGGIORATO
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_PERL_H
+#define ZOO_SERVICE_INTERNAL_PERL_H 1
+
+#pragma once 
+
+#include "service.h"
+#include "service_internal.h"
+#include <stdio.h>
+#include <EXTERN.h>
+#include <perl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void xs_init (pTHX);
+
+void boot_DynaLoader (pTHX_ CV*);
+
+int map_to_hash(map*, HV** );
+
+int maps_to_hash(maps *, HV ** );
+
+int hash_to_map(HV* ,map**);
+
+int hash_to_maps(HV* ,maps** );
+
+int zoo_perl_support(maps**,map*,service*,maps**,maps**);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+
+
+
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.c	(revision 672)
@@ -0,0 +1,454 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef WIN32
+  #define NO_FCGI_DEFINES
+#endif
+
+#ifndef ZEND_DEBUG
+  #define ZEND_DEBUG 0
+#endif  
+ 
+#include "service_internal_php.h"
+
+#include <sapi/embed/php_embed.h>
+#include <zend_stream.h>
+
+zval *php_Array_from_maps(maps* t);
+zval*  php_Array_from_map(map*);
+maps* php_maps_from_Array(HashTable* t);
+map* php_map_from_HasTable(HashTable* t);
+
+#ifdef ZTS
+void ***tsrm_ls;
+#endif
+
+ZEND_BEGIN_MODULE_GLOBALS(zoo)
+long _SERVICE_SUCCEEDED;
+long _SERVICE_FAILED;
+ZEND_END_MODULE_GLOBALS(zoo)
+
+#ifdef ZTS
+#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
+#else
+#define ZOO_G(v) (zoo_globals.v)
+#endif
+
+#define PHP_ZOO_VERSION "1.0"
+#define PHP_ZOO_EXTNAME "ZOO"
+
+PHP_MINIT_FUNCTION(zoo);
+PHP_MSHUTDOWN_FUNCTION(zoo);
+PHP_RINIT_FUNCTION(zoo);
+
+PHP_FUNCTION(zoo_Translate);
+PHP_FUNCTION(zoo_UpdateStatus);
+PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
+PHP_FUNCTION(zoo_SERVICE_FAILED);
+
+extern zend_module_entry zoo_module_entry;
+#define phpext_zoo_ptr &zoo_entry
+
+ZEND_DECLARE_MODULE_GLOBALS(zoo)
+
+static zend_function_entry zoo_functions[] = {
+  PHP_FE(zoo_Translate, NULL)
+  PHP_FE(zoo_UpdateStatus, NULL)
+  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
+  PHP_FE(zoo_SERVICE_FAILED, NULL)
+  {NULL, NULL, NULL}
+};
+
+zend_module_entry zoo_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+    STANDARD_MODULE_HEADER,
+#endif
+    PHP_ZOO_EXTNAME,
+    zoo_functions,
+    PHP_MINIT(zoo),
+    PHP_MSHUTDOWN(zoo),
+    PHP_RINIT(zoo),
+    NULL,
+    NULL,
+#if ZEND_MODULE_API_NO >= 20010901
+    PHP_ZOO_VERSION,
+#endif
+    STANDARD_MODULE_PROPERTIES
+};
+
+ZEND_GET_MODULE(zoo)
+
+PHP_INI_BEGIN()
+PHP_INI_END()
+
+static void
+php_zoo_init_globals(zend_zoo_globals *zoo_globals)
+{
+  zoo_globals->_SERVICE_SUCCEEDED=3;
+  zoo_globals->_SERVICE_FAILED=4;
+}
+
+PHP_RINIT_FUNCTION(zoo)
+{
+  return SUCCESS;
+}
+
+PHP_MINIT_FUNCTION(zoo)
+{
+  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
+  REGISTER_INI_ENTRIES();
+  return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(zoo)
+{
+  UNREGISTER_INI_ENTRIES();
+  return SUCCESS;
+}
+
+PHP_FUNCTION(zoo_Translate)
+{
+  char *value;
+  int value_len;
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
+    RETURN_NULL();
+  }
+  RETURN_STRING(_ss(value), 1);
+}
+
+PHP_FUNCTION(zoo_UpdateStatus)
+{
+  zval *arr;
+  char *message;
+  int message_len;
+  long pourcent;
+  char *status=(char*)malloc(4*sizeof(char));
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
+    RETURN_NULL();
+  }
+  HashTable* t=HASH_OF(arr);
+  maps* conf=php_maps_from_Array(t);
+  setMapInMaps(conf,"lenv","message",message);
+  sprintf(status,"%d",pourcent);
+  setMapInMaps(conf,"lenv","status",status);
+  _updateStatus(conf);
+  freeMaps(&conf);
+  free(conf);
+  free(status);
+  RETURN_NULL();
+}
+
+PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
+{
+  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
+}
+
+PHP_FUNCTION(zoo_SERVICE_FAILED)
+{
+  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
+}
+
+/**
+ * Load a PHP script then run the function corresponding to the service by
+ * passing the conf, inputs and outputs parameters by reference.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param real_inputs the maps containing the inputs
+ * @param real_outputs the maps containing the outputs
+ */
+int zoo_php_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){	
+  maps* m=*main_conf;
+  maps* inputs=*real_inputs;
+  maps* outputs=*real_outputs;
+  char ntmp[1024];
+  getcwd(ntmp,1024);
+    
+  map* libp = getMapFromMaps(m, "main", "libPath"); // KLa  
+  int res=SERVICE_FAILED;
+
+  map* tmp=getMap(s->content,"serviceProvider");
+  if (tmp == NULL || tmp->value == NULL) {
+	  return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
+  }
+  
+  map* cwd=getMapFromMaps(m,"lenv","cwd");
+#ifdef IGNORE_METAPATH
+  map* mp = createMap("metapath", "");
+#else  
+  map* mp = getMap(request, "metapath");
+#endif
+  char *scriptName;
+  
+  if (libp != NULL && libp->value != NULL) {
+	scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
+    sprintf (scriptName, "%s/%s", libp->value, tmp->value);	
+  }
+  else {	
+    if(mp!=NULL && strlen(mp->value)>0){
+      scriptName=(char*)malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
+      sprintf(scriptName,"%s/%s/%s",cwd->value,mp->value,tmp->value);
+    }else{
+      scriptName=(char*)malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
+      sprintf(scriptName,"%s/%s",cwd->value,tmp->value);
+    }
+  } 
+  zend_file_handle iscript;
+  iscript.type=ZEND_HANDLE_FD;
+  iscript.opened_path=NULL;
+  iscript.filename=tmp->value;
+  iscript.free_filename=0;
+  FILE* temp=fopen(scriptName,"rb");
+  if(temp==NULL){
+    char tmp1[1024];
+    sprintf(tmp1,_("Unable to load the PHP file %s"),tmp->value);
+    free(scriptName);
+    return errorException(m,tmp1,"NoApplicableCode",NULL);
+  }
+  iscript.handle.fd=fileno(temp);
+
+  php_embed_init(0,NULL PTSRMLS_CC);
+   
+  zend_try {
+    zend_startup_module(&zoo_module_entry);
+    php_execute_script(&iscript TSRMLS_CC);
+    zval *iargs[3];
+    zval iret, ifunc,ifile;
+      
+    ZVAL_STRING(&ifunc, s->name, 0);
+    iargs[0] = php_Array_from_maps(*main_conf);
+    iargs[1] = php_Array_from_maps(*real_inputs);
+    iargs[2] = php_Array_from_maps(*real_outputs);
+      
+    if((res=call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs TSRMLS_CC))==SUCCESS){
+      
+      HashTable* t=HASH_OF(iargs[2]);
+      HashTable* t1=HASH_OF(iargs[0]);
+      freeMaps(real_outputs);
+      free(*real_outputs);
+      freeMaps(main_conf);
+      free(*main_conf);
+      *real_outputs=php_maps_from_Array(t);
+      *main_conf=php_maps_from_Array(t1);
+
+      res=Z_LVAL(iret);
+    }else{
+      free(scriptName);
+      fclose(temp);
+      return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
+    }
+  } zend_catch { 
+    free(scriptName);
+    fclose(temp);
+    return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
+  } zend_end_try();
+  free(scriptName);
+  fclose(temp);
+  php_embed_shutdown(TSRMLS_C);
+
+  return res;
+}
+
+/**
+ * Convert a maps to a php Array
+ *
+ * @param t the maps to convert
+ * @return the php Array
+ */
+zval *php_Array_from_maps(maps* t){
+  zval *mapArray;
+  zval *mapArrayTmp;
+  maps* tmp=t;
+  int tres=0;
+  MAKE_STD_ZVAL(mapArray);
+  tres=array_init(mapArray);
+  while(tmp!=NULL){
+    add_assoc_zval(mapArray,tmp->name,php_Array_from_map(tmp->content));
+    tmp=tmp->next;
+  }
+  return mapArray;
+}
+
+/**
+ * Convert a map to a php Array
+ *
+ * @param t the map to convert
+ * @return the php Array
+ */
+zval *php_Array_from_map(map* t){
+  zval *mapArray;
+  zval *mapArrayTmp;
+  map* tmp=t;
+  int tres=0;
+  MAKE_STD_ZVAL(mapArray);
+  tres=array_init(mapArray);
+  while(tmp!=NULL){
+    map* sMap=getMapArray(tmp,"size",0);    
+	if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
+      tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
+	} 
+	else if (tmp->value != NULL) {
+      tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
+	}
+    tmp=tmp->next;
+  }
+  return mapArray;
+}
+
+/**
+ * Convert a php Array to a maps
+ *
+ * @param t the php Array to convert
+ * @return the created maps
+ */
+maps* php_maps_from_Array(HashTable *t){
+  maps* final_res=NULL;
+  maps* cursor=final_res;
+  char key[1024];
+  for(zend_hash_internal_pointer_reset(t); 
+      zend_hash_has_more_elements(t) == SUCCESS; 
+      zend_hash_move_forward(t)) { 
+    char *key; 
+    uint keylen; 
+    ulong idx; 
+    int type; 
+    zval **ppzval, tmpcopy; 
+    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
+    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
+      /**
+       * Should never actually fail since the key is known to exist.
+       */
+      continue; 
+    }
+    /**
+     * Duplicate the zval so that * the orignal’s contents are not destroyed
+     */
+    tmpcopy = **ppzval;
+#ifdef DEBUG
+    fprintf(stderr,"key : %s\n",key);
+#endif
+    zval_copy_ctor(&tmpcopy); 
+#ifdef DEBUG
+    fprintf(stderr,"key : %s\n",key);
+#endif
+    /**
+     * Reset refcount & Convert
+     */
+    INIT_PZVAL(&tmpcopy); 
+    //convert_to_string(&tmpcopy); 
+    if (type == HASH_KEY_IS_STRING) { 
+      /**
+       * String Key / Associative
+       */
+      cursor=(maps*)malloc(MAPS_SIZE);
+      cursor->name=strdup(key);
+    }
+#ifdef DEBUG	
+    fprintf(stderr,"key : %s\n",key);
+#endif	
+    HashTable* t=HASH_OF(*ppzval);
+#ifdef DEBUG
+    fprintf(stderr,"key : %s\n",key);
+#endif
+    cursor->content=php_map_from_HasTable(t);
+    cursor->next=NULL;
+    if(final_res==NULL)
+      final_res=cursor;
+    else{
+      addMapsToMaps(&final_res,cursor);
+      freeMaps(&cursor);
+      free(cursor);
+    }
+#ifdef DEBUG
+    fprintf(stderr,"key : %s\n",key);
+#endif
+    /**
+     * Toss out old copy
+     */
+    zval_dtor(&tmpcopy);
+  }
+  return final_res;
+}
+
+/**
+ * Convert a php Array to a map
+ *
+ * @param t the php Array to convert
+ * @return the created map
+ */
+map* php_map_from_HasTable(HashTable* t){
+#ifdef DEBUG
+  fprintf(stderr,"mapsFromPHPArray start\n");
+#endif
+  map* final_res=(map*)malloc(MAP_SIZE);
+  final_res=NULL;
+  char key[1024];
+  for(zend_hash_internal_pointer_reset(t);
+      zend_hash_has_more_elements(t) == SUCCESS;
+      zend_hash_move_forward(t)) {
+    char *key;
+    uint keylen;
+    ulong idx;
+    int type;
+    int len;
+    zval **ppzval, tmpcopy;
+    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
+    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
+      /* Should never actually fail * since the key is known to exist. */ 
+      continue; 
+    }
+    /**
+     * Duplicate the zval so that * the orignal’s contents are not destroyed 
+     */ 
+    tmpcopy = **ppzval; 
+    zval_copy_ctor(&tmpcopy); 
+    /**
+     * Reset refcount & Convert 
+     */ 
+    INIT_PZVAL(&tmpcopy); 
+    convert_to_string(&tmpcopy);
+    if(strncmp(key,"value",5)==0){
+      len=Z_STRLEN_P(&tmpcopy);
+      addToMapWithSize(final_res,key,Z_STRVAL_P(&tmpcopy),len);
+    }
+    else{
+      if(final_res==NULL){
+#ifdef DEBUG
+	fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
+#endif
+	final_res=createMap(key,Z_STRVAL(tmpcopy));
+      }
+      else{
+#ifdef DEBUG
+	fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
+#endif
+	addToMap(final_res,key,Z_STRVAL(tmpcopy));
+      }
+    }
+    /* Toss out old copy */ 
+    zval_dtor(&tmpcopy); 
+  }
+  return final_res;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_php.h	(revision 672)
@@ -0,0 +1,43 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_PHP_H
+#define ZOO_SERVICE_INTERNAL_PHP_H 1
+
+#pragma once
+
+#include "service.h"
+#include "service_internal.h"
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  int zoo_php_support(maps**,map*,service*,maps**,maps**);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.c	(revision 672)
@@ -0,0 +1,671 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2014 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service_internal_python.h"
+
+/**
+ * The state for the zoo Python module
+ */
+struct module_state {
+   PyObject *error;
+};
+
+#if PY_MAJOR_VERSION >= 3
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyString_FromString PyUnicode_FromString
+#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyString_Check PyUnicode_Check
+#define	PyString_AsString _PyUnicode_AsString
+#define	PyString_Size PyUnicode_GetSize
+#else
+#define GETSTATE(m) (&_state)
+static struct module_state _state;
+#endif
+
+/**
+ * The exception for the zoo Python module
+ */
+static PyObject* ZooError;
+
+/**
+ * Function definitions for the zoo Python Module
+ *
+ * Define the following functions available from a service loaded and running
+ * from the ZOO-Kernel Python environment:
+ *  - "_" corresponding to the PythonTranslate function
+ *  - "updte_status" corresponding to the PythonUpdateStatus function
+ * @see PythonTranslate, PythonUpdateStatus
+ */
+PyMethodDef zooMethods[] = {
+  {"_", PythonTranslate, METH_VARARGS, "Translate a string using the zoo-services textdomain."},
+  {"update_status", PythonUpdateStatus, METH_VARARGS, "Update status percentage of a running process."},
+  {NULL, NULL, 0, NULL} /* tempt not the blade, all fear the sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+static int myextension_traverse(PyObject *m, visitproc visit, void *arg) {
+  Py_VISIT(GETSTATE(m)->error);
+  return 0;
+}
+
+static int myextension_clear(PyObject *m) {
+  Py_CLEAR(GETSTATE(m)->error);
+  return 0;
+}
+
+static struct PyModuleDef moduledef = {
+  PyModuleDef_HEAD_INIT,
+  "zoo",
+  NULL,
+  sizeof(struct module_state),
+  zooMethods,
+  NULL,
+  myextension_traverse,
+  myextension_clear,
+  NULL
+};
+#endif
+
+/**
+ * Function to create and initialize the zoo Python module
+ *
+ * @return the Python module (for Python versions < 3, nothing for version >=3)
+ */
+PyMODINIT_FUNC init_zoo(){
+  PyObject *tmp,*d;
+  PyObject *module = 
+#if PY_MAJOR_VERSION >= 3
+    PyModule_Create(&moduledef);
+#else
+    Py_InitModule("zoo", zooMethods);
+#endif
+  if (module == NULL){
+#if PY_MAJOR_VERSION >= 3
+    return NULL;
+#else
+    return;
+#endif
+  }
+
+  struct module_state *st = GETSTATE(module);
+
+  d = PyModule_GetDict(module);
+  tmp = PyInt_FromLong(3);
+  PyDict_SetItemString(d, "SERVICE_SUCCEEDED", tmp);
+  Py_DECREF(tmp);
+
+  tmp = PyInt_FromLong(4);
+  PyDict_SetItemString(d, "SERVICE_FAILED", tmp);
+  Py_DECREF(tmp);
+
+  tmp = PyString_FromString(ZOO_VERSION);
+  PyDict_SetItemString(d, "VERSION", tmp);
+  Py_DECREF(tmp);
+
+  ZooError = PyErr_NewException((char*)"zoo.error", NULL, NULL);
+  Py_INCREF(ZooError);
+  PyModule_AddObject(module, "error", ZooError);
+#if PY_MAJOR_VERSION >= 3
+  return module;
+#endif
+}
+
+/**
+ * Load a Python module then run the function corresponding to the service
+ * by passing the conf, inputs and outputs parameters by reference. 
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param real_inputs the maps containing the inputs
+ * @param real_outputs the maps containing the outputs
+ */
+int zoo_python_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+  char *pythonpath;
+  char *python_path;
+  maps* m=*main_conf;
+  maps* inputs=*real_inputs;
+  maps* outputs=*real_outputs;
+  map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
+  char *ntmp=tmp0->value;
+  map* tmp=NULL;
+  int hasToClean=0;
+  tmp=getMapFromMaps(*main_conf,"env","PYTHONPATH");
+#ifdef DEBUG
+  fprintf(stderr,"PYTHON SUPPORT \n");
+#endif
+  if(tmp!=NULL){
+#ifdef DEBUG
+    fprintf(stderr,"PYTHON SUPPORT (%i)\n",strlen(tmp->value));
+#endif
+    python_path=(char*)malloc((strlen(tmp->value))*sizeof(char));
+    sprintf(python_path,"%s",tmp->value);
+    hasToClean=1;
+  }
+  else{
+    python_path=(char*)".";
+  }
+  tmp=NULL;
+  tmp=getMap(request,"metapath");
+  if(tmp!=NULL && strcmp(tmp->value,"")!=0){
+    pythonpath=(char*)malloc((4+strlen(python_path)+strlen(ntmp)+strlen(tmp->value))*sizeof(char));
+#ifdef WIN32
+  sprintf(pythonpath,"%s/%s/;%s",ntmp,tmp->value,python_path);
+#else
+  sprintf(pythonpath,"%s/%s/:%s",ntmp,tmp->value,python_path);
+#endif
+  }
+  else{
+    pythonpath=(char*)malloc((2+strlen(python_path)+strlen(ntmp))*sizeof(char));
+#ifdef WIN32
+    sprintf(pythonpath,"%s;%s",ntmp,python_path);
+#else
+    sprintf(pythonpath,"%s:%s",ntmp,python_path);
+#endif
+  }
+#ifdef DEBUG
+    fprintf(stderr,"PYTHONPATH=%s\n",pythonpath);
+#endif
+#ifndef WIN32
+  setenv("PYTHONPATH",pythonpath,1);
+#else
+  SetEnvironmentVariable("PYTHONPATH",pythonpath);
+  char* toto=(char*)malloc((strlen(pythonpath)+12)*sizeof(char));
+  sprintf(toto,"PYTHONPATH=%s",pythonpath);
+  putenv(toto);
+  free(toto);
+#endif
+  if(hasToClean>0)
+    free(python_path);
+  free(pythonpath);
+
+  PyThreadState *mainstate;
+#if PY_MAJOR_VERSION >= 3
+  PyImport_AppendInittab("zoo", init_zoo);
+#else
+  PyEval_InitThreads();
+#endif
+  Py_Initialize();
+#if PY_MAJOR_VERSION >= 3
+  PyEval_InitThreads();
+  PyImport_ImportModule("zoo");
+#else
+  init_zoo();
+#endif
+  mainstate = PyThreadState_Swap(NULL);
+  PyEval_ReleaseLock();
+  PyGILState_STATE gstate;
+  gstate = PyGILState_Ensure();
+  PyObject *pName, *pModule, *pFunc;
+  tmp=getMap(s->content,"serviceProvider");
+  map* mp=getMap(request,"metapath");
+  if(tmp!=NULL){
+    if(mp!=NULL && strlen(mp->value)>0){
+      char *mps=zStrdup(mp->value);
+      int i,len=strlen(mps);
+      int j=0;
+      for(i=0;i<len;i++){
+	if(mps[i]=='/'){
+	  mps[i]='.';
+	}
+      }
+      char *mn=(char*)malloc((strlen(mps)+strlen(tmp->value)+2)*sizeof(char));
+      sprintf(mn,"%s.%s",mps,tmp->value);
+      pName = PyString_FromString(mn);
+      free(mn);
+      free(mps);
+    }
+    else{
+      pName = PyString_FromString(tmp->value);
+    }
+  }
+  else{
+    errorException (m, "Unable to parse serviceProvider please check your zcfg file.", "NoApplicableCode", NULL);
+    exit(-1);
+  }
+  pModule = PyImport_Import(pName);
+  int res=SERVICE_FAILED;
+  if (pModule != NULL) {
+    pFunc=PyObject_GetAttrString(pModule,s->name);
+    if (pFunc && PyCallable_Check(pFunc)){
+      PyObject *pValue;
+      PyDictObject* arg1=PyDict_FromMaps(m);
+      PyDictObject* arg2=PyDict_FromMaps(inputs);
+      PyDictObject* arg3=PyDict_FromMaps(outputs);
+      PyObject *pArgs=PyTuple_New(3);
+      if (!pArgs)
+	return -1;
+      PyTuple_SetItem(pArgs, 0, (PyObject *)arg1);
+      PyTuple_SetItem(pArgs, 1, (PyObject *)arg2);
+      PyTuple_SetItem(pArgs, 2, (PyObject *)arg3);
+      pValue = PyObject_CallObject(pFunc, pArgs);
+      if (pValue != NULL) {
+	res=PyInt_AsLong(pValue);
+	freeMaps(real_outputs);
+	free(*real_outputs);
+	freeMaps(main_conf);
+	free(*main_conf);
+	*main_conf=mapsFromPyDict(arg1);
+	*real_outputs=mapsFromPyDict(arg3);
+#ifdef DEBUG
+	fprintf(stderr,"Result of call: %i\n", PyInt_AsLong(pValue));
+	dumpMaps(inputs);
+	dumpMaps(*real_outputs);
+#endif
+      }else{	  
+	PythonZooReport(m,tmp->value,0);
+	res=-1;
+      }
+    }
+    else{
+      char tmpS[1024];
+      sprintf(tmpS, "Cannot find the %s function in the %s file.\n", s->name, tmp->value);
+      errorException(m,tmpS,"NoApplicableCode",NULL);
+      res=-1;
+    }
+  } else{
+    PythonZooReport(m,tmp->value,1);
+    res=-1;
+  } 
+#if PY_MAJOR_VERSION < 3
+  PyGILState_Release(gstate);
+  PyEval_AcquireLock();
+#endif
+  PyThreadState_Swap(mainstate);
+  Py_Finalize();
+  return res;
+}
+
+/**
+ * Report Python error which may occur on loading the Python module or at 
+ * runtime.
+ * 
+ * @param m the conf maps containing the main.cfg settings
+ * @param module the service name
+ * @param load 1 if the Python module was not loaded yet
+ */
+void PythonZooReport(maps* m,const char* module,int load){
+  PyObject *pName, *pModule, *pFunc;
+  PyObject *ptype, *pvalue, *ptraceback,*pValue,*pArgs;
+  PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+  char *pStrErrorMessage = PyString_AsString(pvalue);
+  char *tmp0=_("Python module %s cannot be loaded. Message: %s\n");
+  
+  PyObject *trace=PyObject_Str(pvalue);
+  char *pbt=NULL;
+  if(PyString_Check(trace)){
+    pbt=(char*)malloc((7+strlen(PyString_AsString(trace))+1)*sizeof(char));
+    sprintf(pbt,"TRACE: %s",PyString_AsString(trace));
+  }
+  else
+    fprintf(stderr,"EMPTY TRACE ?");
+  
+  trace=NULL;
+  
+  trace=PyObject_Str(ptype);
+  if(PyString_Check(trace)){
+    char *tpbt=zStrdup(pbt);
+    if(pbt!=NULL)
+      free(pbt);
+    pbt=(char*)malloc((1+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));
+    sprintf(pbt,"%s\n%s",tpbt,PyString_AsString(trace));
+    free(tpbt);
+  }
+  else
+    fprintf(stderr,"EMPTY TRACE ?");
+  
+  if(ptraceback!=NULL){
+    char *tpbt=zStrdup(pbt);
+    pName = PyString_FromString("traceback");
+    pModule = PyImport_Import(pName);
+    pArgs = PyTuple_New(1);
+    PyTuple_SetItem(pArgs, 0, ptraceback);
+    pFunc = PyObject_GetAttrString(pModule,"format_tb");
+    pValue = PyObject_CallObject(pFunc, pArgs);
+    trace=NULL;
+    trace=PyObject_Str(pValue);
+    if(PyString_Check(trace)){
+      if(pbt!=NULL)
+	free(pbt);
+      pbt=(char*)malloc((90+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));
+      sprintf(pbt,_("%s\nUnable to run your python process properly. Please check the following messages : %s"),tpbt,PyString_AsString(trace));
+    }
+    else{
+      if(pbt!=NULL)
+	free(pbt);
+      pbt=(char*)malloc((90+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));      
+      sprintf(pbt,_("%s \n Unable to run your python process properly. Unable to provide any futher informations."),tpbt);
+    }
+    free(tpbt);
+  }
+  if(load>0){
+    char *tmpS=(char*)malloc((strlen(tmp0)+strlen(module)+strlen(pbt)+1)*sizeof(char));
+    sprintf(tmpS,tmp0,module,pbt);
+    errorException(m,tmpS,"NoApplicableCode",NULL);
+    free(tmpS);
+  }else
+    errorException(m,pbt,"NoApplicableCode",NULL);
+  free(pbt);
+}
+
+/**
+ * Convert a maps to a Python dictionary
+ *
+ * @param t the maps to convert
+ * @return a new PyDictObject containing the converted maps
+ * @see PyDict_FromMap
+ * @warning make sure to free ressources returned by this function
+ */
+PyDictObject* PyDict_FromMaps(maps* t){
+  PyObject* res=PyDict_New( );
+  maps* tmp=t;
+  while(tmp!=NULL){
+    PyObject* value=(PyObject*)PyDict_FromMap(tmp->content);
+    PyObject* name=PyString_FromString(tmp->name);
+    if(PyDict_SetItem(res,name,value)<0){
+      fprintf(stderr,"Unable to set map value ...");
+      return NULL;
+    }
+    Py_DECREF(name);
+    tmp=tmp->next;
+  }  
+  return (PyDictObject*) res;
+}
+
+/**
+ * Convert a map to a Python dictionary
+ *
+ * @param t the map to convert
+ * @return a new PyDictObject containing the converted maps
+ * @warning make sure to free ressources returned by this function
+ */
+PyDictObject* PyDict_FromMap(map* t){
+  PyObject* res=PyDict_New( );
+  map* tmp=t;
+  int hasSize=0;
+  map* isArray=getMap(tmp,"isArray");
+  map* size=getMap(tmp,"size");
+  map* tmap=getMapType(tmp);
+  while(tmp!=NULL){
+    PyObject* name=PyString_FromString(tmp->name);
+    if(strcasecmp(tmp->name,"value")==0) {
+      if(isArray!=NULL){
+	map* len=getMap(tmp,"length");
+	int cnt=atoi(len->value);
+	PyObject* value=PyList_New(cnt);
+	PyObject* mvalue=PyList_New(cnt);
+	PyObject* svalue=PyList_New(cnt);
+
+	for(int i=0;i<cnt;i++){
+	  
+	  map* vMap=getMapArray(tmp,"value",i);	    
+	  map* sMap=getMapArray(tmp,"size",i);
+
+	  if(vMap!=NULL){
+	    
+	    PyObject* lvalue;
+	    PyObject* lsvalue;
+	    if(sMap==NULL){
+	      lvalue=PyString_FromString(vMap->value);
+	      lsvalue=Py_None;
+	    }
+	    else{    
+	      lvalue=PyString_FromStringAndSize(vMap->value,atoi(sMap->value));
+	      lsvalue=PyString_FromString(sMap->value);
+	      hasSize=1;
+	    }
+
+	    if(PyList_SetItem(value,i,lvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	    } 
+	    if(PyList_SetItem(svalue,i,lsvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	    } 
+	  }
+	  
+	  map* mMap=getMapArray(tmp,tmap->name,i);
+	  PyObject* lmvalue;
+	  if(mMap!=NULL){
+	    lmvalue=PyString_FromString(mMap->value);
+	  }else
+	    lmvalue=Py_None;
+	  
+	  if(PyList_SetItem(mvalue,i,lmvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	  } 
+	  
+	}
+
+	if(PyDict_SetItem(res,name,value)<0){
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	if(PyDict_SetItem(res,PyString_FromString(tmap->name),mvalue)<0){
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	if(hasSize>0)
+	  if(PyDict_SetItem(res,PyString_FromString("size"),svalue)<0){
+	    fprintf(stderr,"Unable to set key value pair...");
+	    return NULL;
+	  }
+      }
+      else if(size!=NULL){
+	PyObject* value=PyString_FromStringAndSize(tmp->value,atoi(size->value));
+	if(PyDict_SetItem(res,name,value)<0){
+	  Py_DECREF(value);
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	Py_DECREF(value);
+      }
+      else{
+	PyObject* value=PyString_FromString(tmp->value);
+	if(PyDict_SetItem(res,name,value)<0){
+	  Py_DECREF(value);
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	Py_DECREF(value);
+      }
+    }
+    else{
+      if(PyDict_GetItem(res,name)==NULL){
+	PyObject* value=PyString_FromString(tmp->value);
+	if(PyDict_SetItem(res,name,value)<0){
+	  Py_DECREF(value);
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	Py_DECREF(value);
+      }
+    }
+    Py_DECREF(name);
+    tmp=tmp->next;
+  }
+  return (PyDictObject*) res;
+}
+
+/**
+ * Convert a Python dictionary to a maps 
+ *
+ * @param t the PyDictObject to convert
+ * @return a new maps containing the converted PyDictObject
+ * @warning make sure to free ressources returned by this function
+ */
+maps* mapsFromPyDict(PyDictObject* t){
+  maps* res=NULL;
+  maps* cursor=res;
+  PyObject* list=PyDict_Keys((PyObject*)t);
+  int nb=PyList_Size(list);
+  int i;
+  for(i=0;i<nb;i++){
+#ifdef DEBUG
+    fprintf(stderr,">> parsing maps %d\n",i);
+#endif
+    PyObject* key=PyList_GetItem(list,i);
+    PyObject* value=PyDict_GetItem((PyObject*)t,key);
+#ifdef DEBUG
+    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
+	    PyString_AsString(key),PyString_AsString(value));
+#endif
+    cursor=(maps*)malloc(MAPS_SIZE);
+    cursor->name=PyString_AsString(key);
+    cursor->content=mapFromPyDict((PyDictObject*)value);
+#ifdef DEBUG
+    dumpMap(cursor->content);
+#endif
+    cursor->next=NULL;
+    if(res==NULL)
+      res=dupMaps(&cursor);
+    else
+      addMapsToMaps(&res,cursor);
+    freeMap(&cursor->content);
+    free(cursor->content);
+    free(cursor);
+#ifdef DEBUG
+    dumpMaps(res);
+    fprintf(stderr,">> parsed maps %d\n",i);
+#endif
+  }
+  Py_DECREF(list);
+  return res;
+}
+
+/**
+ * Convert a Python dictionary to a map 
+ *
+ * @param t the PyDictObject to convert
+ * @return a new map containing the converted PyDictObject
+ * @warning make sure to free ressources returned by this function
+ */
+map* mapFromPyDict(PyDictObject* t){
+  map* res=NULL;
+  PyObject* list=PyDict_Keys((PyObject*)t);
+  int nb=PyList_Size(list);
+  int i;
+  for(i=0;i<nb;i++){
+    PyObject* key=PyList_GetItem(list,i);
+    PyObject* value=PyDict_GetItem((PyObject*)t,key);
+#ifdef DEBUG
+    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
+	    PyString_AsString(key),PyString_AsString(value));
+#endif
+    
+    if(strncmp(PyString_AsString(key),"value",5)==0){
+      char *buffer=NULL;
+      Py_ssize_t size;
+#if PY_MAJOR_VERSION >= 3
+      buffer=_PyUnicode_AsStringAndSize(value,&size);
+#else
+      PyString_AsStringAndSize(value,&buffer,&size);
+#endif
+      addToMapWithSize(res,PyString_AsString(key),buffer,size);
+    }else{
+      char* lkey=PyString_AsString(key);
+      char* lvalue=PyString_AsString(value);
+      if(res!=NULL){
+	if(PyString_Size(value)>0)
+	  addToMap(res,lkey,lvalue);
+      }
+      else{
+	if(PyString_Size(value)>0)
+	  res=createMap(lkey,lvalue);
+      }
+    }
+  }
+  Py_DECREF(list);
+  return res;
+}
+
+/**
+ * Use the ZOO-Services messages translation function from the Python
+ * environment
+ *
+ * @param self the Python object on which we can run the method
+ * @param args the Python arguments given from the Python environment
+ * @return a new Python string containing the translated value
+ * @see _ss
+ */
+PyObject*
+PythonTranslate(PyObject* self, PyObject* args)
+{
+  char *str;
+  if (!PyArg_ParseTuple(args, "s", &str)){
+#ifdef DEBUG
+    fprintf(stderr,"Incorrect arguments to update status function");
+#endif
+    return NULL;
+  }
+  return PyString_FromString(_ss(str));
+}
+
+/**
+ * Update the ongoing status of a running service from the Python environment
+ *
+ * @param self the Python object on which we can run the method
+ * @param args the Python arguments given from the Python environment
+ * @return None to the Python environment
+ * @see _updateStatus
+ */
+PyObject*
+PythonUpdateStatus(PyObject* self, PyObject* args)
+{
+  maps* conf;
+  PyObject* confdict;
+  int istatus;
+  char* status=NULL;
+  if (!PyArg_ParseTuple(args, "O!i", &PyDict_Type, &confdict, &istatus)){
+#ifdef DEBUG
+    fprintf(stderr,"Incorrect arguments to update status function");
+#endif
+    Py_RETURN_NONE;
+  }
+  if (istatus < 0 || istatus > 100){
+     PyErr_SetString(ZooError, "Status must be a percentage.");
+     Py_RETURN_NONE;
+  }else{
+     char tmpStatus[4];
+     snprintf(tmpStatus, 4, "%i", istatus);
+     status = zStrdup(tmpStatus);
+  }
+  // create a local copy and update the lenv map
+  conf = mapsFromPyDict((PyDictObject*)confdict);
+  if(status!=NULL){
+    setMapInMaps(conf,"lenv","status",status);
+    free(status);
+  }
+  else
+    setMapInMaps(conf,"lenv","status","15");
+  _updateStatus(conf);
+  freeMaps(&conf);
+  free(conf);
+  Py_RETURN_NONE;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_python.h	(revision 672)
@@ -0,0 +1,52 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_PYTHON_H
+#define ZOO_SERVICE_INTERNAL_PYTHON_H 1
+
+#pragma once 
+
+#include "service_internal.h"
+#include "response_print.h"
+#include <Python.h>
+#include "cgic.h"
+#ifdef WIN32
+#include <windows.h>
+#include <direct.h>
+#endif
+
+PyDictObject* PyDict_FromMaps(maps* t);
+PyDictObject* PyDict_FromMap(map* t);
+
+maps* mapsFromPyDict(PyDictObject* t);
+map* mapFromPyDict(PyDictObject* t);
+
+int zoo_python_support(maps**,map*,service*,maps**,maps**);
+
+void PythonZooReport(maps*,const char*,int);
+
+PyObject* PythonTranslate(PyObject*, PyObject*);
+PyObject* PythonUpdateStatus(PyObject*, PyObject*);
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.c	(revision 672)
@@ -0,0 +1,486 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2014 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service_internal_ruby.h"
+
+#if RUBY_API_VERSION_MAJOR >= 2 || RUBY_API_VERSION_MINOR == 9 
+int argc=0;
+char **argv=NULL;
+#endif
+
+/**
+ * Load a Ruby file then run the function corresponding to the service by
+ * passing the conf, inputs and outputs parameters by refernce as Ruby Hash.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param real_inputs the maps containing the inputs
+ * @param real_outputs the maps containing the outputs
+ * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1 
+ *  if the service failed to load or throw error at runtime.
+ */
+int zoo_ruby_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+#if RUBY_API_VERSION_MAJOR >= 2 || RUBY_API_VERSION_MINOR == 9
+  ruby_sysinit(&argc,&argv);
+  RUBY_INIT_STACK;
+#endif
+  ruby_init();
+  maps* m=*main_conf;
+  maps* inputs=*real_inputs;
+  maps* outputs=*real_outputs;
+  map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
+  char *ntmp=tmp0->value;
+  map* tmp=NULL;
+  ruby_init_loadpath();
+  ruby_script("ZOO_EMBEDDED_ENV");
+  
+  VALUE klass=rb_define_module("Zoo");
+  rb_define_const(klass,"SERVICE_SUCCEEDED",INT2FIX(3));
+  rb_define_const(klass,"SERVICE_FAILED",INT2FIX(4));
+  typedef VALUE (*HOOK)(...);
+  rb_define_module_function(klass,"Translate",reinterpret_cast<HOOK>(RubyTranslate),-1);
+  rb_define_module_function(klass,"UpdateStatus",reinterpret_cast<HOOK>(RubyUpdateStatus),-1);
+
+  int error = 0;
+		
+  ID rFunc=Qnil;
+  tmp=getMap(s->content,"serviceProvider");
+  if(tmp!=NULL){
+#if RUBY_VERSION_MINOR == 8
+    const char* script = ruby_sourcefile = rb_source_filename(tmp->value);
+    rb_protect(LoadWrap, reinterpret_cast<VALUE>(script), &error);
+#else
+    rb_load_protect(rb_str_new2(tmp->value), 0, &error);
+#endif
+    if(error) {
+      ruby_trace_error(m);
+      return -1;
+    }
+#if RUBY_VERSION_MINOR == 8
+    ruby_exec();
+#else
+    ruby_exec_node(NULL);
+#endif
+  }
+  else{
+    map* err=createMap("text","Unable to parse serviceProvider please check your zcfg file.");
+    addToMap(err,"code","NoApplicableCode");
+    printExceptionReportResponse(m,err);
+    return -1;
+  }
+  int res=SERVICE_FAILED;
+  rFunc=rb_intern(s->name);
+  if(rFunc!=Qnil){
+    VALUE arg1=RubyHash_FromMaps(m);
+    VALUE arg2=RubyHash_FromMaps(inputs);
+    VALUE arg3=RubyHash_FromMaps(outputs);
+    VALUE rArgs[3]={arg1,arg2,arg3};
+    if (!rArgs)
+      return -1;
+    struct my_callback data;
+    data.obj=Qnil;
+    data.method_id=rFunc;
+    data.nargs=3;
+    data.args[0]=rArgs[0];
+    data.args[1]=rArgs[1];
+    data.args[2]=rArgs[2];
+    typedef VALUE (*HOOK)(VALUE);
+    VALUE tres=rb_protect(reinterpret_cast<HOOK>(FunCallWrap),(VALUE)(&data),&error);
+    if (TYPE(tres) == T_FIXNUM) {
+      res=FIX2INT(tres);
+      freeMaps(real_outputs);
+      free(*real_outputs);
+      freeMaps(main_conf);
+      free(*main_conf);
+      *main_conf=mapsFromRubyHash(arg1);
+      *real_outputs=mapsFromRubyHash(arg3);
+#ifdef DEBUG
+      dumpMaps(*main_conf);
+      dumpMaps(*real_outputs);
+#endif
+    }else{
+      ruby_trace_error(m);
+      res=-1;
+    }
+  }
+  else{
+    char tmpS[1024];
+    sprintf(tmpS, "Cannot find the %s function in the %s file.\n", s->name, tmp->value);
+    map* tmps=createMap("text",tmpS);
+    printExceptionReportResponse(m,tmps);
+    res=-1;
+  }
+  ruby_finalize();
+  return res;
+}
+
+/**
+ * Load a ruby file
+ *
+ * @arg the file to load
+ * @return Qnil
+ */
+VALUE LoadWrap(VALUE arg) {
+  const char *filename = reinterpret_cast<const char*>(arg);
+  rb_load_file(filename);
+  return Qnil;
+}
+
+/**
+ * Call a ruby function with parameters
+ *
+ * @arg the callback structure
+ * @return the value returned the called ruby function
+ */
+VALUE FunCallWrap(VALUE rdata) {
+  struct my_callback* data = (struct my_callback*) rdata;
+  return rb_funcall2(data->obj,data->method_id,data->nargs,data->args);
+}
+
+/**
+ * Print the Ruby Stack Trace in an ows:ExceptionReport XML Document
+ *
+ * @param m the conf maps containing the main.cfg settings
+ * @see printExceptionReportResponse
+ */
+void ruby_trace_error(maps* m){
+#if RUBY_VERSION_MINOR == 8
+  VALUE lasterr = rb_gv_get("$!");
+#else
+  VALUE lasterr = rb_errinfo();
+  VALUE ruby_errinfo = lasterr;
+#endif
+  VALUE message = rb_obj_as_string(lasterr);
+  VALUE lklass = rb_class_path(CLASS_OF(lasterr));
+#if RUBY_VERSION_MINOR == 8
+  char *trace=(char*)malloc((strlen(RSTRING(lklass)->ptr)+strlen(RSTRING(message)->ptr)+3)*sizeof(char));
+  sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message));
+#else
+  char *trace=(char*)malloc((strlen(RSTRING_PTR(lklass))+strlen(RSTRING_PTR(message))+3)*sizeof(char));
+  sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message));
+#endif
+  if(!NIL_P(ruby_errinfo))
+    {
+      VALUE ary = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0);
+      int c;
+      for (c=0; c<RARRAY_LEN(ary); c++) {
+	int len=strlen(trace);
+	char *tmp0=zStrdup(trace);
+#if RUBY_VERSION_MINOR == 8
+	trace=(char *) realloc(trace,(len+strlen(RSTRING(RARRAY(ary)->ptr[c])->ptr)+2)*sizeof(char));
+	sprintf(trace,"%s\n%s",tmp0,RSTRING(RARRAY(ary)->ptr[c])->ptr);
+#else
+	trace=(char *) realloc(trace,(len+strlen(RSTRING_PTR(RARRAY_PTR(ary)[c]))+2)*sizeof(char));
+	sprintf(trace,"%s\n%s",tmp0,RSTRING_PTR(RARRAY_PTR(ary)[c]));
+#endif
+	free(tmp0);
+      }
+    }
+  map* err=createMap("text",trace);
+  addToMap(err,"code","NoApplicableCode");
+  printExceptionReportResponse(m,err);
+}
+
+/**
+ * Convert a maps to a Ruby Hash
+ *
+ * @param t the maps to convert
+ * @return a new Ruby Hash
+ */
+VALUE RubyHash_FromMaps(maps* t){
+  VALUE res=rb_hash_new();
+  maps* tmp=t;
+  while(tmp!=NULL){
+    VALUE value=RubyHash_FromMap(tmp->content);
+    VALUE name=rb_str_new2(tmp->name);
+    rb_hash_aset(res,name,value);
+    tmp=tmp->next;
+  }  
+  return res;
+}
+
+/**
+ * Push the key on the array
+ *
+ * @param key the key to push
+ * @param value not used
+ * @param ary the Array
+ * @return ST_CONTINUE
+ */
+int
+keys_i(VALUE key,VALUE value,VALUE ary)
+{
+  if (key == Qundef) return ST_CONTINUE;
+  rb_ary_push(ary, key);
+  return ST_CONTINUE;
+}
+
+/**
+ * Return the size of a Ruby Hash
+ * 
+ * @param hash the input Hash
+ */
+VALUE
+rb_hash_size(VALUE hash)
+{
+    return INT2FIX(RHASH_TBL(hash)->num_entries);
+}
+
+/**
+ * Convert a map to a Ruby Hash
+ *
+ * @param t the map to convert
+ * @return a new Ruby Hash
+ */
+VALUE RubyHash_FromMap(map* t){
+  VALUE res=rb_hash_new( );
+  map* tmp=t;
+  int hasSize=0;
+  map* isArray=getMap(tmp,"isArray");
+  map* size=getMap(tmp,"size");
+  map* tmap=getMapType(tmp);
+  while(tmp!=NULL){
+    VALUE name= rb_str_new2(tmp->name);
+    if(strcasecmp(tmp->name,"value")==0) {
+      if(isArray!=NULL){
+	map* len=getMap(tmp,"length");
+	int cnt=atoi(len->value);
+	VALUE value=rb_ary_new2(cnt);
+	VALUE mvalue=rb_ary_new2(cnt);
+	VALUE svalue=rb_ary_new2(cnt);
+
+	for(int i=0;i<cnt;i++){
+	  
+	  map* vMap=getMapArray(tmp,"value",i);	    
+	  map* sMap=getMapArray(tmp,"size",i);
+
+	  if(vMap!=NULL){
+	    
+	    VALUE lvalue;
+	    VALUE lsvalue;
+	    if(sMap==NULL){
+	      lvalue=rb_str_new2(vMap->value);
+	      lsvalue=Qnil;
+	    }
+	    else{
+	      lvalue=rb_str_new(vMap->value,atoi(sMap->value));
+	      lsvalue=rb_str_new2(sMap->value);
+	      hasSize=1;
+	    }
+
+	    rb_ary_push(value,lvalue);
+	    rb_ary_push(svalue,lsvalue);
+	  }
+	  
+	  map* mMap=getMapArray(tmp,tmap->name,i);
+
+	  VALUE lmvalue;
+	  if(mMap!=NULL){
+	    lmvalue=rb_str_new2(mMap->value);
+	  }else
+	    lmvalue=Qnil;
+	  rb_ary_push(mvalue,lmvalue);
+	  
+	}
+
+	rb_hash_aset(res, name, mvalue);
+	rb_hash_aset(res, rb_str_new2(tmap->name), mvalue);
+      
+	if(hasSize>0){
+	  VALUE lname=rb_str_new2("size");
+	  rb_hash_aset(res, lname, value);
+	}
+      }
+      else if(size!=NULL){
+	VALUE value=rb_str_new(tmp->value,atoi(size->value));
+	rb_hash_aset(res, name, value);
+      }
+      else{
+	VALUE value=rb_str_new2(tmp->value);
+	rb_hash_aset(res, name, value);
+      }
+    }
+    else{
+      VALUE value=rb_str_new2(tmp->value);
+      rb_hash_aset(res, name, value);
+    }
+    tmp=tmp->next;
+  }
+  return res;
+}
+
+/**
+ * Convert a Ruby Hash to a maps
+ *
+ * @param t the Ruby Hash to convert
+ * @return a new maps
+ */
+maps* mapsFromRubyHash(VALUE t){
+  maps* res=NULL;
+  maps* cursor=res;
+  VALUE list;
+  list = rb_ary_new();
+  typedef int (*HOOK)(...);
+  rb_hash_foreach(t, reinterpret_cast<HOOK>(keys_i), list);
+  int nb=rb_hash_size(t);
+  int i;
+  for(i=0;i<FIX2INT(nb);i++){
+    VALUE key=rb_ary_pop(list);
+    VALUE value=rb_hash_aref(t,key);
+#ifdef DEBUG
+    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
+	    StringValueCStr(key),StringValueCStr(value));
+#endif
+    cursor=(maps*)malloc(MAPS_SIZE);
+    cursor->name=StringValueCStr(key);
+    cursor->content=mapFromRubyHash(value);
+    cursor->next=NULL;
+    if(res==NULL)
+      res=dupMaps(&cursor);
+    else
+      addMapsToMaps(&res,cursor);
+    freeMap(&cursor->content);
+    free(cursor->content);
+    free(cursor);
+  }
+  return res;
+}
+
+/**
+ * Convert a Ruby Hash to a map
+ *
+ * @param t the Ruby Hash to convert
+ * @return a new map
+ */
+map* mapFromRubyHash(VALUE t){
+  map* res=NULL;
+  VALUE list;
+  list = rb_ary_new();
+  typedef int (*HOOK)(...);
+  rb_hash_foreach(t,reinterpret_cast<HOOK>(keys_i), list);
+  int nb=RHASH_TBL(t)->num_entries;
+  int i;
+  for(i=0;i<nb;i++){
+    VALUE key=rb_ary_pop(list);
+    VALUE value=rb_hash_aref(t,key);
+#ifdef DEBUG
+    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
+	    StringValueCStr(key),StringValueCStr(value));
+#endif
+    if(strcmp(StringValueCStr(key),"value")==0){
+      char *buffer=NULL;
+      int size=RSTRING_LEN(value);
+      buffer=StringValueCStr(value);
+      if(res!=NULL){
+	addToMap(res,StringValueCStr(key),"");
+      }else{
+	res=createMap(StringValueCStr(key),"");
+      }
+      map* tmpR=getMap(res,"value");
+      free(tmpR->value);
+      tmpR->value=(char*)malloc((size+1)*sizeof(char));
+      memmove(tmpR->value,buffer,size*sizeof(char));
+      tmpR->value[size]=0;
+      char sin[1024];
+      sprintf(sin,"%d",size);
+      addToMap(res,"size",sin);
+    }else{
+      if(res!=NULL){
+	addToMap(res,StringValueCStr(key),StringValueCStr(value));
+      }
+      else{
+	res=
+	  createMap(StringValueCStr(key),StringValueCStr(value));
+      }
+    }
+  }
+  return res;
+}
+
+/**
+ * Use the ZOO-Services messages translation function from the Ruby
+ * environment (ZOO-API)
+ *
+ * @param argc the number of parameters
+ * @param argv the parameter values given from the Ruby environment
+ * @param obj the Ruby object on which we run the method
+ * @return a new Ruby string containing the translated value
+ * @see _ss
+ */
+VALUE
+RubyTranslate(int argc, VALUE *argv, VALUE obj)
+{
+  return rb_str_new2(_ss(StringValueCStr(argv[0])));
+}
+
+/**
+ * Update the ongoing status of a running service from the Ruby environment
+ * (ZOO-API)
+ *
+ * @param argc the number of parameters
+ * @param argv the parameter values given from the Ruby environment
+ * @param obj the Ruby object on which we run the method
+ * @return a new Ruby string containing the translated value
+ * @see _updateStatus
+ */
+VALUE
+RubyUpdateStatus(int argc, VALUE *argv, VALUE obj)
+{
+  maps* conf;
+  VALUE confdict=argv[0];
+  int istatus=argv[1];
+  char* status;
+  if (istatus < 0 || istatus > 100){
+    fprintf(stderr,"Status must be a percentage.");
+    return Qnil;
+  }else{
+     char tmpStatus[4];
+     snprintf(tmpStatus, 4, "%i", istatus);
+     status = zStrdup(tmpStatus);
+  }
+  /* now update the map */
+  {
+    VALUE lenv = rb_hash_aref(confdict,rb_str_new2("lenv"));
+    if(TYPE(lenv)!=T_NIL){
+      VALUE valobj=rb_str_new2(status);
+      rb_hash_aset(lenv,rb_str_new2("status"),valobj);
+    }
+  }
+  conf = mapsFromRubyHash(confdict);
+  if (getMapFromMaps(conf,"lenv","status") != NULL){
+    fprintf(stderr,"STATUS RETURNED : %s\n",status);
+    if(status!=NULL){
+      setMapInMaps(conf,"lenv","status",status);
+      free(status);
+    }
+    else
+      setMapInMaps(conf,"lenv","status","15");
+    _updateStatus(conf);
+  }
+  freeMaps(&conf);
+  free(conf);
+  return Qnil;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_ruby.h	(revision 672)
@@ -0,0 +1,78 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2014 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_RUBY_H
+#define ZOO_SERVICE_INTERNAL_RUBY_H 1
+
+#pragma once 
+
+#define RUBY_GLOBAL_SETUP
+#undef NEED_STRLCAT
+#undef NEED_STRLCPY
+#include "service.h"
+#include "service_internal.h"
+#undef RUBY_EXPORT
+#undef STRCASECMP
+#undef STRNCASECMP
+#undef _
+#include <ruby.h>
+#if ZRUBY_VERSION < 2
+#include <version.h>
+#else
+#include <ruby/version.h>
+#endif
+#if RUBY_VERSION_MINOR==8
+#include <st.h>
+#else
+#include <ruby/st.h>
+#endif
+
+#define MAX_ARGS 3
+/**
+ * The Ruby method pointer
+ */
+struct my_callback {
+  VALUE obj; //!< Object used to call a method
+  ID method_id; //!< The method to call
+  int nargs; //!< The arguments number
+  VALUE args[MAX_ARGS]; //!< The arguments values
+};
+
+void ruby_trace_error(maps*);
+VALUE FunCallWrap(VALUE);
+VALUE LoadWrap(VALUE);
+
+VALUE RubyHash_FromMaps(maps*);
+VALUE RubyHash_FromMap(map*);
+
+maps* mapsFromRubyHash(VALUE);
+void createMapsFromRubyHash(maps**,VALUE);
+map* mapFromRubyHash(VALUE);
+
+int zoo_ruby_support(maps**,map*,service*,maps**,maps**);
+
+VALUE RubyTranslate(int,VALUE*,VALUE);
+VALUE RubyUpdateStatus(int,VALUE*,VALUE);
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.c	(revision 672)
@@ -0,0 +1,1186 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <limits.h>
+#include <locale.h>
+#include <wx/string.h>
+#include <wx/app.h>
+#include <api_core.h>
+#include <data_manager.h>
+#include <module_library.h>
+#define _ZOO_SAGA
+#include "service_internal_saga.h"
+#include "server_internal.h"
+#include "mimetypes.h"
+
+/**
+ * Global SAGA-GIS output counter 
+ */
+int sagaOutputCounter=0;
+
+/**
+ * Observer used to access the ongoing status of a running OTB Application
+ */
+class SagaWatcher
+{
+ public:
+  static int Callback(TSG_UI_Callback_ID ID, CSG_UI_Parameter &Param_1, CSG_UI_Parameter &Param_2);
+  /** 
+   * Define the message value
+   *
+   * @param conf the maps pointer to copy
+   */
+  static void SetMessage(const char *mess)
+  {
+    FreeMessage();
+    message=zStrdup(mess);
+  }
+  /** 
+   * Free the message value
+   *
+   */
+  static void FreeMessage()
+  {
+    if(message!=NULL)
+      free(message);
+    message=NULL;
+  }
+  /** 
+   * Copy the original conf in the m_conf property
+   *
+   * @param conf the maps pointer to copy
+   */
+  void SetConf(maps **conf)
+  {
+    m_conf=dupMaps(conf);
+  }
+  /**  
+   * Get Configuration maps (m_conf)
+   * @return the m_conf property
+   */
+  const maps& GetConf()
+  {
+    return *m_conf;
+  }
+  /**  
+   * Free Configuration maps (m_Conf)
+   */
+  void FreeConf(){
+    freeMaps(&m_conf);
+    free(m_conf);
+  }
+ private:
+  /** Main conf maps */
+  static maps* m_conf;
+  /** Status */
+  static int status;
+  /** Message */
+  static char* message;
+};
+
+maps* SagaWatcher::m_conf;
+char* SagaWatcher::message=zStrdup("No message left");
+int SagaWatcher::status=1;
+
+/**
+ * The callback function called at any SAGA-GIS module step
+ *
+ * @param id a TSG_UI_Callback_ID as defined in api_core.h (line 1290)
+ * @param param1 
+ * @param param2
+ */
+int
+SagaWatcher::
+Callback(TSG_UI_Callback_ID id, CSG_UI_Parameter &param1, CSG_UI_Parameter &param2)
+{
+
+  int res = 1;
+  switch( id )
+    {
+    default:
+      return 0;
+      break;
+
+    case CALLBACK_DLG_ERROR:
+      return 1;
+      break;
+
+    case CALLBACK_DLG_PARAMETERS:
+    case CALLBACK_PROCESS_SET_OKAY:
+    case CALLBACK_DATAOBJECT_COLORS_GET:
+    case CALLBACK_DATAOBJECT_COLORS_SET:
+    case CALLBACK_DATAOBJECT_PARAMS_GET:
+    case CALLBACK_DATAOBJECT_PARAMS_SET:
+    case CALLBACK_DATAOBJECT_UPDATE:
+    case CALLBACK_DATAOBJECT_SHOW:
+    case CALLBACK_DLG_CONTINUE:
+    case CALLBACK_PROCESS_SET_READY:
+    case CALLBACK_PROCESS_GET_OKAY:
+      return res;
+      break;
+
+    case CALLBACK_PROCESS_SET_PROGRESS:
+      {
+	int cPercent= param2.Number != 0.0 ? 1 + (int)(100.0 * param1.Number / param2.Number) : 100 ;
+	if( cPercent != status ){
+	  status=cPercent;
+	}else
+	  return res;
+      }
+      break;
+
+    case CALLBACK_PROCESS_SET_TEXT:
+      SetMessage(param1.String.b_str());
+      break;
+
+    case CALLBACK_MESSAGE_ADD:
+      SetMessage(param1.String.b_str());
+      break;
+
+    case CALLBACK_MESSAGE_ADD_ERROR:
+      SetMessage(param1.String.b_str());
+      break;
+
+    case CALLBACK_MESSAGE_ADD_EXECUTION:
+      SetMessage(param1.String.b_str());
+      break;
+
+    case CALLBACK_DLG_MESSAGE:
+      SetMessage((param2.String + ": " + param1.String).b_str());
+      break;
+
+    case CALLBACK_DATAOBJECT_ADD:
+      if(SG_Get_Data_Manager().Add((CSG_Data_Object *)param1.Pointer))
+	res = 1 ;
+      else
+	res = 0;
+      return res;
+      break;
+
+    }
+  updateStatus(m_conf,status,message);
+  return( res );
+}
+
+TSG_PFNC_UI_Callback Get_Callback (SagaWatcher watcher){
+  return( &(watcher.Callback) );
+}
+
+
+/**
+ * Get the default file extension for SAGA-GIS parameter type.
+ * Extensions are the following:
+ *  - sgrd for grid and data_object
+ *  - shp for shapes and tin
+ *  - csv for tables
+ *  - spc for points
+ *
+ * @param param a SAGA-GIS Parameter
+ */ 
+const char* sagaGetDefaultExt(CSG_Parameter* param){
+  if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))
+     || CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("data_object"))){
+    return "sgrd";
+  }
+  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes")) ||
+	  CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
+    return "shp";
+  }
+  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
+    return "csv";
+  }
+  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
+    return "spc";
+  }
+  return "unknown";
+}
+
+/**
+ * Load a datasource in the SAGA-GIS Data Manager.
+ *
+ * @param param a SAGA-GIS Parameter
+ * @param arg the arguments map passed to a SAGA-GIS module
+ * @return false on failure, true in case of success
+ */
+bool sagaLoadInput(CSG_Parameter* param,map* arg){
+  if(!param->is_Input() || !param->is_Enabled()){
+    return true;
+  }
+  map* carg=getMap(arg,CSG_String(param->Get_Identifier()).b_str());
+  if(carg!=NULL){
+    wxString fileName(carg->value);
+    if(param->is_DataObject()){
+      // In case it there is a single datasource
+      if(!SG_Get_Data_Manager().Find(&fileName) && !SG_Get_Data_Manager().Add(&fileName) && !param->is_Optional() ){
+	return false;
+      }
+      return( param->Set_Value(SG_Get_Data_Manager().Find(&fileName)) );
+    }
+    else
+      if(param->is_DataObject_List()){
+	// In case there are multiple datasources
+	param->asList()->Del_Items();
+	wxString fileNames(fileName);
+	while( fileNames.Length() > 0 ){
+	  fileName = fileNames.BeforeFirst(';').Trim(false);
+	  fileNames = fileNames.AfterFirst (';');	    
+	  if( !SG_Get_Data_Manager().Find(&fileName) ){
+	    SG_Get_Data_Manager().Add(&fileName);
+	  }
+	  param->asList()->Add_Item(SG_Get_Data_Manager().Find(&fileName));
+	}
+      }
+  }
+  return true;
+}
+
+/**
+ * Extract all SAGA-GIS parameters from a parameters list and set its values to
+ * the one defined in the map.
+ *
+ * @parap params the parameters list
+ * @parap argument the argument map containing the value to use
+ * @return true in success, false in other case
+ */
+bool sagaSetParameters(CSG_Parameters *params,map* argument){
+
+  int pc=params->Get_Count();
+  params->Restore_Defaults();
+
+  for(int k=0;k<pc;k++){
+    CSG_Parameter * param=params->Get_Parameter(k);
+    if( param->is_Output() ){
+      map* omap=getMap(argument,CSG_String(param->Get_Identifier()).b_str());
+      if( param->is_DataObject() && param->is_Optional() && !param->asDataObject() && omap!=NULL){
+	param->Set_Value(DATAOBJECT_CREATE);
+      }
+    }
+    else
+      if( param->is_Option() && !param->is_Information() ){
+	map* inmap=getMap(argument,CSG_String(param->Get_Identifier()).b_str());
+	if(inmap!=NULL){
+	    switch( param->Get_Type() ){
+	    case PARAMETER_TYPE_Bool:
+	      if(strncasecmp(inmap->value,"true",4)==0 || strncasecmp(inmap->value,"1",1)==0){
+		param->Set_Value(1);
+	      }else
+		param->Set_Value(0);
+	      break;
+	    case PARAMETER_TYPE_Parameters:
+	      // TODO: nested inputs gesture
+	      break;
+	    case PARAMETER_TYPE_Int:
+	      param->Set_Value((int)strtol(inmap->value,NULL,10));
+	      break;
+	    case PARAMETER_TYPE_Double:
+	    case PARAMETER_TYPE_Degree:
+	      param->Set_Value((double)strtod(inmap->value,NULL));
+	      break;
+	    case PARAMETER_TYPE_String:
+	      param->Set_Value(CSG_String(inmap->value));
+	      break;
+	    case PARAMETER_TYPE_FilePath:
+	      param->Set_Value(CSG_String(inmap->value));
+	      break;
+	    case PARAMETER_TYPE_FixedTable:
+	      {
+		CSG_Table Table(inmap->value);
+		param->asTable()->Assign_Values(&Table);
+	      }
+	      break;
+	    case PARAMETER_TYPE_Choice:
+	      {
+		int val=(int)strtol(inmap->value,(char**)NULL,10);
+		if(val==0 && strncasecmp(inmap->value,"0",1)!=0)
+		  param->Set_Value(CSG_String(inmap->value));
+		else
+		  param->Set_Value(val);
+	      }
+	      break;
+	    default:
+	      break;
+	    }
+	}else{
+	  if(param->Get_Type()==PARAMETER_TYPE_Range){
+	    inmap=getMap(argument,(CSG_String(param->Get_Identifier())+"_MIN").b_str());
+	    if(inmap!=NULL)
+	      param->asRange()->Set_LoVal(strtod(inmap->value,NULL));
+	    inmap=getMap(argument,(CSG_String(param->Get_Identifier())+"_MAX").b_str());
+	    if(inmap!=NULL)
+	      param->asRange()->Set_HiVal(strtod(inmap->value,NULL));	    
+	  }
+	  if(inmap==NULL){
+	    param->Restore_Default();
+	  }
+	}
+      }
+  }
+
+  for(int k=0;k<pc;k++){
+    CSG_Parameter * param=params->Get_Parameter(k);
+    if( param->is_Input() )
+      if(!sagaLoadInput(param,argument)){
+	fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
+	return false;
+      }
+  }
+  return true;
+}
+
+/**
+ * Save all values outputed by a SAGA-GIS module invocation to files
+ *
+ * @param params the parameters list
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param outputs the maps to set the generated_file for each output
+ */
+bool sagaSaveOutputs(CSG_Parameters *params,maps* main_conf,maps** outputs)
+{
+  for(int j=0; j<params->Get_Count(); j++)
+    {
+      CSG_Parameter *param = params->Get_Parameter(j);
+      maps* cMaps=getMaps(*outputs,CSG_String(param->Get_Identifier()).b_str());
+      // Specific TIN case
+      if(cMaps==NULL && CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin")))
+	cMaps=getMaps(*outputs,(CSG_String(param->Get_Identifier())+"_POINTS").b_str());
+      if(cMaps!=NULL){
+	map* tmpPath=getMapFromMaps(main_conf,"main","tmpPath");
+	map* sid=getMapFromMaps(main_conf,"lenv","usid");
+	const char *file_ext=sagaGetDefaultExt(param);
+
+	if( param->is_Input() )
+	  {
+	    if( param->is_DataObject() )
+	      {
+		CSG_Data_Object *pObject = param->asDataObject();
+		
+		if( pObject && pObject->is_Modified() && SG_File_Exists(pObject->Get_File_Name()) )
+		  {
+		    pObject->Save(pObject->Get_File_Name());
+		    addToMap(cMaps->content,"generated_file",CSG_String(pObject->Get_File_Name()).b_str());
+		  }
+	      }
+	    
+	    else if( param->is_DataObject_List() )
+	      {
+		for(int i=0; i<param->asList()->Get_Count(); i++)
+		  {
+		    CSG_Data_Object *pObject = param->asList()->asDataObject(i);
+		    
+		    if( pObject->is_Modified() && SG_File_Exists(pObject->Get_File_Name()) )
+		      {
+			pObject->Save(pObject->Get_File_Name());
+			setMapArray(cMaps->content,"generated_file",i,CSG_String(pObject->Get_File_Name()).b_str());
+		      }
+		  }
+	      }
+	  }
+	else
+	  if( param->is_Output() )
+	    {
+	      char *realFileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(cMaps->name)+14)*sizeof(char));
+	      char *fullFileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(cMaps->name)+strlen(tmpPath->value)+16)*sizeof(char));
+	      sprintf(realFileName,"Output_%s_%s_%d",cMaps->name,sid->value,sagaOutputCounter);
+	      sprintf(fullFileName,"%s/Output_%s_%s_%d.%s",tmpPath->value,cMaps->name,sid->value,sagaOutputCounter,file_ext);
+	      sagaOutputCounter+=1;
+	      wxString fileName(fullFileName);
+	      addToMap(cMaps->content,"generated_name",realFileName);
+	      free(realFileName);
+	      free(fullFileName);
+
+	      if( param->is_DataObject() )
+		{
+		  if( param->asDataObject() )
+		    {
+		      param->asDataObject()->Save(&fileName);
+		      addToMap(cMaps->content,"generated_file",CSG_String(param->asDataObject()->Get_File_Name()).b_str());
+		    }
+		}
+	    
+	      else if( param->is_DataObject_List() )
+		{
+		  CSG_Strings	fileNames;
+		
+		  while( fileName.Length() > 0 )
+		    {
+		      CSG_String current_file(&fileName);
+		      current_file = current_file.BeforeFirst(';');
+		      if( current_file.Length() > 0 )
+			{
+			  fileNames += current_file;
+			  fileName = fileName.AfterFirst(';');
+			}
+		      else
+			{
+			  fileNames += &fileName;
+			  fileName.Clear();
+			}
+		    }
+		  
+		  int nFileNames = param->asList()->Get_Count() <= fileNames.Get_Count() ? fileNames.Get_Count() : fileNames.Get_Count() - 1;
+		  for(int i=0; i<param->asList()->Get_Count(); i++)
+		    {
+		      fileNames[i].Trim();
+		      if( i < nFileNames )
+			{
+			  param->asList()->asDataObject(i)->Save(fileNames[i]);
+			}
+		      else
+			{
+			  param->asList()->asDataObject(i)->Save(CSG_String::Format(SG_T("%s_%0*d"),
+										    fileNames[fileNames.Get_Count() - 1].c_str(),
+										    SG_Get_Digit_Count(param->asList()->Get_Count()),
+										    1 + i - nFileNames
+										    ));
+			}
+		      setMapArray(cMaps->content,"generated_file",i,
+				  CSG_String(param->asList()->asDataObject(i)->Get_File_Name()).b_str());
+		    }
+		}
+	    }
+      }
+    }
+  return( true );
+}
+
+/**
+ * Invoke the execution of a SAGA-GIS module.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param lib_name the SAGA-GIS library name
+ * @param module_name the SAGA-GIS module name
+ * @param arguments the map containing the arguments to pass to the module
+ * @param outputs default to NULL, contains the maps to fill with the result
+ */
+int sagaExecuteCmd(maps** main_conf,const char* lib_name,const char* module_name,map* arguments,maps** outputs=NULL){
+  int res=SERVICE_FAILED;
+
+  CSG_Module_Library * library=SG_Get_Module_Library_Manager().Get_Library(CSG_String(lib_name),true);
+  if( library == NULL){
+    char tmp[255];
+    sprintf(tmp,"Counld not load the %s SAGA library",lib_name);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+
+  CSG_Module * module=library->Get_Module(atoi(module_name));
+  if(module == NULL){
+    char tmp[255];
+    sprintf(tmp,"Counld not load the %s module from the %s SAGA library",module_name,lib_name);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+
+  CSG_Parameters * params=module->Get_Parameters();
+  if(!params){
+    char tmp[255];
+    sprintf(tmp,"Counld not find any param for the %s module from the %s SAGA library",module_name,lib_name);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+  
+  sagaSetParameters(params,arguments);
+
+  module->Update_Parameter_States();
+
+  bool retval=false;
+  if(module->On_Before_Execution()){
+    retval=module->Execute();
+    module->On_After_Execution();
+  }
+  
+  if(retval && outputs!=NULL){
+    sagaSaveOutputs(module->Get_Parameters(),*main_conf,outputs);
+    SG_Get_Data_Manager().Delete_Unsaved();
+    return SERVICE_SUCCEEDED;
+  }
+
+  return SERVICE_FAILED;
+
+}
+
+/**
+ * Export a SAGA-GIS Shapes to a file in a specific format (GML,KML,GeoJSON).
+ * saga_cmd io_gdal 4 -FILE my.format -SHAPES my.shp -FORMAT XXX
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param in the output maps to fill with the resulting file
+ */
+int sagaExportOGR(maps** conf, maps** in){
+  map* mtype=getMap((*in)->content,"mimeType");
+  map* gfile=getMap((*in)->content,"generated_file");
+  char* fext=NULL;
+  map* arg=NULL;
+  if(strncasecmp(mtype->value,"text/xml",8)==0){
+    fext=zStrdup("xml");
+  }
+  else if(strncasecmp(mtype->value,"application/json",16)==0){
+    fext=zStrdup("json");
+  }
+  else{
+    fext=zStrdup("kml");
+  }
+  char* tmpName=(char*)malloc((strlen(gfile->value)+2)*sizeof(char));
+  strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
+  strncpy(&tmpName[0]+(strlen(gfile->value)-3),fext,(strlen(fext))*sizeof(char));
+  tmpName[strlen(fext)+(strlen(gfile->value)-3)]=0;
+  arg=createMap("SHAPES",gfile->value);
+  addToMap(arg,"FILE",tmpName);
+  if(strncasecmp(mtype->value,"text/xml",8)==0){
+    addToMap(arg,"FORMAT","GML");
+  }
+  else if(strncasecmp(mtype->value,"application/json",16)==0){
+    addToMap(arg,"FORMAT","GeoJSON");
+  }
+  else{
+    addToMap(arg,"FORMAT","LIBKML");
+  }
+  free(fext);
+  free(gfile->value);
+  gfile->value=zStrdup(tmpName);
+  free(tmpName);
+  
+  sagaExecuteCmd(conf,"io_gdal","4",arg);
+  freeMap(&arg);
+  free(arg);
+}
+
+/**
+ * Export a SAGA-GIS pointcloud to a las file.
+ * saga_cmd io_shapes_las 0 -POINTS my.spc -FILE my.las
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param in the output maps to fill with the resulting file
+ */
+void sagaExportPC(maps** conf, maps** in){
+  map* mtype=getMap((*in)->content,"mimeType");
+  map* gfile=getMap((*in)->content,"generated_file");
+  char* fext="las";
+  map* arg=NULL;
+  char* tmpName=(char*)malloc((strlen(gfile->value)+2)*sizeof(char));
+  strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
+  strncpy(&tmpName[0]+(strlen(gfile->value)-3),fext,(strlen(fext))*sizeof(char));
+  tmpName[strlen(fext)+(strlen(gfile->value)-3)]=0;
+  arg=createMap("POINTS",gfile->value);
+  addToMap(arg,"FILE",tmpName);
+  free(gfile->value);
+  gfile->value=zStrdup(tmpName);
+  sagaExecuteCmd(conf,"io_shapes_las","0",arg);
+  freeMap(&arg);
+  free(arg);
+  free(tmpName);
+}
+
+/**
+ * Export a SAGA-GIS Grid to a file in a specific format (tiff,hdr,aa).
+ * saga_cmd io_gdal 1 -FILE my.format -GRIDS my.sgrd -FORMAT XXX
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param in the output maps to fill with the resulting file
+ */
+int sagaExportGDAL(maps** conf, maps** in/*,CSG_Parameter* param*/){
+  map* mtype=getMap((*in)->content,"extension");
+  map* gfile=getMap((*in)->content,"generated_file");
+  char* fext=NULL;
+  map* arg;
+
+  if(mtype!=NULL)
+    fext=zStrdup(mtype->value);
+  else{
+    fext=zStrdup("tiff");
+  }
+
+  mtype=getMap((*in)->content,"mimeType");
+  if(strncasecmp(mtype->value,"image/tiff",10)==0){
+    arg=createMap("FORMAT","1");
+  }
+  else if(strncasecmp(mtype->value,"application/x-ogc-envi",22)==0){
+    arg=createMap("FORMAT","ENVI .hdr Labelled");
+  }
+  else{
+    arg=createMap("FORMAT","ARC Digitized Raster Graphics");
+  }
+
+  if(gfile!=NULL){
+    char* tmpName=(char*)malloc((strlen(gfile->value)+1)*sizeof(char));
+    strncpy(tmpName,gfile->value,(strlen(gfile->value)-4)*sizeof(char));
+    strncpy(&tmpName[0]+(strlen(gfile->value)-4),fext,(strlen(fext))*sizeof(char));
+    tmpName[strlen(fext)+(strlen(gfile->value)-4)]=0;
+    addToMap(arg,"FILE",tmpName);
+    addToMap(arg,"GRIDS",gfile->value);
+    free(tmpName);
+    free(fext);
+    free(gfile->value);
+    map* tmp=getMap(arg,"FILE");
+    gfile->value=zStrdup(tmp->value);
+    sagaExecuteCmd(conf,"io_gdal","1",arg);
+  }
+  else{
+    // Empty result
+    return true;
+  }
+  freeMap(&arg);
+  free(arg);
+}
+
+/**
+ * Export a SAGA-GIS TIN to a file in a specific format (GML,KML,GeoJSON).
+ * Exporting TIN produce 5 separated files (POINTS, CENTER, EDGES, TRIANGLES 
+ * and POLYGONS). Even if a client can choose which result it want to have,
+ * SAGA-GIS module will be invoked in a way that it will produce in any case
+ * each possible outputs. The selection of a specific output is made in the 
+ * ZOO-Kernel itself and not specifically at this level.
+ * saga_cmd tin_tools 3 -TIN my.shp -POINTS p.shp ...
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in the output maps to fill with the resulting file
+ * @see sagaExportOGR
+ */
+int sagaExportTIN(maps** conf, maps** in,const char* tname/*,CSG_Parameter* param*/){
+  map* mtype=getMap((*in)->content,"mimeType");
+  map* gfile=getMap((*in)->content,"generated_file");
+  char* fext="shp";
+  map* arg=createMap("TIN",gfile->value);
+
+  char* tinOut[5]={
+    "POINTS",
+    "CENTER",
+    "EDGES",
+    "TRIANGLES",
+    "POLYGONS"
+  };
+  maps* resouts=NULL;
+
+  int i=0;
+  for(i=0;i<5;i++){
+    char* tmpName=(char*)malloc((strlen(gfile->value)+strlen(tinOut[i])+4)*sizeof(char));
+    strncpy(tmpName,gfile->value,(strlen(gfile->value)-3)*sizeof(char));
+    char *tmpSubName=(char*) malloc((strlen(tinOut[i])+3)*sizeof(char));
+    sprintf(tmpSubName,"_%s.",tinOut[i]);
+    strncpy(&tmpName[0]+(strlen(gfile->value)-4),tmpSubName,(strlen(tmpSubName))*sizeof(char));
+    strncpy(&tmpName[0]+(strlen(gfile->value)+strlen(tmpSubName)-4),fext,(strlen(fext))*sizeof(char));
+    tmpName[strlen(fext)+(strlen(gfile->value)+strlen(tmpSubName)-4)]=0;
+
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup(tinOut[i]);
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+    
+    addToMap(arg,tinOut[i],tmpName);
+    
+    free(tmpName);
+    if(resouts==NULL)
+      resouts=dupMaps(&louts);
+    else
+      addMapsToMaps(&resouts,louts);
+    freeMaps(&louts);
+    free(louts);
+  }
+  
+  sagaExecuteCmd(conf,"tin_tools","3",arg,&resouts);
+
+  for(i=0;i<5;i++){
+    map* generatedFile=getMapFromMaps(resouts,tinOut[i],"generated_file");
+    setMapInMaps(*in,(CSG_String(tname)+"_"+tinOut[i]).b_str(),"generated_file",generatedFile->value);
+    maps* cout=getMaps(*in,(CSG_String(tname)+"_"+tinOut[i]).b_str());
+    sagaExportOGR(conf,&cout);
+  }
+  return true;
+}
+
+/**
+ * Import GDAL Datasource into SAGA-GIS.
+ * saga_cmd io_gdal 0 -TRANSFORM 0 -FILES my.format -GRIDS /tmpPath/MyGridXXX.sgrd
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in in the inputs maps
+ */
+int sagaImportGDAL(maps** conf, maps** in){
+  map* l=getMap((*in)->content,"length");
+  bool shouldClean=false;
+  if(l==NULL){
+    l=createMap("length","1");
+    shouldClean=true;
+  }
+  int len=strtol(l->value,NULL,10);
+  int i=0;
+  for(i=0;i<len;i++){
+    map* arg=createMap("TRANSFORM","0");
+    addToMap(arg,"INTERPOL","4");
+    map* v=getMapArray((*in)->content,"cache_file",i);
+    if(v!=NULL)
+      addToMap(arg,"FILES",v->value);
+    addToMap(arg,"GRIDS","");
+
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup("GRIDS");
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+
+    sagaExecuteCmd(conf,"io_gdal","0",arg,&louts);
+
+    map* tmp=getMapFromMaps(louts,"GRIDS","generated_file");
+    setMapArray((*in)->content,"saga_value",i,tmp->value);
+
+    freeMaps(&louts);
+    free(louts);
+    freeMap(&arg);
+    free(arg);
+  }
+  if(shouldClean){
+    freeMap(&l);
+    free(l);
+  }
+}
+
+/**
+ * Import OGR Datasource into SAGA-GIS.
+ * saga_cmd io_gdal 3 -SHAPES my.shp -FILES my.format
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in in the inputs maps
+ */
+int sagaImportOGR(maps** conf, maps** in){
+  char *ext;
+  map* arg;
+  map* l=getMap((*in)->content,"length");
+  bool shouldClean=false;
+  if(l==NULL){
+    l=createMap("length","1");
+    shouldClean=true;
+  }
+  int len=strtol(l->value,NULL,10);
+  int i=0;
+  for(i=0;i<len;i++){
+    map* v=getMapArray((*in)->content,"cache_file",i);
+    arg=createMap("SHAPES","");
+    if(v!=NULL)
+      addToMap(arg,"FILES",v->value);
+
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup("SHAPES");
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+
+    sagaExecuteCmd(conf,"io_gdal","3",arg,&louts);
+
+    map* tmp=getMapFromMaps(louts,"SHAPES","generated_file");
+    setMapArray((*in)->content,"saga_value",i,tmp->value);
+
+    freeMaps(&louts);
+    free(louts);
+    freeMap(&arg);
+    free(arg);
+  }
+  if(shouldClean){
+    freeMap(&l);
+    free(l);
+  }
+}
+
+/**
+ * Import TIN into SAGA-GIS. Calling this function suppose that sagaImportOGR
+ * was called first.
+ * saga_cmd tin_tools 2 -SHAPES myShapes.shp -TIN myTin.shp
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in in the inputs maps
+ * @see sagaImportOGR
+ */
+bool sagaImportTIN(maps** conf, maps** in){
+  char *ext;
+  map* arg;
+  map* l=getMap((*in)->content,"length");
+  bool shouldClean=false;
+  if(l==NULL){
+    l=createMap("length","1");
+    shouldClean=true;
+  }
+  int len=strtol(l->value,NULL,10);
+  int i=0;
+  for(i=0;i<len;i++){
+    map* v=getMapArray((*in)->content,"saga_value",i);
+    arg=createMap("TIN","");
+    if(v!=NULL)
+      addToMap(arg,"SHAPES",v->value);
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup("TIN");
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+    sagaExecuteCmd(conf,"tin_tools","2",arg,&louts);
+    map* tmp=getMapFromMaps(louts,"TIN","generated_file");
+    v=getMapArray((*in)->content,"saga_value",i);
+    if(tmp!=NULL){
+      if(v!=NULL){
+	free(v->value);
+	v->value=zStrdup(tmp->value);
+      }
+      else
+	setMapArray((*in)->content,"saga_value",i,tmp->value);
+    }
+    freeMaps(&louts);
+    free(louts);
+    freeMap(&arg);
+    free(arg);
+  }
+  if(shouldClean){
+    freeMap(&l);
+    free(l);
+  }
+  return true;
+}
+
+/**
+ * Import table into SAGA-GIS. 
+ * saga_cmd io_table 1 -TABLE myTable -FILENAME myFile -SEPARATOR 2
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in in the inputs maps
+ */
+int sagaImportTable(maps** conf, maps** in){
+  char *ext;
+  map* arg;
+  map* l=getMap((*in)->content,"length");
+  bool shouldClean=false;
+  if(l==NULL){
+    l=createMap("length","1");
+    shouldClean=true;
+  }
+  int len=strtol(l->value,NULL,10);
+  int i=0;
+  for(i=0;i<len;i++){
+
+    // Create and fill arg map
+    arg=createMap("SEPARATOR","2");
+    addToMap(arg,"TABLE","");
+    map* v=getMapArray((*in)->content,"cache_file",i);
+    if(v!=NULL)
+      addToMap(arg,"FILENAME",v->value);
+
+    // Create the output maps
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup("TABLE");
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+
+    // Execute the saga command
+    sagaExecuteCmd(conf,"io_table","1",arg,&louts);
+
+    // Fetch result and add it to the original map as saga_value
+    map* tmp=getMapFromMaps(louts,"TABLE","generated_file");
+    setMapArray((*in)->content,"saga_value",i,tmp->value);
+
+    // Cleanup
+    freeMaps(&louts);
+    free(louts);
+    freeMap(&arg);
+    free(arg);
+
+  }
+  // Cleanup if required
+  if(shouldClean){
+    freeMap(&l);
+    free(l);
+  }
+}
+
+/**
+ * Import las file as pointcloud into SAGA-GIS. 
+ * saga_cmd io_shapes_las 1 -POINTS my.spc -FILENAME my.las
+ * 
+ * @param conf the conf maps containing the main.cfg settings
+ * @param in in the inputs maps
+ */
+int sagaImportPC(maps** conf, maps** in){
+  char *ext;
+  map* arg;
+  map* l=getMap((*in)->content,"length");
+  bool shouldClean=false;
+  if(l==NULL){
+    l=createMap("length","1");
+    shouldClean=true;
+  }
+  int len=strtol(l->value,NULL,10);
+  int i=0;
+  for(i=0;i<len;i++){
+
+    // Create and fill arg map
+    arg=createMap("POINTS","");
+    map* v=getMapArray((*in)->content,"cache_file",i);
+    if(v!=NULL)
+      addToMap(arg,"FILES",v->value);
+
+    // Create the output maps
+    maps* louts=(maps*)malloc(MAPS_SIZE);
+    louts->name=zStrdup("POINTS");
+    louts->content=createMap("mimeType","UNKOWN");
+    louts->next=NULL;
+
+    // Execute the saga command
+    sagaExecuteCmd(conf,"io_shapes_las","1",arg,&louts);
+
+    // Fetch result and add it to the original map as saga_value
+    map* tmp=getMapFromMaps(louts,"POINTS","generated_file");
+    setMapArray((*in)->content,"saga_value",i,tmp->value);
+
+    // Cleanup
+    freeMaps(&louts);
+    free(louts);
+    freeMap(&arg);
+    free(arg);
+
+  }
+  // Cleanup if required
+  if(shouldClean){
+    freeMap(&l);
+    free(l);
+  }
+}
+
+/**
+ * Load and invoke a SAGA-GIS module defined in a service metadata definitions.
+ * Load all the input data into SAGA-GIS using io_gdal, io_tables and 
+ * io_shapes_las for SAGA grids/shapes, tables and pointcloud respectively. 
+ * Load and run the module from its library and invoke it using the data 
+ * imported in SAGA-GIS at first stage. After the execution, export the outputs
+ * to files using io_gdal and io_shapes_las for grids/shapes and pointcloud 
+ * respectively.
+ *
+ * @param main_conf the conf maps containing the main.cfg settings
+ * @param request the map containing the HTTP request
+ * @param s the service structure
+ * @param inputs the maps containing the inputs
+ * @param outputs the maps containing the outputs
+ */
+int zoo_saga_support(maps** main_conf,map* request,service* s,maps** inputs,maps** outputs){
+  int res=SERVICE_FAILED;
+  if( !wxInitialize() ){
+    fprintf(stderr,"initialisation failed");
+    return SERVICE_FAILED;
+  }
+  setlocale(LC_NUMERIC, "C");
+  static bool g_bShow_Messages = false;
+
+  dumpMapsValuesToFiles(main_conf,inputs);
+
+  SagaWatcher watcher=SagaWatcher();
+  watcher.SetConf(main_conf);
+
+  SG_Set_UI_Callback(Get_Callback(watcher));
+
+  int n = SG_Get_Module_Library_Manager().Add_Directory(wxT(MODULE_LIBRARY_PATH),false);
+  if( SG_Get_Module_Library_Manager().Get_Count() <= 0 ){
+    setMapInMaps(*main_conf,"lenv","message","Could not load any SAGA tool library");
+    res=SERVICE_FAILED;
+    return res;
+  }
+
+  map* serviceProvider=getMap(s->content,"serviceProvider");
+
+  // Load the SAGA-GIS library corresponding to the serviceProvider
+  CSG_Module_Library * library=SG_Get_Module_Library_Manager().Get_Library(CSG_String(serviceProvider->value),true);
+  if( library == NULL){
+    char tmp[255];
+    sprintf(tmp,"Counld not load the %s SAGA library",serviceProvider->value);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+  
+  // Load the SAGA-GIS module corresponding to the service name from the library
+  CSG_Module * module=library->Get_Module(atoi(s->name));
+  if(module == NULL){
+    char tmp[255];
+    sprintf(tmp,"Counld not load the %s module from the %s SAGA library",
+	    s->name,serviceProvider->value);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+
+  // Load all the parameters defined for the module
+  CSG_Parameters * params=module->Get_Parameters();
+  int pc=params->Get_Count();
+  if(!params){
+    char tmp[255];
+    sprintf(tmp,"Counld not find any param for the %s module from the %s SAGA library",
+	    s->name,serviceProvider->value);
+    setMapInMaps(*main_conf,"lenv","message",tmp);
+    res=SERVICE_FAILED;
+    return res;
+  }
+
+  // Loop over each inputs to transform raster files to grid when needed, 
+  // import tables, shapes or point clouds
+  for(int k=0;k<pc;k++){
+    CSG_Parameter * param=params->Get_Parameter(k);
+    if(param!=NULL && !param->is_Output()){
+      maps* inmap=getMaps(*inputs,CSG_String(param->Get_Identifier()).b_str());
+      if(inmap!=NULL){
+	map* tmp=getMap(inmap->content,"value");
+	if(tmp==NULL || strncasecmp(tmp->value,"NULL",4)!=0){
+	  if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))){
+	    sagaImportGDAL(main_conf,&inmap);
+	  }
+	  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
+	    sagaImportOGR(main_conf,&inmap);
+	    sagaImportTIN(main_conf,&inmap);
+	  }
+	  else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes"))){
+	    sagaImportOGR(main_conf,&inmap);
+	  }
+	  else{
+	    if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
+	      sagaImportTable(main_conf,&inmap);
+	    }
+	    else
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
+		sagaImportPC(main_conf,&inmap);
+	      }
+	  }
+	}
+      }
+    }
+  }
+
+  // Create a map conraining arguments to pass to the SAGA-GIS module
+  // Fetch all input value (specifically for data imported into SAGA-GIS)
+  maps* inp=*inputs;
+  int k=0;
+  map* cParams=NULL;
+  while(inp!=NULL){
+    map* len=getMap(inp->content,"length");
+    bool shouldClean=false;
+    if(len==NULL){
+      len=createMap("length","1");
+      shouldClean=true;
+    }
+    int len0=strtol(len->value,NULL,10);
+    int i=0;
+    char *cinput=NULL;
+    int clen=0;
+    for(i=0;i<len0;i++){
+      map* val=getMapArray(inp->content,"saga_value",i);
+      if(val==NULL)
+	val=getMapArray(inp->content,"value",i);
+      if(val!=NULL && strncasecmp(val->value,"NULL",4)!=0){
+	if(cinput==NULL){
+	  cinput=zStrdup(val->value);
+	}
+	else{
+	  cinput=(char*)realloc(cinput,(clen+strlen(val->value)+1)*sizeof(char));
+	  strncpy(&cinput[0]+clen,";",1);
+	  strncpy(&cinput[0]+(clen+1),val->value,strlen(val->value));
+	  clen+=1;
+	}
+	clen+=strlen(val->value);
+	cinput[clen]=0;
+      }
+    }
+    if(cinput!=NULL && strncasecmp(cinput,"NULL",4)!=0){
+      if(cParams==NULL)
+	cParams=createMap(inp->name,cinput);
+      else
+	addToMap(cParams,inp->name,cinput);
+      free(cinput);
+    }
+    inp=inp->next;
+  }
+
+  // Fetch all output and define a resulting filename
+  inp=*outputs;
+  map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
+  map* sid=getMapFromMaps(*main_conf,"lenv","usid");
+  while(inp!=NULL){
+    for(int k=0;k<pc;k++){
+      CSG_Parameter * param=params->Get_Parameter(k);
+      if(CSG_String(param->Get_Identifier()).Cmp(inp->name)==0){
+	const char *file_ext=sagaGetDefaultExt(param);
+	char *fileName=(char*)malloc((strlen(file_ext)+strlen(sid->value)+strlen(inp->name)+strlen(tmpPath->value)+11)*sizeof(char));
+	sprintf(fileName,"%s/Output_%s_%s.%s",tmpPath->value,inp->name,sid->value,file_ext);
+	if(cParams==NULL)
+	  cParams=createMap(inp->name,fileName);
+	else
+	  addToMap(cParams,inp->name,fileName);
+      }
+    }
+    inp=inp->next;
+  }
+
+  sagaSetParameters(params,cParams);
+
+  module->Update_Parameter_States();
+  
+  bool retval=false;
+  if(module->On_Before_Execution()){
+    retval=module->Execute();
+    module->On_After_Execution();
+  }
+
+  sagaSaveOutputs(params,*main_conf,outputs);
+
+  // Loop over each outputs to transform grid to raster file when needed, 
+  // export tables, shapes or point clouds
+  for(int k=0;k<pc;k++){
+    CSG_Parameter * param=params->Get_Parameter(k);
+    if(param!=NULL && param->is_Output()){
+      maps* inmap=getMaps(*outputs,CSG_String(param->Get_Identifier()).b_str());
+      if(inmap!=NULL){
+	if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("grid"))
+	   || CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("data_object"))){
+	  sagaExportGDAL(main_conf,&inmap);
+	}else{
+	  if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("shapes"))){
+	    sagaExportOGR(main_conf,&inmap);
+	  }
+	  else{
+	    if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("table"))){
+	    }
+	    else{
+	      if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
+		sagaExportTIN(main_conf,&inmap,"TIN");
+	      }
+	      else
+		if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("points"))){
+		  sagaExportPC(main_conf,&inmap);
+	      }
+	    }
+	  }
+	}
+      }
+      else if(CSG_String(param->Get_Type_Identifier()).Contains(CSG_String("tin"))){
+	sagaExportTIN(main_conf,outputs,CSG_String(param->Get_Identifier()).b_str());
+      }
+	      
+    }
+  }
+
+  wxUninitialize();
+
+  return SERVICE_SUCCEEDED;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_internal_saga.h	(revision 672)
@@ -0,0 +1,35 @@
+/*
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SERVICE_INTERNAL_SAGA_H
+#define ZOO_SERVICE_INTERNAL_SAGA_H 1
+
+#pragma once 
+
+#include "service.h"
+#include "service_internal.h"
+
+int zoo_saga_support(maps**,map*,service*,maps**,maps**);
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_loader.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_loader.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_loader.c	(revision 672)
@@ -0,0 +1,272 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2009-2010 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * Environment variables definitions.
+ * All the following fixed values should be extracted from a configuration main
+ * configuration file for all the potential services.
+ */
+/**
+ * END "Environment variables definitions"
+ */
+#define length(x) (sizeof(x) / sizeof(x[0]))
+
+extern "C" int yylex();
+extern "C" int crlex();
+
+#include <string.h>
+
+#include "service.h"
+#include "service_internal.h"
+#include "service_internal_python.h"
+
+#include <dirent.h>
+#include <signal.h>
+#include <unistd.h>
+#ifndef WIN32
+#include <dlfcn.h>
+#include <libgen.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#include <stdarg.h>
+
+void sigint_handler(int sig){
+    printf("Not this time!\n");
+}
+
+int main(int argc, char *argv[])
+{
+  if (argc < 4){
+    printf( "Usage: %s <servicename> <directory>|<definition_file> <REQUEST> [<functionname> <param_1>[...<param_n>]]\n", basename(argv[0]) );
+    return 1;
+  }
+ 
+  map* outputs=NULL;
+  /**
+   * Parsing inputs (need a loop over all files in the service path !!)
+   */
+  maps* m;
+  m=(maps*)malloc(MAP_SIZE);
+  conf_read("main.cfg",m);
+  map* tmpm=getMapFromMaps(m,"main","serverAddress");
+  int toto=count(tmpm);
+  //printf(" - %i \n",toto);
+
+  if(tmpm!=NULL)
+    SERVICE_URL=strdup(tmpm->value);
+  else
+    SERVICE_URL=DEFAULT_SERVICE_URL;
+
+  service* s[100];
+  service* s1;
+  int scount=0;
+
+  if(strcmp(argv[3],"GetCapabilities")==0){
+    int i=0;
+    struct dirent *dp;
+    DIR *dirp = opendir(argv[1]);
+    int t;
+    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
+    xmlNodePtr n = printGetCapabilitiesHeader(doc,argv[2],m);
+    
+    int saved_stdout = dup(fileno(stdout));
+    stdout = freopen("/dev/null" , "w" , stdout);
+    while ((dp = readdir(dirp)) != NULL)
+      if(strstr(dp->d_name,".zcfg")!=0){
+	char toto1[1024];
+	sprintf(toto1,"%s%s",argv[1],dp->d_name);
+	char *toto=toto1;
+	s1=(service*)malloc(sizeof(char*)+(MAP_SIZE*2)+(2*ELEMENTS_SIZE));
+	//s[scount]=(service*)malloc(sizeof(service*));
+	//#ifdef DEBUG
+	fprintf(stderr,"#################\n%s\n#################\n",toto1);
+	//printf("|(1)");
+	//#endif
+	t=getServiceFromFile(toto1,&s1);
+	
+	//printf("|(2)");
+	printGetCapabilitiesForProcess(m,n,s1);
+	/**
+	 * Valgrind told us that there is an issue regarding a 
+	 * "conditional jump or move depends on uninitialised value(s)" for
+	 * freeIOType
+	 */
+	//freeService(&s1);
+	scount++;
+      }
+    char buf[20];
+    sprintf(buf, "/dev/fd/%d", saved_stdout);
+    stdout = freopen(buf , "w" , stdout);
+
+    printDocument(doc);
+    fflush(stdout);
+    free(m);
+    return 0;
+  }
+  else{
+    s1=(service*)malloc(sizeof(char*)+(MAP_SIZE*2)+(2*ELEMENTS_SIZE));
+    //s[0]=(service*)malloc(sizeof(service*));
+    int t=getServiceFromFile(argv[1],&s1);
+    if(strcmp(argv[3],"DescribeProcess")==0){
+      printDescribeProcessResponse(s1,argv[2]);
+      //dumpMaps(m);
+      //free(s1);
+      return 0;
+    }
+    else
+      if(strcmp(argv[3],"Execute")!=0){
+	fprintf(stderr,"");
+	//free(s);
+	return 0;
+      }
+  }
+  //dumpService(s);
+  s[0]=s1;
+  map* inputs=NULL;
+  elements* c_inputs=s1->inputs;
+  int j;
+  for(j=0;j<argc-5;j++){
+    //dumpElements(c_inputs);
+    if(inputs!=NULL)
+      addToMap(inputs,c_inputs->name,argv[j+5]);
+    else
+      inputs=createMap(c_inputs->name,argv[j+5]);
+    if(c_inputs->next!=NULL || j+1>=argc-5)
+      c_inputs=c_inputs->next;
+    else{
+      map* tmps=createMap("text","ERROR you provided more inputs than requested.");
+      printExceptionReportResponse(m,tmps);
+      //printf("ERROR you provided more inputs than requested.");
+      return -1;
+    }
+#ifdef DEBUG
+    printf("ARGV1 %d %s\n",j,inputs->value);
+#endif
+  }
+
+#ifdef DEBUG
+  dumpMap(inputs);
+#endif
+
+  const struct tm *tm;
+  size_t len;
+  time_t now;
+  char *sDate;
+  
+  now = time ( NULL );
+  tm = localtime ( &now );
+
+  sDate = new char[TIME_SIZE];
+
+  len = strftime ( sDate, TIME_SIZE, "%d-%B-%YT%I:%M:%SZ", tm );
+
+#ifdef DEBUG
+  printf("Trying to load %s\n", argv[2]);
+#endif
+  void* so = dlopen(argv[2], RTLD_LAZY);
+  char *errstr;
+  errstr = dlerror();
+  if( so != NULL ) {
+    typedef int (*execute_t)(map**,map**);
+#ifdef DEBUG
+    printf("Library loaded %s \n",errstr);
+#endif
+    execute_t execute=(execute_t)dlsym(so,argv[4]);
+#ifdef DEBUG
+    errstr = dlerror();
+    printf("Function loaded %s\n",errstr);
+#endif	
+
+    /**
+     * Need to check if we need to fork to load a status enabled 
+     */
+    char _toto[10];
+    sprintf(_toto,"input_%i",argc-5);
+    map* toto=getMap(inputs,_toto);
+    if(strcmp(argv[argc-1],"bg")!=0){
+#ifdef DEBUG
+      printf("RUN IN NORMAL MODE \n");
+#endif
+      int res=execute(&inputs,&outputs);
+#ifdef DEBUG
+      printf("RUNNED IN NORMAL MODE \n");
+      dumpMap(inputs);
+      dumpMap(outputs);
+#endif
+      printProcessResponse(m,getpid(),s[0],argv[2],res,inputs,outputs);
+    }
+    else{
+      pid_t   pid;
+      int cpid=getpid();
+      pid = fork ();
+      if (pid > 0) {
+	/**
+	 * dady :
+	 * set status to SERVICE_ACCEPTED
+	 */
+	printProcessResponse(m,pid,s[0],argv[2],SERVICE_ACCEPTED,inputs,outputs);
+      }else if (pid == 0) {
+	/* son */
+	if (signal(SIGINT, sigint_handler) == SIG_ERR) {
+	  printf("signal");
+	  map* tmps=createMap("text","father received sigint.");
+	  printExceptionReportResponse(m,tmps);
+	  exit(1);
+	}
+#ifdef DEBUG
+	printf("RUN IN BACKGROUND MODE \n");
+#endif
+	char tmp1[256];
+	sprintf(tmp1,"service/temp/%s_%d.xml",argv[2],getpid());
+	stdout = freopen(tmp1 , "w+" , stdout);
+	/**
+	 * set status to SERVICE_STARTED
+	 */
+	printProcessResponse(m,getpid(),s[0],argv[2],SERVICE_STARTED,inputs,outputs);
+	fflush(stdout);
+	rewind(stdout);
+	int t=execute(&inputs,&outputs);
+	/**
+	 * set status to status code returned by the service function
+	 */
+	printProcessResponse(m,getpid(),s[0],argv[2],t,inputs,outputs);
+      } else {
+	/* error */
+      }
+    }
+#ifdef DEBUG
+    errstr = dlerror();
+    printf("Function successfully loaded %s, unloading now.\n",errstr);
+#endif
+    dlclose(so);
+  }
+  else {
+#ifdef DEBUG
+    printf("C Library can't be loaded %s \n",errstr);
+#endif
+    python_support(m,s[0],argc,argv,inputs,outputs);
+  }
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_yaml.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_yaml.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/service_yaml.c	(revision 672)
@@ -0,0 +1,459 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2014 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <service.h>
+#include <yaml.h>
+
+static service* my_service=NULL;
+static map* current_content=NULL;
+static elements* current_element=NULL;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Read and parse a ZCFG file in YAML format 
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param file the file name to read
+ * @param service the service structure to fill
+ * @param name the service name
+ * @return 1 on success, -1 if error occured
+ */
+int getServiceFromYAML(maps* conf, char* file,service** service,char *name){
+  FILE *fh = fopen("test.yml", "r");
+  if(current_content!=NULL){
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"(STARTING)FREE current_element\n");
+#endif
+  if(current_element!=NULL){
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  my_service=NULL;
+  
+  my_service=*service;
+  my_service->name=strdup(name);
+  my_service->content=NULL;
+  my_service->metadata=NULL;
+  my_service->inputs=NULL;
+  my_service->outputs=NULL;
+  fh = fopen(file,"r");
+  if (fh==NULL){
+    fprintf(stderr,"error : file not found\n") ;
+    return -1;
+  }
+  yaml_parser_t parser;
+  yaml_token_t  token;   /* new variable */
+
+  /* Initialize parser */
+  if(!yaml_parser_initialize(&parser))
+    fputs("Failed to initialize parser!\n", stderr);
+  if(fh == NULL)
+    fputs("Failed to open file!\n", stderr);
+  /* Set input file */
+  yaml_parser_set_input_file(&parser, fh);
+  /* BEGIN new code */
+  int level=0;
+  int plevel=level;
+  int ilevel=-1;
+  int blevel=-1;
+  int ttype=0;
+  int wait_metadata=-1;
+  char *cur_key;
+  do {
+    yaml_parser_scan(&parser, &token);
+    switch(token.type)
+    {
+    /* Stream start/end */
+    case YAML_STREAM_START_TOKEN: 
+#ifdef DEBUG_YAML
+      puts("STREAM START"); 
+#endif
+      break;
+    case YAML_STREAM_END_TOKEN:   
+#ifdef DEBUG_YAML
+      puts("STREAM END");   
+#endif
+      break;
+    /* Token types (read before actual token) */
+    case YAML_KEY_TOKEN:   
+#ifdef DEBUG_YAML
+      printf("(Key token)   "); 
+#endif
+      ttype=0;
+      break;
+    case YAML_VALUE_TOKEN: 
+#ifdef DEBUG_YAML
+      printf("(Value token) "); 
+#endif
+      ttype=1;
+      break;
+    /* Block delimeters */
+    case YAML_BLOCK_SEQUENCE_START_TOKEN: 
+#ifdef DEBUG_YAML
+      puts("<b>Start Block (Sequence)</b>"); 
+#endif
+      break;
+    case YAML_BLOCK_ENTRY_TOKEN:          
+#ifdef DEBUG_YAML
+      puts("<b>Start Block (Entry)</b>");    
+#endif
+      break;
+    case YAML_BLOCK_END_TOKEN:      
+      blevel--;
+      if(ilevel>=0)
+	ilevel--;
+#ifdef DEBUG_YAML
+      printf("<b>End block</b> (%d,%d,%d,%d)\n", blevel,level,ilevel,ttype); 
+#endif
+      break;
+    /* Data */
+    case YAML_BLOCK_MAPPING_START_TOKEN:  
+#ifdef DEBUG_YAML
+      puts("[Block mapping]");            
+#endif
+      blevel++;
+      break;
+    case YAML_SCALAR_TOKEN:  
+      if(ttype==0){
+	cur_key=zStrdup((char *)token.data.scalar.value);
+      }
+      if(ttype==1){
+	if(current_content==NULL){
+	  current_content=createMap(cur_key,(char *)token.data.scalar.value);
+	}else{
+	  addToMap(current_content,cur_key,(char *)token.data.scalar.value);
+	}
+	free(cur_key);
+	cur_key=NULL;
+      }
+
+      if(ttype==0 && blevel==0 && level==0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0 && blevel==0){
+	addMapToMap(&my_service->content,current_content);
+#ifdef DEBUG_YAML
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=1;
+      }
+      if(ttype==0 && blevel>0 && level>0 && strcasecmp((char *)token.data.scalar.value,"MetaData")==0){
+	if(current_element->content==NULL && current_content!=NULL)
+	  addMapToMap(&current_element->content,current_content);
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=1;
+      }
+      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"inputs")==0 && blevel==0){
+	if(wait_metadata>0){
+	  addMapToMap(&my_service->metadata,current_content);
+	  wait_metadata=-1;
+	}else{
+	  if(current_content!=NULL && my_service->content==NULL)
+	    addMapToMap(&my_service->content,current_content);
+	}
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=false;
+	level++;
+      }
+      if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"outputs")==0 && blevel==1){
+	level++;
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
+#endif
+	if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
+	  current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	  current_element->defaults->content=NULL;
+	  current_element->defaults->next=NULL;
+	  addMapToMap(&current_element->defaults->content,current_content);
+#ifdef DEBUG_YAML
+	  dumpElements(current_element);
+	  dumpMap(current_content);
+	  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}else{
+	  if(current_content!=NULL && ilevel<=0){
+	    addMapToIoType(&current_element->supported,current_content);
+#ifdef DEBUG_YAML
+	    dumpElements(current_element);
+	    dumpMap(current_content);
+	    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
+	}
+      }
+      if(level==1 && strcasecmp((char *)token.data.scalar.value,"default")==0){
+	ilevel=0;
+      }
+      if(level==1 && strcasecmp((char *)token.data.scalar.value,"supported")==0){
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
+#endif
+	if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
+	  current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	  current_element->defaults->content=NULL;
+	  current_element->defaults->next=NULL;
+	  addMapToMap(&current_element->defaults->content,current_content);
+#ifdef DEBUG_YAML
+	  dumpElements(current_element);
+	  dumpMap(current_content);
+	  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}else{
+	  if(current_content!=NULL && ilevel<=0){
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	    }
+	    addMapToMap(&current_element->supported->content,current_content);
+#ifdef DEBUG_YAML
+	    dumpElements(current_element);
+	    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
+	}
+	ilevel=1;
+      }
+
+
+      if(strncasecmp((char *)token.data.scalar.value,"ComplexData",11)==0 || 
+	 strncasecmp((char *)token.data.scalar.value,"LiteralData",10)==0 || 
+	 strncasecmp((char *)token.data.scalar.value,"ComplexOutput",13)==0 || 
+	 strncasecmp((char *)token.data.scalar.value,"LiteralOutput",12)==0 || 
+	 strncasecmp((char *)token.data.scalar.value,"BoundingBoxOutput",13)==0 || 
+	 strncasecmp((char *)token.data.scalar.value,"BoundingBoxData",12)==0){
+	current_element->format=zStrdup((char *)token.data.scalar.value);
+	free(cur_key);
+	cur_key=NULL;
+	if(wait_metadata>0 && current_content!=NULL){
+	  addMapToMap(&current_element->metadata,current_content);
+	  wait_metadata=-1;
+	}else{
+	  if(current_content!=NULL){
+	    addMapToMap(&current_element->content,current_content);
+	  }
+	}
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+#ifdef DEBUG_YAML
+	dumpElements(current_element);
+#endif
+      }
+
+      if(blevel==1 && level==1){
+	if(current_element!=NULL && current_content!=NULL){
+	  if(current_element->defaults==NULL){
+	    current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	    current_element->defaults->content=NULL;
+	    current_element->defaults->next=NULL;
+	    addMapToMap(&current_element->defaults->content,current_content);
+	  }else{
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	      addMapToMap(&current_element->supported->content,current_content);
+	    }else
+	      addMapToIoType(&current_element->supported,current_content);
+	  }
+	}
+	if(current_element!=NULL){
+	  if(my_service->inputs==NULL)
+	    my_service->inputs=dupElements(current_element);
+	  else
+	    addToElements(&my_service->inputs,current_element);
+	  freeElements(&current_element);
+	  free(current_element);
+	}
+	plevel=level;
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=zStrdup((char *)token.data.scalar.value);
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->next=NULL;
+	
+      }
+      if(blevel==1 && level==2){
+	if(current_element!=NULL && current_content!=NULL){
+	  if(current_element->defaults==NULL){
+	    current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	    current_element->defaults->content=NULL;
+	    current_element->defaults->next=NULL;
+	    addMapToMap(&current_element->defaults->content,current_content);
+	  }else{
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	      addMapToMap(&current_element->supported->content,current_content);
+	    }else
+	      addMapToIoType(&current_element->supported,current_content);
+	  }
+	}
+	if(current_element!=NULL){
+	  if(plevel==level){
+	    if(my_service->outputs==NULL)
+	      my_service->outputs=dupElements(current_element);
+	    else
+	      addToElements(&my_service->outputs,current_element);
+	  }else{
+	    if(my_service->inputs==NULL)
+	      my_service->inputs=dupElements(current_element);
+	    else
+	      addToElements(&my_service->inputs,current_element);
+	  }
+	  freeElements(&current_element);
+	  free(current_element);
+	}
+	plevel=level;
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=zStrdup((char *)token.data.scalar.value);
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->next=NULL;
+	
+      }
+
+
+#ifdef DEBUG_YAML
+      printf("scalar %s (%d,%d,%d,%d,%d)\n", token.data.scalar.value,blevel,level,plevel,ilevel,ttype); 
+#endif
+      break;
+    /* Others */
+    default:
+      if(token.type==0){
+	char tmp[1024];
+	sprintf(tmp,"Wrong charater found in %s: \\t",name);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return -1;
+      }
+#ifdef DEBUG_YAML
+      printf("Got token of type %d\n", token.type);
+#endif
+      break;
+    }
+    if(token.type != YAML_STREAM_END_TOKEN )
+      yaml_token_delete(&token);
+  } while(token.type != YAML_STREAM_END_TOKEN);
+  yaml_token_delete(&token);
+
+
+#ifdef DEBUG_YAML
+  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+  if(current_element!=NULL && current_content!=NULL){
+    if(current_element->defaults==NULL){
+      current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+      current_element->defaults->content=NULL;
+      current_element->defaults->next=NULL;
+      addMapToMap(&current_element->defaults->content,current_content);
+    }else{
+      if(current_element->supported==NULL){
+	current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	current_element->supported->content=NULL;
+	current_element->supported->next=NULL;
+	addMapToMap(&current_element->supported->content,current_content);
+      }else
+	addMapToIoType(&current_element->supported,current_content);
+    }
+#ifdef DEBUG_YAML
+    dumpMap(current_content);
+    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+  if(current_element!=NULL){
+    if(my_service->outputs==NULL)
+      my_service->outputs=dupElements(current_element);
+    else
+      addToElements(&my_service->outputs,current_element);
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  /* END new code */
+
+  /* Cleanup */
+  yaml_parser_delete(&parser);
+  fclose(fh);
+
+#ifdef DEBUG_YAML
+  dumpService(my_service);
+#endif
+  *service=my_service;
+
+  return 1;
+}
+#ifdef __cplusplus
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sql/schema.sql
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sql/schema.sql	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sql/schema.sql	(revision 672)
@@ -0,0 +1,69 @@
+--------------------------------------------------------------------------------
+--
+-- PostgreSQL definition of tables required byt the ZOO-Kernel version >= 1.5.0
+-- if the the db-backend option is activated
+--
+-- Copyright (C) 2015 GeoLabs SARL. All rights reserved.
+-- Author: David Saggiorato <david.saggiorato@geolabs.fr>
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy
+-- of this software and associated documentation files (the "Software"), to deal
+-- in the Software without restriction, including without limitation the rights
+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-- copies of the Software, and to permit persons to whom the Software is
+-- furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in
+-- all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+-- THE SOFTWARE.
+--
+-------------------------------------------------------------------------------- 
+-- If your database is not using UTF-8 per default then uncomment the following 
+-- SET client_encoding = 'UTF8';
+-------------------------------------------------------------------------------- 
+-- Create a dedicated schema to store all tables
+-- Uncomment the following 2 lines to activate the schema use
+-- CREATE SCHEMA zoo;
+-- SET search_path TO zoo;
+--------------------------------------------------------------------------------
+-- Services table
+-- Used to store informations about services running asynchronously
+create table services (
+       osid TEXT unique,
+       sid TEXT unique,
+       uuid TEXT unique,
+       fstate varchar(25),
+       status TEXT,
+       response TEXT,
+       creation_time timestamp with time zone default now(),
+       end_time timestamp with time zone default NULL,
+       progress int,
+       message TEXT
+);
+--------------------------------------------------------------------------------
+-- Responses table 
+-- Used to store the response provided by a services running asynchronously
+create table responses (
+       uuid text references services(uuid) ON DELETE CASCADE,
+       content text,
+       creation_time timestamp with time zone default now()
+);
+--------------------------------------------------------------------------------
+-- Files table
+-- Used to store the files generated during the service execution
+create table files (
+       uuid TEXT references services(uuid) ON DELETE CASCADE,
+       filename text,
+       nature varchar(10),
+       name varchar(255),
+       creation_time timestamp with time zone default now(),
+       expiration_time timestamp with time zone default now() + interval '48 hours'
+);
+--------------------------------------------------------------------------------
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.c	(revision 672)
@@ -0,0 +1,465 @@
+/*
+ * Author : David Saggiorato
+ *          Gérald Fenoy
+ *  Copyright 2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef RELY_ON_DB
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+#include "ogr_p.h"
+
+#include "sqlapi.h"
+#include <fcgi_stdio.h>
+#include <stdlib.h>
+
+/**
+ * Global GDALDataset pointer
+ */
+OGRDataSource *zoo_DS = NULL;
+
+/**
+ * Global OGRLayer pointer pointing to the lastest result set
+ */
+OGRLayer *zoo_ResultSet = NULL;
+
+/**
+ * Create a GDAL / OGR string for connecting to the db backend
+ * (do not support active_schema)
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ */
+char* createInitString(maps* conf){
+  char* res=NULL;
+  char keywords[5][9]={
+    "dbname",
+    "host",
+    "port",
+    "user",
+    "password"
+  };
+  int i=0;
+  maps* cconf=getMaps(conf,"database");
+  int len=0;
+  for(i=0;i<5;i++){
+    map* tmp=getMap(cconf->content,keywords[i]);
+    if(tmp!=NULL){
+      if(res==NULL){
+	res=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+4)*sizeof(char));
+	sprintf(res,"%s='%s'",keywords[i],tmp->value);
+	len+=strlen(res);
+      }else{
+	char* res1=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
+	sprintf(res1," %s='%s'",keywords[i],tmp->value);
+	res=(char*)realloc(res,(len+strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
+	memcpy(res+len,res1,(strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
+	len+=strlen(res1);
+	res[len]=0;
+	free(res1);
+      }
+    }
+  }
+  map* tmp=getMap(cconf->content,"type");
+  if(tmp!=NULL){
+    char* fres=(char*)malloc((strlen(res)+strlen(tmp->value)+2)*sizeof(char));
+    sprintf(fres,"%s:%s",tmp->value,res);
+    free(res);
+    return fres;
+  }
+  return res;
+}
+
+/**
+ * Connect to the db backend.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @see createInitString
+ */
+void init_sql(maps* conf){
+  char* sqlInitString=createInitString(conf);
+  OGRSFDriver *poDriver = NULL;
+  OGRRegisterAll();
+  zoo_DS = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
+  if( zoo_DS == NULL ){
+#ifdef DEBUG
+    fprintf(stderr,"sqlInitString: %s FAILED !\n",sqlInitString);
+    fflush(stderr);
+#endif
+    free(sqlInitString);
+    setMapInMaps(conf,"lenv","message","Failed to connect to the database backend");
+    return;
+  }
+#ifdef DEBUG
+  fprintf(stderr,"sqlInitString: %s SUCEED !\n",sqlInitString);
+  fflush(stderr);
+#endif
+  free(sqlInitString);
+}
+
+/**
+ * Close any connection to the db backend.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ */
+void close_sql(maps* conf){
+  if( zoo_ResultSet != NULL )
+    zoo_DS->ReleaseResultSet( zoo_ResultSet );
+  if(zoo_DS!=NULL){
+    OGRDataSource::DestroyDataSource( zoo_DS );
+    zoo_DS=NULL;
+  }
+}
+
+/**
+ * Call OGRCleanupAll.
+ * 
+ */
+void end_sql(){
+  OGRCleanupAll();
+}
+
+/**
+ * Execute a SQL query to the SQL Database Backend.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param sqlQuery the SQL query to run
+ * @return -1 in case of failure and 1 if the query succeed.
+ */
+int execSql(maps* conf,const char* sqlQuery){
+  zoo_ResultSet = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
+  if( zoo_ResultSet != NULL ){
+    return 1;
+  }
+  return -1;
+}
+
+/**
+ * Clean any memory allocated by executing a request
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param sqlQuery the SQL query to run
+ * @return -1 in case of failure and 1 if the query succeed.
+ */
+void cleanUpResultSet(const maps* conf){
+  if( zoo_ResultSet != NULL ){
+    zoo_DS->ReleaseResultSet( zoo_ResultSet );
+    zoo_ResultSet=NULL;
+  }
+}
+
+/**
+ * Record a file stored during ZOO-Kernel execution
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param filename the file's name
+ * @param type the type (Intput,Output,Response)
+ * @param name the maps containing the setting of the main.cfg file
+ */
+void recordStoredFile(maps* conf,const char* filename,const char* type,const char* name){
+  map *uusid=getMapFromMaps(conf,"lenv","usid");
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(uusid->value)+strlen(filename)+strlen(type)+(name!=NULL?strlen(name):2)+68+1)*sizeof(char));
+  if(name!=NULL)
+    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s','%s');",schema->value,uusid->value,filename,type,name);
+  else
+    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s',NULL);",schema->value,uusid->value,filename,type);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+}
+
+/**
+ * Insert the reference tuple corresponding to the running service
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ */
+void recordServiceStatus(maps* conf){
+  map *sid=getMapFromMaps(conf,"lenv","sid");
+  map *osid=getMapFromMaps(conf,"lenv","osid");
+  map *uusid=getMapFromMaps(conf,"lenv","usid");
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+
+				strlen(uusid->value)+
+				strlen(osid->value)+
+				strlen(sid->value)+56+1)*sizeof(char));
+  sprintf(sqlQuery,
+	  "INSERT INTO %s.services (uuid,sid,osid)"
+	  "VALUES ('%s','%s','%s');",
+	  schema->value,
+	  uusid->value,sid->value,osid->value);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+}
+
+/**
+ * Store the content of the result file
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param filename the file's name
+ */
+void recordResponse(maps* conf,char* filename){
+  FILE *file = fopen (filename, "rb");
+  fseek (file, 0, SEEK_END);
+  long flen = ftell (file);
+  fseek (file, 0, SEEK_SET);
+  char *tmps = (char *) malloc ((flen + 1) * sizeof (char));
+  fread (tmps, flen, 1, file);
+  tmps[flen]=0;
+  fclose(file);
+  map *sid=getMapFromMaps(conf,"lenv","usid");
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+51+1)*sizeof(char));
+  sprintf(sqlQuery,"INSERT INTO %s.responses (content,uuid) VALUES ($$%s$$,$$%s$$);",schema->value,tmps,sid->value);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+}
+
+/**
+ * Update the current status of the running service.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ * @return 0 on success, -2 if shmget failed, -1 if shmat failed
+ */
+int _updateStatus(maps* conf){
+  map *sid=getMapFromMaps(conf,"lenv","usid");
+  map *p=getMapFromMaps(conf,"lenv","status");
+  map *msg=getMapFromMaps(conf,"lenv","message");
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
+  sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
+  fflush(stderr);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+  return 0;
+}
+
+/**
+ * Get the ongoing status of a running service 
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the reported status char* (MESSAGE|POURCENTAGE)
+ */
+char* _getStatus(maps* conf,char* pid){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
+  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  OGRFeature  *poFeature = NULL;
+  const char *tmp1;
+  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+      if( poFeature->IsFieldSet( iField ) ){
+	tmp1=strdup(poFeature->GetFieldAsString( iField ));
+      }
+      else
+	tmp1=NULL;
+    }
+    OGRFeature::DestroyFeature( poFeature );
+  }
+  cleanUpResultSet(conf);
+  return (char*)tmp1;
+}
+
+/**
+ * Read the cache file of a running service 
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the reported status char* (temporary/final result)
+ */
+char* _getStatusFile(maps* conf,char* pid){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+82+1)*sizeof(char));
+  sprintf(sqlQuery,
+	  "select content from %s.responses where uuid=$$%s$$"
+	  " order by creation_time desc limit 1",schema->value,pid);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  OGRFeature  *poFeature = NULL;
+  const char *tmp1;
+  int hasRes=-1;
+  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+      if( poFeature->IsFieldSet( iField ) ){
+	tmp1=strdup(poFeature->GetFieldAsString( iField ));
+	hasRes=1;
+      }
+      else
+	tmp1=NULL;
+    }
+    OGRFeature::DestroyFeature( poFeature );
+  }
+  if(hasRes<0)
+    tmp1=NULL;
+  cleanUpResultSet(conf);
+  return (char*)tmp1;
+}
+
+/**
+ * Delete a service reference from the database.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ */
+void removeService(maps* conf,char* pid){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)
+    malloc((strlen(pid)+strlen(schema->value)+38+1)
+	   *sizeof(char));
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  sprintf(sqlQuery,
+	  "DELETE FROM %s.services where uuid=$$%s$$;",
+	  schema->value,pid);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+  close_sql(conf);
+  end_sql();
+}
+
+/**
+ * Stop handling status repport.
+ *
+ * @param conf the map containing the setting of the main.cfg file
+ */
+void unhandleStatus(maps* conf){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  map *sid=getMapFromMaps(conf,"lenv","usid");
+  map *fstate=getMapFromMaps(conf,"lenv","fstate");
+  char *sqlQuery=(char*)malloc((strlen(sid->value)+
+				strlen(schema->value)+
+				(fstate!=NULL?
+				 strlen(fstate->value):
+				 6)
+				+66+1)*sizeof(char));
+  sprintf(sqlQuery,
+	  "UPDATE %s.services set end_time=now(), fstate=$$%s$$"
+	  " where uuid=$$%s$$;",
+	  schema->value,(fstate!=NULL?fstate->value:"Failed"),sid->value);
+  execSql(conf,sqlQuery);
+  cleanUpResultSet(conf);
+  close_sql(conf);
+  end_sql();
+}
+
+/**
+ * Read the sid identifier attached of a service if any
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ * @return the sid value
+ */
+char* getStatusId(maps* conf,char* pid){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
+  sprintf(sqlQuery,
+	  "select osid from %s.services where uuid=$$%s$$",
+	  schema->value,pid);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  OGRFeature  *poFeature = NULL;
+  const char *tmp1;
+  int hasRes=-1;
+  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+      if( poFeature->IsFieldSet( iField ) ){
+	tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
+	hasRes=1;
+	break;
+      }
+    }
+    OGRFeature::DestroyFeature( poFeature );
+  }
+  if(hasRes<0)
+    tmp1=NULL;
+  return (char*)tmp1;
+}
+
+/**
+ * Read the Result file (.res).
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the service identifier (usid key from the [lenv] section)
+ */
+void readFinalRes(maps* conf,char* pid,map* statusInfo){
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
+  sprintf(sqlQuery,
+	  "select fstate from %s.services where uuid=$$%s$$",
+	  schema->value,pid);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  OGRFeature  *poFeature = NULL;
+  int hasRes=-1;
+  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+      if( poFeature->IsFieldSet( iField ) ){
+	addToMap(statusInfo,"Status",poFeature->GetFieldAsString( iField ));
+	hasRes=1;
+	break;
+      }
+    }
+    OGRFeature::DestroyFeature( poFeature );
+  }
+  if(hasRes<0)
+    addToMap(statusInfo,"Status","Failed");
+  return;
+}
+
+/**
+ * Check if a service is running.
+ *
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param pid the unique service identifier (usid from the lenv section)
+ * @return 1 in case the service is still running, 0 otherwise
+ */
+int isRunning(maps* conf,char* pid){
+  int res=0;
+  map *schema=getMapFromMaps(conf,"database","schema");
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+73+1)*sizeof(char));
+  sprintf(sqlQuery,"select count(*) as t from %s.services where uuid=$$%s$$ and end_time is null;",schema->value,pid);
+  if( zoo_DS == NULL )
+    init_sql(conf);
+  execSql(conf,sqlQuery);
+  OGRFeature  *poFeature = NULL;
+  const char *tmp1;
+  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+      if( poFeature->IsFieldSet( iField ) && 
+	  atoi(poFeature->GetFieldAsString( iField ))>0 ){
+	res=1;
+	break;
+      }
+    }
+    OGRFeature::DestroyFeature( poFeature );
+  }
+  cleanUpResultSet(conf);
+  return res;
+}
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/sqlapi.h	(revision 672)
@@ -0,0 +1,51 @@
+/*
+ * Author : David Saggiorato
+ *
+ *  Copyright 2008-2009 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_SQLAPI_H
+#define ZOO_SQLAPI_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RELY_ON_DB
+#include "service.h"
+#include "service_internal.h"
+  void init_sql(maps*);
+  void close_sql(maps*);
+  int execSql(maps*,const char*);
+  void recordStoredFile(maps*,const char*,const char*,const char*);
+  void recordServiceStatus(maps*);
+  void recordResponse(maps*,char*);
+  void readFinalRes(maps*,char*,map*);
+  int isRunning(maps*,char*);
+  char* getStatusId(maps*,char*);
+  void removeService(maps*,char*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.c	(revision 672)
@@ -0,0 +1,463 @@
+/*
+ *  ulinet.c
+ *
+ * Author : Gérald FENOY
+ *
+ * Copyright (c) 2008-2015 GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#define _ULINET
+#define MAX_WAIT_MSECS 180*1000 /* Wait max. 180 seconds */
+#include "ulinet.h"
+#include <assert.h>
+
+/**
+ * Write the downloaded content to a _HINTERNET structure
+ *
+ * @param buffer the buffer to read
+ * @param size size of each member
+ * @param nmemb number of element to read
+ * @param data the _HINTERNET structure to write in
+ * @return the size red, -1 if buffer is NULL
+ */
+size_t write_data_into(void *buffer, size_t size, size_t nmemb, void *data){
+  size_t realsize = size * nmemb;
+  _HINTERNET *psInternet;
+  if(buffer==NULL){
+    buffer=NULL;
+    return -1;
+  }
+  psInternet=(_HINTERNET *)data;
+  if(psInternet->pabyData){
+    psInternet->pabyData=(unsigned char*)realloc(psInternet->pabyData,psInternet->nDataLen+realsize+1);
+    psInternet->nDataAlloc+=psInternet->nDataLen+realsize+1;
+  }
+  else{
+    psInternet->pabyData=(unsigned char*)malloc(psInternet->nDataLen+realsize+1);
+    psInternet->nDataAlloc=realsize+1;
+  }
+
+  if (psInternet->pabyData) {
+    memcpy( psInternet->pabyData + psInternet->nDataLen, buffer, realsize);
+    psInternet->nDataLen += realsize;
+    psInternet->pabyData[psInternet->nDataLen] = 0;
+  }
+
+  buffer=NULL;
+  return realsize;
+}
+
+/**
+ * In case of presence of "Set-Cookie" in the headers red, store the cookie
+ * identifier in CCookie
+ *
+ * @param buffer the buffer to read
+ * @param size size of each member
+ * @param nmemb number of element to read
+ * @param data the _HINTERNET structure to write in
+ * @return the size red, -1 if buffer is NULL
+ * @see CCookie
+ */
+size_t header_write_data(void *buffer, size_t size, size_t nmemb, void *data){
+  if(strncmp("Set-Cookie: ",(char*)buffer,12)==0){
+    int i;
+    char env[256];
+    char path[256];
+    char domain[256];
+    char* tmp;
+    for(i=0;i<12;i++)
+#ifndef WIN32
+      buffer++;
+#else
+	;
+#endif
+    sscanf((char*)buffer,"%s; path=%s; domain=%s",env,path,domain);
+    tmp=strcat(env,CCookie[0]);
+#ifdef MSG_LAF_OUT
+    printf("\n**Cookie env : [%s] , path : [%s], domain : [%s]**\n",env,path,domain);
+    printf("buffer : %d (%s) (%s) (%s)\n",(buffer==NULL),buffer,tmp,CCookie);
+#endif
+    strcpy(CCookie[0],tmp);
+  }
+  return size * nmemb;//write_data_into(buffer,size,nmemb,data,HEADER);
+};
+
+/**
+ * Define the proxy to use for a CURL handler
+ * 
+ * @param handle the CURL handler
+ * @param host the proxy host (including http://)
+ * @param port the proxy port
+ */
+void setProxy(CURL* handle,char* host,long port){
+  char* proxyDef=(char*)malloc((strlen(host)+10+2)*sizeof(char));
+  sprintf(proxyDef,"%s:%ld",host,port);
+  curl_easy_setopt(handle,CURLOPT_PROXY,proxyDef);
+  free(proxyDef);
+}
+
+/**
+ * MACOSX
+ */
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+
+
+char* CFStringToCString(CFStringRef dest,char *buffer){
+  CFStringEncoding encoding = kCFStringEncodingUTF8;
+  Boolean bool2 = CFStringGetCString(dest,buffer,1024,encoding);
+  if(bool2){
+    printf("Loaded into local_buffer");
+    return buffer;
+  }
+  return NULL;
+}
+
+OSStatus setProxiesForProtcol(CURL* handle,const char *proto){
+  OSStatus		err;
+  CFDictionaryRef proxyDict;
+  CFArrayRef		proxies;
+  
+  CFStringRef key_enabled = NULL;
+  CFStringRef key_host = NULL;
+  CFStringRef key_port = NULL;
+  
+  bool proxy_enabled;
+  char *proxy_host;
+  long proxy_port;
+  
+  proxyDict = NULL;
+  proxies = NULL;
+
+  err = noErr;
+  proxyDict = SCDynamicStoreCopyProxies(NULL);
+
+  if(strncmp(proto,"http",4)==0){
+      key_enabled=kSCPropNetProxiesHTTPEnable;
+      key_host=kSCPropNetProxiesHTTPProxy;
+      key_port=kSCPropNetProxiesHTTPPort;
+  }
+  else
+    if(strncmp(proto,"https",5)==0){
+      key_enabled=kSCPropNetProxiesHTTPSEnable;
+      key_host=kSCPropNetProxiesHTTPSProxy;
+      key_port=kSCPropNetProxiesHTTPSPort;
+    }
+
+  CFNumberGetValue(CFDictionaryGetValue(proxyDict,key_enabled),kCFNumberIntType,&proxy_enabled);
+  if(proxy_enabled){
+    CFNumberGetValue(CFDictionaryGetValue(proxyDict,key_port),CFNumberGetType(CFDictionaryGetValue(proxyDict,key_port)),&proxy_port);
+    char buffer[1024];
+    CFStringToCString(CFDictionaryGetValue(proxyDict,key_host),buffer);
+    proxy_host=buffer;
+
+#ifdef MSG_LAF_VERBOSE
+    printf("\n**[PROXY SETTINGS DETECTION %s (%d) %s:%li (%s)]**\n",proto,proxy_enabled,(char*)proxy_host,proxy_port,buffer);
+#endif
+
+    if (proxyDict == NULL) {
+      err = coreFoundationUnknownErr;
+    }
+
+    setProxy(handle,proxy_host,proxy_port);
+  }
+  return err;
+}
+#else
+/**
+ * Should autodetect the proxy configuration (do nothing on linux)
+ *
+ * @param handle a CURL handle
+ * @param proto the protocol requiring the use of a proxy
+ */
+bool setProxiesForProtcol(CURL* handle,const char *proto){
+#ifdef MSG_LAF_VERBOSE
+  fprintf( stderr, "setProxiesForProtocol (do nothing) ...\n" );
+#endif
+  return true;
+}
+#endif
+
+/**
+ * Create a HINTERNET
+ *
+ * @param lpszAgent the HTPP User-Agent to use to send requests
+ * @param  dwAccessType type of access required
+ * @param  lpszProxyName the name of the proxy server(s) to use 
+ * @param  lpszProxyBypass ip address or host names which should not be routed
+ *  through the proxy
+ * @param  dwFlags Options (INTERNET_FLAG_ASYNC,INTERNET_FLAG_FROM_CACHE,INTERNET_FLAG_OFFLINE)
+ * @return the created HINTERNET
+ */
+HINTERNET InternetOpen(char* lpszAgent,int dwAccessType,char* lpszProxyName,char* lpszProxyBypass,int dwFlags){
+  HINTERNET ret;
+  ret.handle=curl_multi_init();
+  ret.agent=strdup(lpszAgent);
+  ret.nb=0;
+  ret.ihandle[ret.nb].header=NULL;
+  return ret;
+}
+
+/**
+ * Close a HINTERNET connection and free allocated ressources
+ *
+ * @param handle0 the HINTERNET connection to close
+ */
+void InternetCloseHandle(HINTERNET* handle0){
+  int i=0;
+  for(i=0;i<handle0->nb;i++){
+    _HINTERNET handle=handle0->ihandle[i];
+    if(handle.hasCacheFile>0){
+      fclose(handle.file);
+      unlink(handle.filename);
+    }
+    else{
+      handle.pabyData = NULL;
+      handle.nDataAlloc = handle.nDataLen = 0;
+    }
+    if(handle0->ihandle[i].header!=NULL){
+      curl_slist_free_all(handle0->ihandle[i].header);
+      handle0->ihandle[i].header=NULL;
+    }
+    if(handle.post!=NULL)
+      free(handle.post);
+    free(handle.mimeType);
+    handle.mimeType = NULL;
+  }
+  if(handle0->handle)
+    curl_multi_cleanup(handle0->handle);
+  free(handle0->agent);
+  for(i=handle0->nb-1;i>=0;i--){
+    free(handle0->waitingRequests[i]);
+  }
+}
+
+/**
+ * Create a new element in the download queue
+ *
+ * @param hInternet the HINTERNET connection to add the download link
+ * @param lpszUrl the url to download
+ * @param lpszHeaders the additional headers to be sent to the HTTP server
+ * @param dwHeadersLength the size of the additional headers
+ * @param dwFlags desired download mode (INTERNET_FLAG_NO_CACHE_WRITE for not using cache file)
+ * @param dwContext not used
+ */
+HINTERNET InternetOpenUrl(HINTERNET* hInternet,LPCTSTR lpszUrl,LPCTSTR lpszHeaders,size_t dwHeadersLength,size_t dwFlags,size_t dwContext){
+
+  char filename[255];
+  struct MemoryStruct header;
+
+  hInternet->ihandle[hInternet->nb].handle=curl_easy_init( );
+  hInternet->ihandle[hInternet->nb].hasCacheFile=0;
+  hInternet->ihandle[hInternet->nb].nDataAlloc = 0;
+  hInternet->ihandle[hInternet->nb].mimeType = NULL;
+  hInternet->ihandle[hInternet->nb].nDataLen = 0;
+  hInternet->ihandle[hInternet->nb].id = hInternet->nb;
+  hInternet->ihandle[hInternet->nb].nDataAlloc = 0;
+  hInternet->ihandle[hInternet->nb].pabyData = NULL;
+  hInternet->ihandle[hInternet->nb].post = NULL;
+
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_COOKIEFILE, "ALL");
+#ifndef TIGER
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_COOKIELIST, "ALL");
+#endif
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_USERAGENT, hInternet->agent);
+  
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_FOLLOWLOCATION,1);
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_MAXREDIRS,3);
+  
+  header.memory=NULL;
+  header.size = 0;
+
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_HEADERFUNCTION, header_write_data);
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEHEADER, (void *)&header);
+
+#ifdef MSG_LAF_VERBOSE
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_VERBOSE, 1);
+#endif
+
+      
+  switch(dwFlags)
+    {
+    case INTERNET_FLAG_NO_CACHE_WRITE:
+      hInternet->ihandle[hInternet->nb].hasCacheFile=-1;
+      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEFUNCTION, write_data_into);
+      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEDATA, (void*)&hInternet->ihandle[hInternet->nb]);
+      break;
+    default:
+      sprintf(hInternet->ihandle[hInternet->nb].filename,"/tmp/ZOO_Cache%d",(int)time(NULL));
+      hInternet->ihandle[hInternet->nb].filename[24]=0;
+#ifdef MSG_LAF_VERBOSE
+      fprintf(stderr,"file=%s",hInternet->ihandle[hInternet->nb].filename);
+#endif
+      hInternet->ihandle[hInternet->nb].filename=filename;
+      hInternet->ihandle[hInternet->nb].file=fopen(hInternet->ihandle[hInternet->nb].filename,"w+");
+    
+      hInternet->ihandle[hInternet->nb].hasCacheFile=1;
+      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEFUNCTION, NULL);
+      curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle, CURLOPT_WRITEDATA, hInternet->ihandle[hInternet->nb].file);
+      hInternet->ihandle[hInternet->nb].nDataLen=0;
+      break;
+    }
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"URL (%s)\nBODY (%s)\n",lpszUrl,lpszHeaders);
+#endif
+  if(lpszHeaders!=NULL && strlen(lpszHeaders)>0){
+#ifdef MSG_LAF_VERBOSE
+    fprintf(stderr,"FROM ULINET !!");
+    fprintf(stderr,"HEADER : [%s] %d\n",lpszHeaders,dwHeadersLength);
+#endif
+    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POST,1);
+#ifdef ULINET_DEBUG
+    fprintf(stderr,"** (%s) %d **\n",lpszHeaders,dwHeadersLength);
+    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_VERBOSE,1);
+#endif
+    hInternet->ihandle[hInternet->nb].post=strdup(lpszHeaders);
+    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POSTFIELDS,hInternet->ihandle[hInternet->nb].post);
+    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_POSTFIELDSIZE,(long)dwHeadersLength);
+  }
+  if(hInternet->ihandle[hInternet->nb].header!=NULL)
+    curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_HTTPHEADER,hInternet->ihandle[hInternet->nb].header);
+
+  curl_easy_setopt(hInternet->ihandle[hInternet->nb].handle,CURLOPT_URL,lpszUrl);
+
+  curl_multi_add_handle(hInternet->handle,hInternet->ihandle[hInternet->nb].handle);
+  
+  hInternet->ihandle[hInternet->nb].header=NULL;
+  ++hInternet->nb;
+
+#ifdef ULINET_DEBUG
+  fprintf(stderr,"DEBUG MIMETYPE: %s\n",hInternet.mimeType);
+  fflush(stderr);
+#endif
+  return *hInternet;
+};
+
+/**
+ * Download all opened urls in the queue
+ *
+ * @param hInternet the HINTERNET structure containing the queue
+ * @return 0
+ */
+int processDownloads(HINTERNET* hInternet){
+  int still_running=0;
+  int msgs_left=0;
+  int i=0;
+  do{
+    curl_multi_perform(hInternet->handle, &still_running);
+  }while(still_running);  
+  for(i=0;i<hInternet->nb;i++){
+    char *tmp;
+    curl_easy_getinfo(hInternet->ihandle[i].handle,CURLINFO_CONTENT_TYPE,&tmp);
+    if(tmp!=NULL)
+      hInternet->ihandle[i].mimeType=strdup(tmp);
+    curl_easy_getinfo(hInternet->ihandle[i].handle,CURLINFO_RESPONSE_CODE,&hInternet->ihandle[i].code);
+    curl_multi_remove_handle(hInternet->handle, hInternet->ihandle[i].handle);
+    curl_easy_cleanup(hInternet->ihandle[i].handle);
+  }
+  return 0;
+}
+
+/**
+ * Initialize the CCookie for a specific index (hInternet.nb)
+ *
+ * @param hInternet the HINTERNET structure to know the CCookie index to reset
+ * @return 1
+ * @see HINTERNET
+ */
+int freeCookieList(HINTERNET hInternet){
+  memset(&CCookie[hInternet.nb][0],0,1024);
+#ifndef TIGER
+  curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_COOKIELIST, "ALL");
+#endif
+  return 1;
+}
+
+/**
+ * Copy a downloaded content
+ * 
+ * @param hInternet the _HINTERNET structure
+ * @param lpBuffer the memory space to copy the downloaded content
+ * @param dwNumberOfBytesToRead the size of lpBuffer
+ * @param lpdwNumberOfBytesRead number of bytes red
+ * @return 1 on success, 0 if failure
+ */
+int InternetReadFile(_HINTERNET hInternet,LPVOID lpBuffer,int dwNumberOfBytesToRead, size_t *lpdwNumberOfBytesRead){
+  int dwDataSize;
+
+  if(hInternet.hasCacheFile>0){
+    fseek (hInternet.file , 0 , SEEK_END);
+    dwDataSize=ftell(hInternet.file); //taille du ficher
+    rewind (hInternet.file);
+  }
+  else{
+    memset(lpBuffer,0,hInternet.nDataLen+1);
+    memcpy(lpBuffer, hInternet.pabyData, hInternet.nDataLen );
+    dwDataSize=hInternet.nDataLen;
+    free( hInternet.pabyData );
+    hInternet.pabyData=NULL;
+  }
+
+  if( dwNumberOfBytesToRead /* buffer size */ < dwDataSize )
+    return 0;
+
+#ifdef MSG_LAF_VERBOSE
+  printf("\nfile size : %dko\n",dwDataSize/1024);
+#endif
+
+  if(hInternet.hasCacheFile>0){
+    *lpdwNumberOfBytesRead = fread(lpBuffer,1,dwDataSize,hInternet.file); 
+  }
+  else{
+    *lpdwNumberOfBytesRead = hInternet.nDataLen;
+    free( hInternet.pabyData );
+    hInternet.pabyData = NULL;
+    hInternet.nDataAlloc = hInternet.nDataLen = 0;
+  }
+
+  CCookie[hInternet.id][0]=0;
+
+  if( *lpdwNumberOfBytesRead < dwDataSize )
+      return 0;
+  else
+      return 1; // TRUE
+}
+
+
+/**
+ * Use basic authentication for accessing a ressource
+ * 
+ * @param hInternet the _HINTERNET structure
+ * @param login the login to use to authenticate
+ * @param passwd the password to use to authenticate
+ */
+int setBasicAuth(HINTERNET hInternet,char* login,char* passwd){
+  char *tmp;
+  tmp=(char*)malloc((strlen(login)+strlen(passwd)+2)*sizeof(char));
+  sprintf(tmp,"%s:%s",login,passwd);
+  if(curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle,CURLOPT_USERPWD,tmp)==CURLE_OUT_OF_MEMORY){
+    free(tmp);
+    return -1;
+  }
+  curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_HTTPAUTH,CURLAUTH_ANY);
+  free(tmp);
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/ulinet.h	(revision 672)
@@ -0,0 +1,176 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2008-2009 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef _ULINET_H
+#define _ULINET_H
+
+#include "fcgi_stdio.h"
+#include <stdlib.h>
+#include <fcntl.h>
+#include <curl/curl.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <string.h>
+#include "time.h"
+#ifdef USE_JS
+#ifdef WIN32
+#define XP_WIN 1
+#else
+#define XP_UNIX 0
+#endif
+#include "jsapi.h"
+#endif
+#ifndef bool
+#define bool int
+#endif
+#ifndef true
+#define true 1
+#define false 0
+#endif
+
+#define MAX_REQ 50
+
+#ifdef _ULINET
+static char CCookie[MAX_REQ][1024];
+#else
+/**
+ * The cookies found
+ */
+extern char CCookie[MAX_REQ][1024];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /**
+   * Headers storage
+   * @see header_write_data
+   */
+  struct MemoryStruct {
+    char *memory; //!< the memory space to store data 
+    size_t size; //!< size of the memory space
+  };
+
+  /**
+   * Individual CURL handler
+   */
+  typedef struct {
+    CURL *handle; //!< the CURL handler
+    struct curl_slist *header; //!< the headers to send
+    char* filename; //!< the cached file name
+    FILE* file; //!< the file pointer
+    unsigned char *pabyData; //!< the downloaded content
+    char *mimeType; //!< the mimeType returned by the server
+    char *post; //!< the potential POST XML content
+    int hasCacheFile; //!< 1 if we used a cache file
+    int nDataLen; //!< the length of the downloaded content
+    int nDataAlloc; //!< 
+    long code; //!< the last received response code
+    int id; //!< The position of the element in the queue
+  } _HINTERNET;
+
+  /**
+   * Multiple CURL handlers
+   */
+  typedef struct {
+    CURLM *handle; //!< the CURLM handler
+    _HINTERNET ihandle[MAX_REQ]; //!< individual handlers in the queue 
+    char *waitingRequests[MAX_REQ]; //!< request in the queue
+    char *agent; //!< The User-Agent to use for HTTP request
+    int nb; //!< number of element in the queue 
+  } HINTERNET;
+
+  size_t write_data_into(void*,size_t,size_t,void*);
+
+  size_t header_write_data(void*,size_t,size_t,void*);
+
+  void setProxy(CURL*,char*,long);
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+
+#include <CoreServices/CoreServices.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+  char* CFStringToCString(CFStringRef,char*);
+  OSStatus setProxiesForProtcol(CURL*,const char*);
+
+#else
+
+//#include <gconf/gconf-client.h>
+  int setProxiesForProtcol(CURL*,const char*);
+
+#endif
+
+
+#define INTERNET_OPEN_TYPE_DIRECT                      0
+#define INTERNET_OPEN_TYPE_PRECONFIG                   1
+#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 2
+#define INTERNET_OPEN_TYPE_PROXY                       3
+#ifndef WIN32
+typedef char* LPCTSTR;
+#endif
+  HINTERNET InternetOpen(char*,int,char*,char*,int);
+
+  void InternetCloseHandle(HINTERNET*);
+
+#define INTERNET_FLAG_EXISTING_CONNECT         0
+#define INTERNET_FLAG_HYPERLINK                1
+#define INTERNET_FLAG_IGNORE_CERT_CN_INVALID   2
+#define INTERNET_FLAG_IGNORE_CERT_DATE_INVALID 3
+#define INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP  4
+#define INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS 5
+#define INTERNET_FLAG_KEEP_CONNECTION          6
+#define INTERNET_FLAG_NEED_FILE                7
+#define INTERNET_FLAG_NO_AUTH                  8
+#define INTERNET_FLAG_NO_AUTO_REDIRECT         9
+#define INTERNET_FLAG_NO_CACHE_WRITE          10
+//typedef char* LPVOID;
+#ifndef WIN32
+  typedef void* LPVOID;
+  typedef void* LPTSTR;
+  typedef size_t* LPDWORD;
+#endif
+#ifndef bool
+#define bool int
+#endif
+
+#  define CHECK_INET_HANDLE(h) (h.handle != 0)
+
+  HINTERNET InternetOpenUrl(HINTERNET*,LPCTSTR,LPCTSTR,size_t,size_t,size_t);
+
+  int processDownloads(HINTERNET*);
+
+  int freeCookieList(HINTERNET);
+
+  int InternetReadFile(_HINTERNET,LPVOID,int,size_t*);
+
+  int setBasicAuth(HINTERNET,char*,char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zcfg2yaml.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 672)
@@ -0,0 +1,44 @@
+/**
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2014 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "server_internal.h"
+#include "response_print.h"
+#include "service.h"
+
+extern   int getServiceFromFile(maps*,const char*,service**);
+
+int main(int argc, char** argv){
+  service* s1=NULL;
+  maps *m=NULL;
+  char conf_file[1024];
+  snprintf(conf_file,1024,"%s",argv[1]);
+  s1=(service*)malloc(SERVICE_SIZE);
+  if(s1 == NULL){ 
+    return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
+  }
+  int t=getServiceFromFile(m,conf_file,&s1);
+  if(t>=0)
+    dumpServiceAsYAML(s1);
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_loader.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_loader.c	(revision 672)
@@ -0,0 +1,423 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2008-2011 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#define MALLOC_CHECK_ 0
+#define MALLOC_CHECK 0
+
+/**
+ * Specific includes
+ */
+#ifndef WIN32
+#include "fcgio.h"
+#include "fcgi_config.h" 
+#include "fcgi_stdio.h"
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+#include "service_internal.h"
+#include "response_print.h"
+
+
+#ifdef WIN32
+#include "windows.h"
+#define strtok_r strtok_s
+#endif
+
+extern "C" {
+#include "cgic.h"
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+}
+
+#include "service_internal.h"
+#include "request_parser.h"
+
+int runRequest(map**);
+
+using namespace std;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE -1
+#endif
+
+/**
+ * Main entry point for cgic.
+ * @return 0 on sucess.
+ */
+int cgiMain(){
+  /**
+   * We'll use cgiOut as the default output (stdout) to produce plain text 
+   * response.
+   */
+  dup2(fileno(cgiOut),fileno(stdout));
+#ifdef DEBUG
+  fprintf(cgiOut,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
+  fprintf(cgiOut,"Welcome on ZOO verbose debuging mode \r\n\r\n");
+  fflush(cgiOut);
+  fprintf (stderr, "Addr:%s\n", cgiRemoteAddr); 
+  fprintf (stderr, "RequestMethod: (%s) %d %d\n", cgiRequestMethod,strncasecmp(cgiRequestMethod,"post",4),strncmp(cgiContentType,"text/xml",8)==0 || strncasecmp(cgiRequestMethod,"post",4)==0); 
+  fprintf (stderr, "Request: %s\n", cgiQueryString);
+  fprintf (stderr, "ContentType: %s\n", cgiContentType);
+  fprintf (stderr, "ContentLength: %d\n", cgiContentLength);
+  fflush(stderr);
+#endif
+  
+  char *strQuery=NULL;
+  if(cgiQueryString!=NULL)
+    strQuery=zStrdup(cgiQueryString);
+  map* tmpMap=NULL;
+
+  if(strncmp(cgiContentType,"text/xml",8)==0 || 
+     strncasecmp(cgiRequestMethod,"post",4)==0){
+    if(cgiContentLength==0){
+       char *buffer=new char[2];
+       char *res=NULL;
+       int r=0;
+       while((r=fread(buffer,sizeof(char),1,cgiIn))){
+	 buffer[1]=0;
+	 if(res==NULL){
+	   res=(char*)malloc(2*sizeof(char));
+	   sprintf(res,"%s",buffer);
+	 }
+	 else{
+	   res=(char*)realloc(res,(cgiContentLength+2)*sizeof(char));
+	   memcpy(res + cgiContentLength, buffer, sizeof(char));
+	   res[cgiContentLength+1]=0;
+	 }
+	 cgiContentLength+=r;
+       }
+       delete[] buffer;
+       if(res==NULL && (strQuery==NULL || strlen(strQuery)==0)){
+	 return errorException(NULL,"ZOO-Kernel failed to process your request because the request was empty.","InternalError",NULL);
+       }else{
+	 if(strQuery==NULL || strlen(strQuery)==0)
+	   tmpMap=createMap("request",res);
+       }
+       if(res!=NULL)
+	 free(res);
+    }else{
+      char *buffer=new char[cgiContentLength+1];
+      if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>0){
+	buffer[cgiContentLength]=0;
+	tmpMap=createMap("request",buffer);
+      }else{
+	buffer[0]=0;
+	char **array, **arrayStep;
+	if (cgiFormEntries(&array) != cgiFormSuccess) {
+	  return 1;
+	}
+	arrayStep = array;
+	while (*arrayStep) {
+	  char *ivalue=new char[cgiContentLength];
+	  cgiFormStringNoNewlines(*arrayStep, ivalue, cgiContentLength);
+	  char* tmpValueFinal=(char*) malloc((strlen(*arrayStep)+strlen(ivalue)+2)*sizeof(char));	
+	  sprintf(tmpValueFinal,"%s=%s",*arrayStep,ivalue);
+
+	  if(strlen(buffer)==0){		
+	    sprintf(buffer,"%s",tmpValueFinal);
+	  }else{		
+	    char *tmp=zStrdup(buffer);
+	    sprintf(buffer,"%s&%s",tmp,tmpValueFinal);
+	    free(tmp);
+	  }	  
+	  free(tmpValueFinal);
+#ifdef DEBUG
+	  fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,ivalue);
+#endif
+	  delete[]ivalue;
+	  arrayStep++;
+	}	
+	if(tmpMap!=NULL)
+	  addToMap(tmpMap,"request",buffer);
+	else
+	  tmpMap=createMap("request",buffer);
+      }
+      delete[]buffer;
+    }	
+  }
+  else{
+#ifdef DEBUG
+    dumpMap(tmpMap);
+#endif
+    char **array, **arrayStep;
+    if (cgiFormEntries(&array) != cgiFormSuccess) {
+      return 1;
+    }
+    arrayStep = array;
+    while (*arrayStep) {
+      char *value=new char[cgiContentLength];
+      cgiFormStringNoNewlines(*arrayStep, value, cgiContentLength);
+#ifdef DEBUG
+      fprintf(stderr,"(( \n %s \n %s \n ))",*arrayStep,value);
+#endif
+#ifdef WIN32
+      char* tmp = url_decode(value); 
+      if(tmpMap!=NULL)		
+        addToMap(tmpMap,*arrayStep,tmp);
+      else		
+        tmpMap=createMap(*arrayStep,tmp);
+      free(tmp);
+#else
+      if(tmpMap!=NULL)
+        addToMap(tmpMap,*arrayStep,value);
+      else
+        tmpMap=createMap(*arrayStep,value);
+#endif	
+      arrayStep++;
+      delete[]value;
+    }
+    cgiStringArrayFree(array);
+  }
+
+#ifdef WIN32
+  map *tmpReq=getMap(tmpMap,"rfile");
+  if(tmpReq!=NULL){
+    FILE *lf=fopen(tmpReq->value,"r");
+    fseek(lf,0,SEEK_END);
+    long flen=ftell(lf);
+    fseek(lf,0,SEEK_SET);
+    char *buffer=(char*)malloc((flen+1)*sizeof(char));
+    fread(buffer,flen,1,lf);
+    fclose(lf);
+    addToMap(tmpMap,"request",buffer);
+    free(buffer);
+    cgiContentLength=flen+9;
+  }
+#endif
+  /**
+   * In case that the POST method was used, then check if params came in XML
+   * format else try to use the attribute "request" which should be the only 
+   * one.
+   */
+  if(strncasecmp(cgiRequestMethod,"post",4)==0 || 
+     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0) 
+#ifdef WIN32
+     ||tmpReq!=NULL
+#endif
+     ){
+    /**
+     * Store the original XML request in xrequest map
+     */
+    map* t1=getMap(tmpMap,"request");
+    if(t1!=NULL && strncasecmp(t1->value,"<",1)==0) {
+      addToMap(tmpMap,"xrequest",t1->value);
+      xmlInitParser();
+      xmlDocPtr doc = xmlParseMemory(t1->value,cgiContentLength);
+      {
+	xmlXPathObjectPtr reqptr=extractFromDoc(doc,"/*[local-name()='Envelope']/*[local-name()='Body']/*");
+	if(reqptr!=NULL){
+	  xmlNodeSet* req=reqptr->nodesetval;
+	  if(req!=NULL && req->nodeNr==1){
+	    addToMap(tmpMap,"soap","true");
+	    for(int k=0;k < req->nodeNr;k++){
+	      xmlDocSetRootElement(doc, req->nodeTab[k]);
+	      xmlChar *xmlbuff;
+	      int buffersize;
+	      xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
+	      addToMap(tmpMap,"xrequest",(char*)xmlbuff);
+	      xmlFree(xmlbuff);
+	    }
+	  }
+	  xmlXPathFreeObject(reqptr);
+	}
+      }
+
+      xmlNodePtr cur = xmlDocGetRootElement(doc);
+      char *tval;
+      tval=NULL;
+      tval = (char*) xmlGetProp(cur,BAD_CAST "service");
+      if(tval!=NULL){
+	addToMap(tmpMap,"service",tval);
+	xmlFree(tval);
+      }
+      tval=NULL;
+      tval = (char*) xmlGetProp(cur,BAD_CAST "language");
+      if(tval!=NULL){
+	addToMap(tmpMap,"language",tval);
+	xmlFree(tval);
+      }
+      const char* requests[3]={"GetCapabilities","DescribeProcess","Execute"};
+      for(int j=0;j<3;j++){
+	char tt[128];
+	sprintf(tt,"/*[local-name()='%s']",requests[j]);
+	xmlXPathObjectPtr reqptr=extractFromDoc(doc,tt);
+	if(reqptr!=NULL){
+	  xmlNodeSet* req=reqptr->nodesetval;
+#ifdef DEBUG
+	  fprintf(stderr,"%i",req->nodeNr);
+#endif
+	  if(req!=NULL && req->nodeNr==1){
+	    if(t1->value!=NULL)
+	      free(t1->value);
+	    t1->value=zStrdup(requests[j]);
+	    j=2;
+	  }
+	  xmlXPathFreeObject(reqptr);
+	}
+      }
+      if(strncasecmp(t1->value,"GetCapabilities",15)==0){
+	xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
+	xmlNodeSet* vers=versptr->nodesetval;
+	if(vers!=NULL && vers->nodeTab!=NULL && vers->nodeTab[0]!=NULL){
+	  xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
+	  addToMap(tmpMap,"version",(char*)content);
+	  xmlFree(content);
+	}
+	if(cur->ns){
+	  addToMap(tmpMap,"wps_schemas",(char*)cur->ns->href);
+	  int j=0;
+	  for(j=0;j<2;j++)
+	    if(strncasecmp(schemas[j][2],(char*)cur->ns->href,strlen(schemas[j][2]))==0){
+	      char vers[6];
+	      sprintf(vers,"%d.0.0",j+1);
+	      addToMap(tmpMap,"version",(char*)vers);
+	    }
+	}
+	xmlXPathFreeObject(versptr);
+      }else{
+	tval=NULL;
+	tval = (char*) xmlGetProp(cur,BAD_CAST "version");
+	if(tval!=NULL){
+	  addToMap(tmpMap,"version",tval);
+	  xmlFree(tval);
+	}
+	tval = (char*) xmlGetProp(cur,BAD_CAST "language");
+	if(tval!=NULL){
+	  addToMap(tmpMap,"language",tval);
+	  xmlFree(tval);
+	}
+	xmlXPathObjectPtr idptr=extractFromDoc(doc,"/*/*[local-name()='Identifier']");
+	if(idptr!=NULL){
+	  xmlNodeSet* id=idptr->nodesetval;
+	  if(id!=NULL){
+	    char* identifiers=NULL;
+	    identifiers=(char*)calloc(cgiContentLength,sizeof(char));
+	    identifiers[0]=0;
+	    for(int k=0;k<id->nodeNr;k++){
+	      xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
+	      if(strlen(identifiers)>0){
+		char *tmp=zStrdup(identifiers);
+		snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
+		free(tmp);
+	      }
+	      else{
+		snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
+	      }
+	      xmlFree(content);
+	    }
+	    xmlXPathFreeObject(idptr);
+	    addToMap(tmpMap,"Identifier",identifiers);
+	    free(identifiers);
+	  }
+	}else{
+	  idptr=extractFromDoc(doc,"/*/*[local-name()='JobID']");
+	  if(idptr!=NULL){
+	    xmlNodeSet* id=idptr->nodesetval;
+	    if(id!=NULL){
+	      char* identifiers=NULL;
+	      identifiers=(char*)calloc(cgiContentLength,sizeof(char));
+	      identifiers[0]=0;
+	      for(int k=0;k<id->nodeNr;k++){
+		xmlChar* content=xmlNodeListGetString(doc, id->nodeTab[k]->xmlChildrenNode,1);
+		if(strlen(identifiers)>0){
+		  char *tmp=zStrdup(identifiers);
+		  snprintf(identifiers,strlen(tmp)+xmlStrlen(content)+2,"%s,%s",tmp,content);
+		  free(tmp);
+		}
+		else{
+		  snprintf(identifiers,xmlStrlen(content)+1,"%s",content);
+		}
+		xmlFree(content);
+	      }
+	      xmlXPathFreeObject(idptr);
+	      addToMap(tmpMap,"JobID",identifiers);
+	      free(identifiers);
+	    }
+	}
+	}
+      }
+      xmlFreeDoc(doc);
+      xmlCleanupParser();
+    }else{
+      freeMap(&tmpMap);
+      free(tmpMap);
+      tmpMap=createMap("not_valid","true");
+    }
+
+    char *token,*saveptr;
+    token=strtok_r(cgiQueryString,"&",&saveptr);
+    while(token!=NULL){
+      char *token1,*saveptr1;
+      char *name=NULL;
+      char *value=NULL;
+      token1=strtok_r(token,"=",&saveptr1);
+      while(token1!=NULL){
+        if(name==NULL)
+          name=zStrdup(token1);
+        else
+          value=zStrdup(token1);
+        token1=strtok_r(NULL,"=",&saveptr1);
+      }	  
+      //addToMap(tmpMap,name,value);
+	  /* knut: strtok(_r) ignores delimiter bytes at start and end of string; 
+	   * it will return non-empty string or NULL, e.g. "metapath=" yields value=NULL.
+	   * This modification sets value="" instead of NULL.
+	   */
+	  addToMap(tmpMap,name, value != NULL ? value : "");
+
+      free(name);
+      free(value);
+      name=NULL;
+      value=NULL;
+      token=strtok_r(NULL,"&",&saveptr);
+    }
+    
+  }
+
+  if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
+    map* tmp=getMap(tmpMap,"dataInputs");
+    if(tmp!=NULL){
+      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
+    }
+  }
+
+  if(strQuery!=NULL)
+    free(strQuery);
+
+  
+  runRequest(&tmpMap);
+
+  if(tmpMap!=NULL){
+    freeMap(&tmpMap);
+    free(tmpMap);
+  }
+  return 0;
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 672)
@@ -0,0 +1,2358 @@
+/*
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2008-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+extern "C" int yylex ();
+extern "C" int crlex ();
+
+#ifdef USE_OTB
+#include "service_internal_otb.h"
+#else
+#define length(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#include "cgic.h"
+
+extern "C"
+{
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+}
+
+#include "ulinet.h"
+
+#include <libintl.h>
+#include <locale.h>
+#include <string.h>
+
+#include "service.h"
+
+#include "service_internal.h"
+#include "server_internal.h"
+#include "response_print.h"
+#include "request_parser.h"
+#include "sqlapi.h"
+
+#ifdef USE_PYTHON
+#include "service_internal_python.h"
+#endif
+
+#ifdef USE_SAGA
+#include "service_internal_saga.h"
+#endif
+
+#ifdef USE_JAVA
+#include "service_internal_java.h"
+#endif
+
+#ifdef USE_PHP
+#include "service_internal_php.h"
+#endif
+
+#ifdef USE_JS
+#include "service_internal_js.h"
+#endif
+
+#ifdef USE_RUBY
+#include "service_internal_ruby.h"
+#endif
+
+#ifdef USE_PERL
+#include "service_internal_perl.h"
+#endif
+
+#include <dirent.h>
+#include <signal.h>
+#include <unistd.h>
+#ifndef WIN32
+#include <dlfcn.h>
+#include <libgen.h>
+#else
+#include <windows.h>
+#include <direct.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#define pid_t int;
+#endif
+#include <fcntl.h>
+#include <time.h>
+#include <stdarg.h>
+
+#ifdef WIN32
+extern "C"
+{
+  __declspec (dllexport) char *strcasestr (char const *a, char const *b)
+#ifndef USE_MS
+  {
+    char *x = zStrdup (a);
+    char *y = zStrdup (b);
+
+      x = _strlwr (x);
+      y = _strlwr (y);
+    char *pos = strstr (x, y);
+    char *ret = pos == NULL ? NULL : (char *) (a + (pos - x));
+      free (x);
+      free (y);
+      return ret;
+  };
+#else
+   ;
+#endif
+}
+#endif
+
+/**
+ * Translation function for zoo-kernel
+ */
+#define _(String) dgettext ("zoo-kernel",String)
+/**
+ * Translation function for zoo-service
+ */
+#define __(String) dgettext ("zoo-service",String)
+
+#ifdef WIN32
+  #ifndef PROGRAMNAME
+    #define PROGRAMNAME "zoo_loader.cgi"
+  #endif
+#endif
+
+extern int getServiceFromFile (maps *, const char *, service **);
+
+/**
+ * Parse the service file using getServiceFromFile or use getServiceFromYAML
+ * if YAML support was activated.
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param file the file name to parse
+ * @param service the service to update witht the file content
+ * @param name the service name
+ * @return true if the file can be parsed or false
+ * @see getServiceFromFile, getServiceFromYAML
+ */
+int
+readServiceFile (maps * conf, char *file, service ** service, char *name)
+{
+  int t = getServiceFromFile (conf, file, service);
+#ifdef YAML
+  if (t < 0)
+    {
+      t = getServiceFromYAML (conf, file, service, name);
+    }
+#endif
+  return t;
+}
+
+/**
+ * Replace a char by another one in a string
+ *
+ * @param str the string to update
+ * @param toReplace the char to replace
+ * @param toReplaceBy the char that will be used
+ */
+void
+translateChar (char *str, char toReplace, char toReplaceBy)
+{
+  int i = 0, len = strlen (str);
+  for (i = 0; i < len; i++)
+    {
+      if (str[i] == toReplace)
+        str[i] = toReplaceBy;
+    }
+}
+
+
+/**
+ * Create the profile registry.
+ *
+ * The profile registry is optional (created only if the registry key is
+ * available in the [main] section of the main.cfg file) and can be used to
+ * store the profiles hierarchy. The registry is a directory which should
+ * contain the following sub-directories: 
+ *  * concept: direcotry containing .html files describing concept
+ *  * generic: directory containing .zcfg files for wps:GenericProcess
+ *  * implementation: directory containing .zcfg files for wps:Process
+ *
+ * @param m the conf maps containing the main.cfg settings
+ * @param r the registry to update
+ * @param reg_dir the resgitry 
+ * @param saved_stdout the saved stdout identifier
+ * @return 0 if the resgitry is null or was correctly updated, -1 on failure
+ */
+int
+createRegistry (maps* m,registry ** r, char *reg_dir, int saved_stdout)
+{
+  struct dirent *dp;
+  int scount = 0;
+
+  if (reg_dir == NULL)
+    return 0;
+  DIR *dirp = opendir (reg_dir);
+  if (dirp == NULL)
+    {
+      return -1;
+    }
+  while ((dp = readdir (dirp)) != NULL){
+    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.')
+      {
+
+        char * tmpName =
+          (char *) malloc ((strlen (reg_dir) + strlen (dp->d_name) + 2) *
+                           sizeof (char));
+        sprintf (tmpName, "%s/%s", reg_dir, dp->d_name);
+	
+	DIR *dirp1 = opendir (tmpName);
+	struct dirent *dp1;
+	while ((dp1 = readdir (dirp1)) != NULL){
+	  char* extn = strstr(dp1->d_name, ".zcfg");
+	  if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
+	    {
+	      int t;
+	      char *tmps1=
+		(char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
+				 sizeof (char));
+	      sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
+	      char *tmpsn = zStrdup (dp1->d_name);
+	      tmpsn[strlen (tmpsn) - 5] = 0;
+	      service* s1 = (service *) malloc (SERVICE_SIZE);
+	      if (s1 == NULL)
+		{
+		  dup2 (saved_stdout, fileno (stdout));
+		  errorException (m, _("Unable to allocate memory."),
+				  "InternalError", NULL);
+		  return -1;
+		}
+	      t = readServiceFile (m, tmps1, &s1, tmpsn);
+	      free (tmpsn);
+	      if (t < 0)
+		{
+		  map *tmp00 = getMapFromMaps (m, "lenv", "message");
+		  char tmp01[1024];
+		  if (tmp00 != NULL)
+		    sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
+			     dp1->d_name, tmp00->value);
+		  else
+		    sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
+			     dp1->d_name);
+		  dup2 (saved_stdout, fileno (stdout));
+		  errorException (m, tmp01, "InternalError", NULL);
+		  return -1;
+		}
+#ifdef DEBUG
+	      dumpService (s1);
+	      fflush (stdout);
+	      fflush (stderr);
+#endif
+	      if(strncasecmp(dp->d_name,"implementation",14)==0){
+		inheritance(*r,&s1);
+	      }
+	      addServiceToRegistry(r,dp->d_name,s1);
+	      freeService (&s1);
+	      free (s1);
+	      scount++;
+	    }
+	}
+	(void) closedir (dirp1);
+      }
+  }
+  (void) closedir (dirp);
+  return 0;
+}
+
+/**
+ * Recursivelly parse zcfg starting from the ZOO-Kernel cwd.
+ * Call the func function given in arguments after parsing the ZCFG file.
+ *
+ * @param m the conf maps containing the main.cfg settings
+ * @param r the registry containing profiles hierarchy
+ * @param n the root XML Node to add the sub-elements
+ * @param conf_dir the location of the main.cfg file (basically cwd)
+ * @param prefix the current prefix if any, or NULL
+ * @param saved_stdout the saved stdout identifier
+ * @param level the current level (number of sub-directories to reach the
+ * current path)
+ * @see inheritance, readServiceFile
+ */
+int
+recursReaddirF (maps * m, registry *r, xmlNodePtr n, char *conf_dir, char *prefix,
+                int saved_stdout, int level, void (func) (maps *, xmlNodePtr,
+                                                          service *))
+{
+  struct dirent *dp;
+  int scount = 0;
+
+  if (conf_dir == NULL)
+    return 1;
+  DIR *dirp = opendir (conf_dir);
+  if (dirp == NULL)
+    {
+      if (level > 0)
+        return 1;
+      else
+        return -1;
+    }
+  char tmp1[25];
+  sprintf (tmp1, "sprefix_%d", level);
+  char levels[17];
+  sprintf (levels, "%d", level);
+  setMapInMaps (m, "lenv", "level", levels);
+  while ((dp = readdir (dirp)) != NULL)
+    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.'
+        && strstr (dp->d_name, ".") == NULL)
+      {
+
+        char *tmp =
+          (char *) malloc ((strlen (conf_dir) + strlen (dp->d_name) + 2) *
+                           sizeof (char));
+        sprintf (tmp, "%s/%s", conf_dir, dp->d_name);
+
+        if (prefix != NULL)
+          {
+            prefix = NULL;
+          }
+        prefix = (char *) malloc ((strlen (dp->d_name) + 2) * sizeof (char));
+        sprintf (prefix, "%s.", dp->d_name);
+
+        //map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
+
+        int res;
+        if (prefix != NULL)
+          {
+            setMapInMaps (m, "lenv", tmp1, prefix);
+            char levels1[17];
+            sprintf (levels1, "%d", level + 1);
+            setMapInMaps (m, "lenv", "level", levels1);
+            res =
+              recursReaddirF (m, r, n, tmp, prefix, saved_stdout, level + 1,
+                              func);
+            sprintf (levels1, "%d", level);
+            setMapInMaps (m, "lenv", "level", levels1);
+            free (prefix);
+            prefix = NULL;
+          }
+        else
+          res = -1;
+        free (tmp);
+        if (res < 0)
+          {
+            return res;
+          }
+      }
+    else
+      {
+        char* extn = strstr(dp->d_name, ".zcfg");
+        if(dp->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
+          {
+            int t;
+            char tmps1[1024];
+            memset (tmps1, 0, 1024);
+            snprintf (tmps1, 1024, "%s/%s", conf_dir, dp->d_name);
+            service *s1 = (service *) malloc (SERVICE_SIZE);
+            if (s1 == NULL)
+              {
+                dup2 (saved_stdout, fileno (stdout));
+                errorException (m, _("Unable to allocate memory."),
+                                "InternalError", NULL);
+                return -1;
+              }
+#ifdef DEBUG
+            fprintf (stderr, "#################\n%s\n#################\n",
+                     tmps1);
+#endif
+            char *tmpsn = zStrdup (dp->d_name);
+            tmpsn[strlen (tmpsn) - 5] = 0;
+            t = readServiceFile (m, tmps1, &s1, tmpsn);
+            free (tmpsn);
+            if (t < 0)
+              {
+                map *tmp00 = getMapFromMaps (m, "lenv", "message");
+                char tmp01[1024];
+                if (tmp00 != NULL)
+                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
+                           dp->d_name, tmp00->value);
+                else
+                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
+                           dp->d_name);
+                dup2 (saved_stdout, fileno (stdout));
+                errorException (m, tmp01, "InternalError", NULL);
+                return -1;
+              }
+#ifdef DEBUG
+            dumpService (s1);
+            fflush (stdout);
+            fflush (stderr);
+#endif
+	    inheritance(r,&s1);
+            func (m, n, s1);
+            freeService (&s1);
+            free (s1);
+            scount++;
+          }
+      }
+  (void) closedir (dirp);
+  return 1;
+}
+
+/**
+ * Signal handling function which simply call exit(0).
+ *
+ * @param sig the signal number
+ */
+void
+donothing (int sig)
+{
+#ifdef DEBUG
+  fprintf (stderr, "Signal %d after the ZOO-Kernel returned result!\n", sig);
+#endif
+  exit (0);
+}
+
+/**
+ * Signal handling function which create an ExceptionReport node containing the
+ * information message corresponding to the signal number.
+ *
+ * @param sig the signal number
+ */
+void
+sig_handler (int sig)
+{
+  char tmp[100];
+  const char *ssig;
+  switch (sig)
+    {
+    case SIGSEGV:
+      ssig = "SIGSEGV";
+      break;
+    case SIGTERM:
+      ssig = "SIGTERM";
+      break;
+    case SIGINT:
+      ssig = "SIGINT";
+      break;
+    case SIGILL:
+      ssig = "SIGILL";
+      break;
+    case SIGFPE:
+      ssig = "SIGFPE";
+      break;
+    case SIGABRT:
+      ssig = "SIGABRT";
+      break;
+    default:
+      ssig = "UNKNOWN";
+      break;
+    }
+  sprintf (tmp,
+           _
+           ("ZOO Kernel failed to process your request, receiving signal %d = %s"),
+           sig, ssig);
+  errorException (NULL, tmp, "InternalError", NULL);
+#ifdef DEBUG
+  fprintf (stderr, "Not this time!\n");
+#endif
+  exit (0);
+}
+
+/**
+ * Load a service provider and run the service function.
+ *
+ * @param myMap the conf maps containing the main.cfg settings
+ * @param s1 the service structure
+ * @param request_inputs map storing all the request parameters
+ * @param inputs the inputs maps
+ * @param ioutputs the outputs maps
+ * @param eres the result returned by the service execution
+ */
+void
+loadServiceAndRun (maps ** myMap, service * s1, map * request_inputs,
+                   maps ** inputs, maps ** ioutputs, int *eres)
+{
+  char tmps1[1024];
+  char ntmp[1024];
+  maps *m = *myMap;
+  maps *request_output_real_format = *ioutputs;
+  maps *request_input_real_format = *inputs;
+  /**
+   * Extract serviceType to know what kind of service should be loaded
+   */
+  map *r_inputs = NULL;
+#ifndef WIN32
+  getcwd (ntmp, 1024);
+#else
+  _getcwd (ntmp, 1024);
+#endif
+  r_inputs = getMap (s1->content, "serviceType");
+#ifdef DEBUG
+  fprintf (stderr, "LOAD A %s SERVICE PROVIDER \n", r_inputs->value);
+  fflush (stderr);
+#endif
+
+  map* libp = getMapFromMaps(m, "main", "libPath");
+  
+  if (strlen (r_inputs->value) == 1
+      && strncasecmp (r_inputs->value, "C", 1) == 0)
+  {
+     if (libp != NULL && libp->value != NULL) {
+	    r_inputs = getMap (s1->content, "ServiceProvider");
+		sprintf (tmps1, "%s/%s", libp->value, r_inputs->value);
+	 }
+     else {	 
+        r_inputs = getMap (request_inputs, "metapath");
+        if (r_inputs != NULL)
+          sprintf (tmps1, "%s/%s", ntmp, r_inputs->value);
+        else
+          sprintf (tmps1, "%s/", ntmp);
+	  
+        char *altPath = zStrdup (tmps1);
+        r_inputs = getMap (s1->content, "ServiceProvider");
+        sprintf (tmps1, "%s/%s", altPath, r_inputs->value);
+        free (altPath);
+	 }
+#ifdef DEBUG
+      fprintf (stderr, "Trying to load %s\n", tmps1);
+#endif
+#ifdef WIN32
+      HINSTANCE so =
+        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+#else
+      void *so = dlopen (tmps1, RTLD_LAZY);
+#endif
+#ifdef WIN32
+      char* errstr = getLastErrorMessage();
+#else
+      char *errstr;
+      errstr = dlerror ();
+#endif
+#ifdef DEBUG
+	  fprintf (stderr, "%s loaded (%s) \n", tmps1, errstr);
+#endif
+      if (so != NULL)
+        {
+#ifdef DEBUG
+          fprintf (stderr, "Library loaded %s \n", errstr);
+          fprintf (stderr, "Service Shared Object = %s\n", r_inputs->value);
+#endif
+          r_inputs = getMap (s1->content, "serviceType");
+#ifdef DEBUG
+          dumpMap (r_inputs);
+          fprintf (stderr, "%s\n", r_inputs->value);
+          fflush (stderr);
+#endif
+          if (strncasecmp (r_inputs->value, "C-FORTRAN", 9) == 0)
+            {
+              r_inputs = getMap (request_inputs, "Identifier");
+              char fname[1024];
+              sprintf (fname, "%s_", r_inputs->value);
+#ifdef DEBUG
+              fprintf (stderr, "Try to load function %s\n", fname);
+#endif
+#ifdef WIN32
+              typedef int (CALLBACK * execute_t) (char ***, char ***,
+                                                  char ***);
+              execute_t execute = (execute_t) GetProcAddress (so, fname);
+#else
+              typedef int (*execute_t) (char ***, char ***, char ***);
+              execute_t execute = (execute_t) dlsym (so, fname);
+#endif
+#ifdef DEBUG
+#ifdef WIN32
+			  errstr = getLastErrorMessage();
+#else
+              errstr = dlerror ();
+#endif
+              fprintf (stderr, "Function loaded %s\n", errstr);
+#endif
+
+              char main_conf[10][30][1024];
+              char inputs[10][30][1024];
+              char outputs[10][30][1024];
+              for (int i = 0; i < 10; i++)
+                {
+                  for (int j = 0; j < 30; j++)
+                    {
+                      memset (main_conf[i][j], 0, 1024);
+                      memset (inputs[i][j], 0, 1024);
+                      memset (outputs[i][j], 0, 1024);
+                    }
+                }
+              mapsToCharXXX (m, (char ***) main_conf);
+              mapsToCharXXX (request_input_real_format, (char ***) inputs);
+              mapsToCharXXX (request_output_real_format, (char ***) outputs);
+              *eres =
+                execute ((char ***) &main_conf[0], (char ***) &inputs[0],
+                         (char ***) &outputs[0]);
+#ifdef DEBUG
+              fprintf (stderr, "Function run successfully \n");
+#endif
+              charxxxToMaps ((char ***) &outputs[0],
+                             &request_output_real_format);
+            }
+          else
+            {
+#ifdef DEBUG
+#ifdef WIN32
+			  errstr = getLastErrorMessage();
+              fprintf (stderr, "Function %s failed to load because of %s\n",
+                       r_inputs->value, errstr);
+#endif
+#endif
+              r_inputs = getMapFromMaps (m, "lenv", "Identifier");
+#ifdef DEBUG
+              fprintf (stderr, "Try to load function %s\n", r_inputs->value);
+#endif
+              typedef int (*execute_t) (maps **, maps **, maps **);
+#ifdef WIN32
+              execute_t execute =
+                (execute_t) GetProcAddress (so, r_inputs->value);
+#else
+              execute_t execute = (execute_t) dlsym (so, r_inputs->value);
+#endif
+
+              if (execute == NULL)
+                {
+#ifdef WIN32
+				  errstr = getLastErrorMessage();
+#else
+                  errstr = dlerror ();
+#endif
+                  char *tmpMsg =
+                    (char *) malloc (2048 + strlen (r_inputs->value));
+                  sprintf (tmpMsg,
+                           _
+                           ("Error occured while running the %s function: %s"),
+                           r_inputs->value, errstr);
+                  errorException (m, tmpMsg, "InternalError", NULL);
+                  free (tmpMsg);
+#ifdef DEBUG
+                  fprintf (stderr, "Function %s error %s\n", r_inputs->value,
+                           errstr);
+#endif
+                  *eres = -1;
+                  return;
+                }
+
+#ifdef DEBUG
+#ifdef WIN32
+			  errstr = getLastErrorMessage();
+#else
+              errstr = dlerror ();
+#endif
+              fprintf (stderr, "Function loaded %s\n", errstr);
+#endif
+
+#ifdef DEBUG
+              fprintf (stderr, "Now run the function \n");
+              fflush (stderr);
+#endif
+              *eres =
+                execute (&m, &request_input_real_format,
+                         &request_output_real_format);
+#ifdef DEBUG
+              fprintf (stderr, "Function loaded and returned %d\n", eres);
+              fflush (stderr);
+#endif
+            }
+#ifdef WIN32
+          *ioutputs = dupMaps (&request_output_real_format);
+          FreeLibrary (so);
+#else
+          dlclose (so);
+#endif
+        }
+      else
+        {
+      /**
+       * Unable to load the specified shared library
+       */
+          char tmps[1024];
+#ifdef WIN32
+		  errstr = getLastErrorMessage();
+#else
+	      errstr = dlerror ();
+#endif
+          sprintf (tmps, _("Unable to load C Library %s"), errstr);
+	  errorException(m,tmps,"InternalError",NULL);
+          *eres = -1;
+        }
+    }
+  else
+
+#ifdef USE_SAGA
+  if (strncasecmp (r_inputs->value, "SAGA", 6) == 0)
+    {
+      *eres =
+        zoo_saga_support (&m, request_inputs, s1,
+                            &request_input_real_format,
+                            &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_OTB
+  if (strncasecmp (r_inputs->value, "OTB", 6) == 0)
+    {
+      *eres =
+        zoo_otb_support (&m, request_inputs, s1,
+                            &request_input_real_format,
+                            &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_PYTHON
+  if (strncasecmp (r_inputs->value, "PYTHON", 6) == 0)
+    {
+      *eres =
+        zoo_python_support (&m, request_inputs, s1,
+                            &request_input_real_format,
+                            &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_JAVA
+  if (strncasecmp (r_inputs->value, "JAVA", 4) == 0)
+    {
+      *eres =
+        zoo_java_support (&m, request_inputs, s1, &request_input_real_format,
+                          &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_PHP
+  if (strncasecmp (r_inputs->value, "PHP", 3) == 0)
+    {
+      *eres =
+        zoo_php_support (&m, request_inputs, s1, &request_input_real_format,
+                         &request_output_real_format);
+    }
+  else
+#endif
+
+
+#ifdef USE_PERL
+  if (strncasecmp (r_inputs->value, "PERL", 4) == 0)
+    {
+      *eres =
+        zoo_perl_support (&m, request_inputs, s1, &request_input_real_format,
+                          &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_JS
+  if (strncasecmp (r_inputs->value, "JS", 2) == 0)
+    {
+      *eres =
+        zoo_js_support (&m, request_inputs, s1, &request_input_real_format,
+                        &request_output_real_format);
+    }
+  else
+#endif
+
+#ifdef USE_RUBY
+  if (strncasecmp (r_inputs->value, "Ruby", 4) == 0)
+    {
+      *eres =
+        zoo_ruby_support (&m, request_inputs, s1, &request_input_real_format,
+                          &request_output_real_format);
+    }
+  else
+#endif
+
+    {
+      char tmpv[1024];
+      sprintf (tmpv,
+               _
+               ("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),
+               r_inputs->value);
+      errorException (m, tmpv, "InternalError", NULL);
+      *eres = -1;
+    }
+  *myMap = m;
+  *ioutputs = request_output_real_format;
+}
+
+
+#ifdef WIN32
+/**
+ * createProcess function: create a new process after setting some env variables
+ */
+void
+createProcess (maps * m, map * request_inputs, service * s1, char *opts,
+               int cpid, maps * inputs, maps * outputs)
+{
+  STARTUPINFO si;
+  PROCESS_INFORMATION pi;
+  ZeroMemory (&si, sizeof (si));
+  si.cb = sizeof (si);
+  ZeroMemory (&pi, sizeof (pi));
+  char *tmp = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
+  char *tmpq = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
+  map *req = getMap (request_inputs, "request");
+  map *id = getMap (request_inputs, "identifier");
+  map *di = getMap (request_inputs, "DataInputs");
+
+  // The required size for the dataInputsKVP and dataOutputsKVP buffers
+  // may exceed cgiContentLength, hence a 2 kb extension. However, a 
+  // better solution would be to have getMapsAsKVP() determine the required
+  // buffer size before allocating memory.	
+  char *dataInputsKVP = getMapsAsKVP (inputs, cgiContentLength + 2048, 0);
+  char *dataOutputsKVP = getMapsAsKVP (outputs, cgiContentLength + 2048, 1);
+#ifdef DEBUG
+  fprintf (stderr, "DATAINPUTSKVP %s\n", dataInputsKVP);
+  fprintf (stderr, "DATAOUTPUTSKVP %s\n", dataOutputsKVP);
+#endif
+  map *sid = getMapFromMaps (m, "lenv", "sid");
+  map *r_inputs = getMapFromMaps (m, "main", "tmpPath");
+  map *r_inputs1 = getMap (request_inputs, "metapath");
+  
+  int hasIn = -1;
+  if (r_inputs1 == NULL)
+    {
+      r_inputs1 = createMap ("metapath", "");
+      hasIn = 1;
+    }
+  map *r_inputs2 = getMap (request_inputs, "ResponseDocument");
+  if (r_inputs2 == NULL)
+    r_inputs2 = getMap (request_inputs, "RawDataOutput");
+  map *tmpPath = getMapFromMaps (m, "lenv", "cwd");
+
+  map *tmpReq = getMap (request_inputs, "xrequest");
+  
+  if(r_inputs2 != NULL && tmpReq != NULL) {
+	const char key[] = "rfile=";
+	char* kvp = (char*) malloc((FILENAME_MAX + strlen(key))*sizeof(char));
+	char* filepath = kvp + strlen(key);
+	strncpy(kvp, key, strlen(key));
+	addToCache(m, tmpReq->value, tmpReq->value, "text/xml", strlen(tmpReq->value), 
+	           filepath, FILENAME_MAX);				   
+    if (filepath == NULL) {
+        errorException( m, _("Unable to cache HTTP POST Execute request."), "InternalError", NULL);  
+		return;
+    }	
+	sprintf(tmp,"\"metapath=%s&%s&cgiSid=%s",
+	        r_inputs1->value,kvp,sid->value);
+    sprintf(tmpq,"metapath=%s&%s",
+	        r_inputs1->value,kvp);
+	free(kvp);		
+  }
+  else if (r_inputs2 != NULL)
+    {
+      sprintf (tmp,
+               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s",
+               r_inputs1->value, req->value, id->value, dataInputsKVP,
+               r_inputs2->name, dataOutputsKVP, sid->value);
+      sprintf (tmpq,
+               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",
+               r_inputs1->value, req->value, id->value, dataInputsKVP,
+               r_inputs2->name, dataOutputsKVP);		   
+    }
+  else
+    {
+      sprintf (tmp,
+               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s",
+               r_inputs1->value, req->value, id->value, dataInputsKVP,
+               sid->value);
+      sprintf (tmpq,
+               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",
+               r_inputs1->value, req->value, id->value, dataInputsKVP,
+               sid->value);   
+    }
+
+  if (hasIn > 0)
+    {
+      freeMap (&r_inputs1);
+      free (r_inputs1);
+    }
+  char *tmp1 = zStrdup (tmp);
+  sprintf (tmp, "\"%s\" %s \"%s\"", PROGRAMNAME, tmp1, sid->value);  
+  free (dataInputsKVP);
+  free (dataOutputsKVP);
+#ifdef DEBUG
+  fprintf (stderr, "REQUEST IS : %s \n", tmp);
+#endif
+
+  map* usid = getMapFromMaps (m, "lenv", "usid");
+  if (usid != NULL && usid->value != NULL) {
+    SetEnvironmentVariable("USID", TEXT (usid->value));
+  }
+
+  SetEnvironmentVariable ("CGISID", TEXT (sid->value));
+  SetEnvironmentVariable ("QUERY_STRING", TEXT (tmpq));
+  // knut: Prevent REQUEST_METHOD=POST in background process call to cgic:main (process hangs when reading cgiIn):
+  SetEnvironmentVariable("REQUEST_METHOD", "GET");
+  
+  char clen[1000];
+  sprintf (clen, "%d", strlen (tmpq));
+  SetEnvironmentVariable ("CONTENT_LENGTH", TEXT (clen));
+
+  if (!CreateProcess (NULL,     // No module name (use command line)
+                      TEXT (tmp),       // Command line
+                      NULL,     // Process handle not inheritable
+                      NULL,     // Thread handle not inheritable
+                      FALSE,    // Set handle inheritance to FALSE
+                      CREATE_NO_WINDOW, // Apache won't wait until the end
+                      NULL,     // Use parent's environment block
+                      NULL,     // Use parent's starting directory 
+                      &si,      // Pointer to STARTUPINFO struct
+                      &pi)      // Pointer to PROCESS_INFORMATION struct
+    )
+    {
+#ifdef DEBUG
+      fprintf (stderr, "CreateProcess failed (%d).\n", GetLastError ());
+#endif
+      if (tmp != NULL) {
+        free(tmp);
+      }
+      if (tmpq != NULL) {
+        free(tmpq);
+      }		
+      return;
+    }
+  else
+    {
+#ifdef DEBUG
+      fprintf (stderr, "CreateProcess successful (%d).\n\n\n\n",
+               GetLastError ());
+#endif
+    }
+  CloseHandle (pi.hProcess);
+  CloseHandle (pi.hThread);
+  
+  if (tmp != NULL) {
+    free(tmp);
+  }
+  if (tmpq != NULL) {
+    free(tmpq);
+  }
+  
+#ifdef DEBUG
+  fprintf (stderr, "CreateProcess finished !\n");
+#endif
+}
+#endif
+
+/**
+ * Process the request.
+ *
+ * @param inputs the request parameters map 
+ * @return 0 on sucess, other value on failure
+ * @see conf_read,recursReaddirF
+ */
+int
+runRequest (map ** inputs)
+{
+
+#ifndef USE_GDB
+#ifndef WIN32
+  signal (SIGCHLD, SIG_IGN);
+#endif  
+  signal (SIGSEGV, sig_handler);
+  signal (SIGTERM, sig_handler);
+  signal (SIGINT, sig_handler);
+  signal (SIGILL, sig_handler);
+  signal (SIGFPE, sig_handler);
+  signal (SIGABRT, sig_handler);
+#endif
+
+  map *r_inputs = NULL;
+  map *request_inputs = *inputs;
+#ifdef IGNORE_METAPATH
+  addToMap(request_inputs, "metapath", "");
+#endif  
+  maps *m = NULL;
+  char *REQUEST = NULL;
+  /**
+   * Parsing service specfic configuration file
+   */
+  m = (maps *) malloc (MAPS_SIZE);
+  if (m == NULL)
+    {
+      return errorException (m, _("Unable to allocate memory."),
+                             "InternalError", NULL);
+    }
+  char ntmp[1024];
+#ifndef WIN32
+  getcwd (ntmp, 1024);
+#else
+  _getcwd (ntmp, 1024);
+#endif
+  r_inputs = getMapOrFill (&request_inputs, "metapath", "");
+
+  char conf_file[10240];
+  snprintf (conf_file, 10240, "%s/%s/main.cfg", ntmp, r_inputs->value);
+  if (conf_read (conf_file, m) == 2)
+    {
+      errorException (NULL, _("Unable to load the main.cfg file."),
+                      "InternalError", NULL);
+      free (m);
+      return 1;
+    }
+#ifdef DEBUG
+  fprintf (stderr, "***** BEGIN MAPS\n");
+  dumpMaps (m);
+  fprintf (stderr, "***** END MAPS\n");
+#endif
+
+  map *getPath = getMapFromMaps (m, "main", "gettextPath");
+  if (getPath != NULL)
+    {
+      bindtextdomain ("zoo-kernel", getPath->value);
+      bindtextdomain ("zoo-services", getPath->value);
+    }
+  else
+    {
+      bindtextdomain ("zoo-kernel", "/usr/share/locale/");
+      bindtextdomain ("zoo-services", "/usr/share/locale/");
+    }
+
+
+  /**
+   * Manage our own error log file (usefull to separate standard apache debug
+   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong 
+   * headers messages returned by the CGI due to wrong redirection of stderr)
+   */
+  FILE *fstde = NULL;
+  map *fstdem = getMapFromMaps (m, "main", "logPath");
+  if (fstdem != NULL)
+    fstde = freopen (fstdem->value, "a+", stderr);
+
+  r_inputs = getMap (request_inputs, "language");
+  if (r_inputs == NULL)
+    r_inputs = getMap (request_inputs, "AcceptLanguages");
+  if (r_inputs == NULL)
+    r_inputs = getMapFromMaps (m, "main", "language");
+  if (r_inputs != NULL)
+    {
+      if (isValidLang (m, r_inputs->value) < 0)
+        {
+          char tmp[1024];
+          sprintf (tmp,
+                   _
+                   ("The value %s is not supported for the <language> parameter"),
+                   r_inputs->value);
+          errorException (m, tmp, "InvalidParameterValue", "language");
+          freeMaps (&m);
+          free (m);
+          free (REQUEST);
+          return 1;
+
+        }
+      char *tmp = zStrdup (r_inputs->value);
+      setMapInMaps (m, "main", "language", tmp);
+#ifdef DEB
+      char tmp2[12];
+      sprintf (tmp2, "%s.utf-8", tmp);
+      translateChar (tmp2, '-', '_');
+      setlocale (LC_ALL, tmp2);
+#else
+      translateChar (tmp, '-', '_');
+      setlocale (LC_ALL, tmp);
+#endif
+#ifndef WIN32
+      setenv ("LC_ALL", tmp, 1);
+#else
+      char tmp1[12];
+      sprintf (tmp1, "LC_ALL=%s", tmp);
+      putenv (tmp1);
+#endif
+      free (tmp);
+    }
+  else
+    {
+      setlocale (LC_ALL, "en_US");
+#ifndef WIN32
+      setenv ("LC_ALL", "en_US", 1);
+#else
+      char tmp1[12];
+      sprintf (tmp1, "LC_ALL=en_US");
+      putenv (tmp1);
+#endif
+      setMapInMaps (m, "main", "language", "en-US");
+    }
+  setlocale (LC_NUMERIC, "en_US");
+  bind_textdomain_codeset ("zoo-kernel", "UTF-8");
+  textdomain ("zoo-kernel");
+  bind_textdomain_codeset ("zoo-services", "UTF-8");
+  textdomain ("zoo-services");
+
+  map *lsoap = getMap (request_inputs, "soap");
+  if (lsoap != NULL && strcasecmp (lsoap->value, "true") == 0)
+    setMapInMaps (m, "main", "isSoap", "true");
+  else
+    setMapInMaps (m, "main", "isSoap", "false");
+
+  if(strlen(cgiServerName)>0)
+    {
+      char tmpUrl[1024];
+	
+      if ( getenv("HTTPS") != NULL && strncmp(getenv("HTTPS"), "on", 2) == 0 ) { // Knut: check if non-empty instead of "on"?		
+	if ( strncmp(cgiServerPort, "443", 3) == 0 ) { 
+	  sprintf(tmpUrl, "https://%s%s", cgiServerName, cgiScriptName);
+	}
+	else {
+	  sprintf(tmpUrl, "https://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
+	}
+      }
+      else {
+	if ( strncmp(cgiServerPort, "80", 2) == 0 ) { 
+	  sprintf(tmpUrl, "http://%s%s", cgiServerName, cgiScriptName);
+	}
+	else {
+	  sprintf(tmpUrl, "http://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
+	}
+      }
+#ifdef DEBUG
+      fprintf(stderr,"*** %s ***\n",tmpUrl);
+#endif
+      setMapInMaps(m,"main","serverAddress",tmpUrl);
+    }
+
+  //Check for minimum inputs
+  map* version=getMap(request_inputs,"version");
+  if(version==NULL)
+    version=getMapFromMaps(m,"main","version");
+  setMapInMaps(m,"main","rversion",version->value);
+  int vid=getVersionId(version->value);
+  if(vid<0)
+    vid=0;
+  map* err=NULL;
+  const char **vvr=(const char**)requests[vid];
+  checkValidValue(request_inputs,&err,"request",vvr,1);
+  const char *vvs[]={
+    "WPS",
+    NULL
+  };
+  if(err!=NULL){
+    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
+    printExceptionReportResponse (m, err);
+    freeMap(&err);
+    free(err);
+    if (count (request_inputs) == 1)
+      {
+	freeMap (&request_inputs);
+	free (request_inputs);
+      }
+    freeMaps (&m);
+    free (m);
+    return 1;
+  }
+  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
+
+  const char *vvv[]={
+    "1.0.0",
+    "2.0.0",
+    NULL
+  };
+  r_inputs = getMap (request_inputs, "Request");
+  REQUEST = zStrdup (r_inputs->value);
+  int reqId=-1;
+  if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
+    checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
+    int j=0;
+    for(j=0;j<nbSupportedRequests;j++){
+      if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
+	if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
+	  checkValidValue(request_inputs,&err,"identifier",NULL,1);
+	  reqId=j+1;
+	  break;
+	}
+	else
+	  if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
+	     strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
+	    checkValidValue(request_inputs,&err,"jobid",NULL,1);
+	    reqId=j+1;
+	    break;
+	  }
+      }else
+	break;
+    }
+  }else{
+    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
+    map* version1=getMap(request_inputs,"AcceptVersions");
+    if(version1!=NULL){
+      if(strstr(version1->value,schemas[1][0])!=NULL)
+	addToMap(request_inputs,"version",schemas[1][0]);
+      else
+	addToMap(request_inputs,"version",version1->value);
+      version=getMap(request_inputs,"version");
+      setMapInMaps(m,"main","rversion",version->value);
+      vid=getVersionId(version->value);
+    }
+  }
+  if(err!=NULL){
+    printExceptionReportResponse (m, err);
+    freeMap(&err);
+    free(err);
+    if (count (request_inputs) == 1)
+      {
+	freeMap (&request_inputs);
+	free (request_inputs);
+      }
+    free(REQUEST);
+    freeMaps (&m);
+    free (m);
+    return 1;
+  }
+
+  r_inputs = getMap (request_inputs, "serviceprovider");
+  if (r_inputs == NULL)
+    {
+      addToMap (request_inputs, "serviceprovider", "");
+    }
+
+  maps *request_output_real_format = NULL;
+  map *tmpm = getMapFromMaps (m, "main", "serverAddress");
+  if (tmpm != NULL)
+    SERVICE_URL = zStrdup (tmpm->value);
+  else
+    SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
+
+
+
+  service *s1;
+  int scount = 0;
+#ifdef DEBUG
+  dumpMap (r_inputs);
+#endif
+  char conf_dir[1024];
+  int t;
+  char tmps1[1024];
+
+  r_inputs = NULL;
+  r_inputs = getMap (request_inputs, "metapath");
+  
+  if (r_inputs != NULL)
+    snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
+  else
+    snprintf (conf_dir, 1024, "%s", ntmp);
+
+  map* reg = getMapFromMaps (m, "main", "registry");
+  registry* zooRegistry=NULL;
+  if(reg!=NULL){
+    int saved_stdout = dup (fileno (stdout));
+    dup2 (fileno (stderr), fileno (stdout));
+    createRegistry (m,&zooRegistry,reg->value,saved_stdout);
+    dup2 (saved_stdout, fileno (stdout));
+  }
+
+  if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
+    {
+#ifdef DEBUG
+      dumpMap (r_inputs);
+#endif
+      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
+      xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
+      /**
+       * Here we need to close stdout to ensure that unsupported chars 
+       * has been found in the zcfg and then printed on stdout
+       */
+      int saved_stdout = dup (fileno (stdout));
+      dup2 (fileno (stderr), fileno (stdout));
+      if (int res =		  
+          recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
+                          printGetCapabilitiesForProcess) < 0)
+        {
+          freeMaps (&m);
+          free (m);
+	  if(zooRegistry!=NULL){
+	    freeRegistry(&zooRegistry);
+	    free(zooRegistry);
+	  }
+          free (REQUEST);
+          free (SERVICE_URL);
+          fflush (stdout);
+          return res;
+        }
+      fflush (stdout);
+      dup2 (saved_stdout, fileno (stdout));
+      printDocument (m, doc, getpid ());
+      freeMaps (&m);
+      free (m);
+      if(zooRegistry!=NULL){
+	freeRegistry(&zooRegistry);
+	free(zooRegistry);
+      }
+      free (REQUEST);
+      free (SERVICE_URL);
+      fflush (stdout);
+      return 0;
+    }
+  else
+    {
+      r_inputs = getMap (request_inputs, "JobId");
+      if(reqId>nbReqIdentifier){
+	if (strncasecmp (REQUEST, "GetStatus", strlen(REQUEST)) == 0 ||
+	    strncasecmp (REQUEST, "GetResult", strlen(REQUEST)) == 0){
+	  runGetStatus(m,r_inputs->value,REQUEST);
+	  freeMaps (&m);
+	  free (m);
+	  if(zooRegistry!=NULL){
+	    freeRegistry(&zooRegistry);
+	    free(zooRegistry);
+	  }
+	  free (REQUEST);
+	  free (SERVICE_URL);
+	  return 0;
+	}
+	else
+	  if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
+	    runDismiss(m,r_inputs->value);
+	    freeMaps (&m);
+	    free (m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    return 0;
+	    
+	  }
+	return 0;
+      }
+      if(reqId<=nbReqIdentifier){
+	r_inputs = getMap (request_inputs, "Identifier");
+
+	struct dirent *dp;
+	DIR *dirp = opendir (conf_dir);
+	if (dirp == NULL)
+	  {
+	    errorException (m, _("The specified path path does not exist."),
+			    "InvalidParameterValue", conf_dir);
+	    freeMaps (&m);
+	    free (m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    return 0;
+	  }
+	if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
+	  {
+	    /**
+	     * Loop over Identifier list
+	     */
+	    xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
+	    r_inputs = NULL;
+	    r_inputs = getMap (request_inputs, "version");
+	    xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
+					  root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
+
+	    r_inputs = getMap (request_inputs, "Identifier");
+
+	    char *orig = zStrdup (r_inputs->value);
+
+	    int saved_stdout = dup (fileno (stdout));
+	    dup2 (fileno (stderr), fileno (stdout));
+	    if (strcasecmp ("all", orig) == 0)
+	      {
+		if (int res =
+		    recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
+				    printDescribeProcessForProcess) < 0)
+		  return res;
+	      }
+	    else
+	      {
+		char *saveptr;
+		char *tmps = strtok_r (orig, ",", &saveptr);
+
+		char buff[256];
+		char buff1[1024];
+		while (tmps != NULL)
+		  {
+		    int hasVal = -1;
+		    char *corig = zStrdup (tmps);
+		    if (strstr (corig, ".") != NULL)
+		      {
+
+			parseIdentifier (m, conf_dir, corig, buff1);
+			map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
+			if (tmpMap != NULL)
+			  addToMap (request_inputs, "metapath", tmpMap->value);
+			map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
+
+			s1 = (service *) malloc (SERVICE_SIZE);
+			t = readServiceFile (m, buff1, &s1, tmpMapI->value);
+			if (t < 0)
+			  {
+			    map *tmp00 = getMapFromMaps (m, "lenv", "message");
+			    char tmp01[1024];
+			    if (tmp00 != NULL)
+			      sprintf (tmp01,
+				       _
+				       ("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),
+				       tmps, tmp00->value);
+			    else
+			      sprintf (tmp01,
+				       _
+				       ("Unable to parse the ZCFG file for the following ZOO-Service: %s."),
+				       tmps);
+			    dup2 (saved_stdout, fileno (stdout));
+			    errorException (m, tmp01, "InvalidParameterValue",
+					    "identifier");
+			    freeMaps (&m);
+			    free (m);
+			    if(zooRegistry!=NULL){
+			      freeRegistry(&zooRegistry);
+			      free(zooRegistry);
+			    }
+			    free (REQUEST);
+			    free (corig);
+			    free (orig);
+			    free (SERVICE_URL);
+			    free (s1);
+			    closedir (dirp);
+			    xmlFreeDoc (doc);
+			    xmlCleanupParser ();
+			    zooXmlCleanupNs ();
+			    return 1;
+			  }
+#ifdef DEBUG
+			dumpService (s1);
+#endif
+			inheritance(zooRegistry,&s1);
+			printDescribeProcessForProcess (m, n, s1);
+			freeService (&s1);
+			free (s1);
+			s1 = NULL;
+			scount++;
+			hasVal = 1;
+			setMapInMaps (m, "lenv", "level", "0");
+		      }
+		    else
+		      {
+			memset (buff, 0, 256);
+			snprintf (buff, 256, "%s.zcfg", corig);
+			memset (buff1, 0, 1024);
+#ifdef DEBUG
+			printf ("\n#######%s\n########\n", buff);
+#endif
+			while ((dp = readdir (dirp)) != NULL)
+			  {
+			    if (strcasecmp (dp->d_name, buff) == 0)
+			      {
+				memset (buff1, 0, 1024);
+				snprintf (buff1, 1024, "%s/%s", conf_dir,
+					  dp->d_name);
+				s1 = (service *) malloc (SERVICE_SIZE);
+				if (s1 == NULL)
+				  {
+				    dup2 (saved_stdout, fileno (stdout));
+				    return errorException (m,
+							   _
+							   ("Unable to allocate memory."),
+							   "InternalError",
+							   NULL);
+				  }
+#ifdef DEBUG
+				printf
+				  ("#################\n(%s) %s\n#################\n",
+				   r_inputs->value, buff1);
+#endif
+				char *tmp0 = zStrdup (dp->d_name);
+				tmp0[strlen (tmp0) - 5] = 0;
+				t = readServiceFile (m, buff1, &s1, tmp0);
+				free (tmp0);
+				if (t < 0)
+				  {
+				    map *tmp00 =
+				      getMapFromMaps (m, "lenv", "message");
+				    char tmp01[1024];
+				    if (tmp00 != NULL)
+				      sprintf (tmp01,
+					       _
+					       ("Unable to parse the ZCFG file: %s (%s)"),
+					       dp->d_name, tmp00->value);
+				    else
+				      sprintf (tmp01,
+					       _
+					       ("Unable to parse the ZCFG file: %s."),
+					       dp->d_name);
+				    dup2 (saved_stdout, fileno (stdout));
+				    errorException (m, tmp01, "InternalError",
+						    NULL);
+				    freeMaps (&m);
+				    free (m);
+				    if(zooRegistry!=NULL){
+				      freeRegistry(&zooRegistry);
+				      free(zooRegistry);
+				    }
+				    free (orig);
+				    free (REQUEST);
+				    closedir (dirp);
+				    xmlFreeDoc (doc);
+				    xmlCleanupParser ();
+				    zooXmlCleanupNs ();
+				    return 1;
+				  }
+#ifdef DEBUG
+				dumpService (s1);
+#endif
+				inheritance(zooRegistry,&s1);
+				printDescribeProcessForProcess (m, n, s1);
+				freeService (&s1);
+				free (s1);
+				s1 = NULL;
+				scount++;
+				hasVal = 1;
+			      }
+			  }
+		      }
+		    if (hasVal < 0)
+		      {
+			map *tmp00 = getMapFromMaps (m, "lenv", "message");
+			char tmp01[1024];
+			if (tmp00 != NULL)
+			  sprintf (tmp01,
+				   _("Unable to parse the ZCFG file: %s (%s)"),
+				   buff, tmp00->value);
+			else
+			  sprintf (tmp01,
+				   _("Unable to parse the ZCFG file: %s."),
+				   buff);
+			dup2 (saved_stdout, fileno (stdout));
+			errorException (m, tmp01, "InvalidParameterValue",
+					"Identifier");
+			freeMaps (&m);
+			free (m);
+			if(zooRegistry!=NULL){
+			  freeRegistry(&zooRegistry);
+			  free(zooRegistry);
+			}
+			free (orig);
+			free (REQUEST);
+			closedir (dirp);
+			xmlFreeDoc (doc);
+			xmlCleanupParser ();
+			zooXmlCleanupNs ();
+			return 1;
+		      }
+		    rewinddir (dirp);
+		    tmps = strtok_r (NULL, ",", &saveptr);
+		    if (corig != NULL)
+		      free (corig);
+		  }
+	      }
+	    closedir (dirp);
+	    fflush (stdout);
+	    dup2 (saved_stdout, fileno (stdout));
+	    free (orig);
+	    printDocument (m, doc, getpid ());
+	    freeMaps (&m);
+	    free (m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    fflush (stdout);
+	    return 0;
+	  }
+	else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
+	  {
+	    map* version=getMapFromMaps(m,"main","rversion");
+	    int vid=getVersionId(version->value);
+	    int len,j=0;
+	    for(j=0;j<nbSupportedRequests;j++){
+	      if(requests[vid][j]!=NULL)
+		len+=strlen(requests[vid][j])+2;
+	      else{
+		len+=4;
+		break;
+	      }
+	    }
+	    char *tmpStr=(char*)malloc(len*sizeof(char));
+	    int it=0;
+	    for(j=0;j<nbSupportedRequests;j++){
+	      if(requests[vid][j]!=NULL){
+		if(it==0){
+		  sprintf(tmpStr,"%s",requests[vid][j]);
+		  it++;
+		}else{
+		  char *tmpS=zStrdup(tmpStr);
+		  if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
+		    sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
+		  }else{
+		    sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
+		  
+		  }
+		  free(tmpS);
+		}
+	      }
+	      else{
+		len+=4;
+		break;
+	      }
+	    }
+	    char* message=(char*)malloc((61+len)*sizeof(char));
+	    sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
+	    errorException (m,_(message),"InvalidParameterValue", "request");
+#ifdef DEBUG
+	    fprintf (stderr, "No request found %s", REQUEST);
+#endif
+	    closedir (dirp);
+	    freeMaps (&m);
+	    free (m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    fflush (stdout);
+	    return 0;
+	  }
+	closedir (dirp);
+      }
+    }
+
+  map *postRequest = NULL;
+  postRequest = getMap (request_inputs, "xrequest");
+
+  if(vid==1 && postRequest==NULL){
+    errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request");  
+    freeMaps (&m);
+    free (m);
+    if(zooRegistry!=NULL){
+      freeRegistry(&zooRegistry);
+      free(zooRegistry);
+    }
+    free (REQUEST);
+    free (SERVICE_URL);
+    fflush (stdout);
+    return 0;
+  }
+  
+  s1 = NULL;
+  s1 = (service *) malloc (SERVICE_SIZE);
+  if (s1 == NULL)
+    {
+      freeMaps (&m);
+      free (m);
+      if(zooRegistry!=NULL){
+	freeRegistry(&zooRegistry);
+	free(zooRegistry);
+      }
+      free (REQUEST);
+      free (SERVICE_URL);
+      return errorException (m, _("Unable to allocate memory."),
+                             "InternalError", NULL);
+    }
+
+  r_inputs = getMap (request_inputs, "MetaPath");
+  if (r_inputs != NULL)
+    snprintf (tmps1, 1024, "%s/%s", ntmp, r_inputs->value);
+  else
+    snprintf (tmps1, 1024, "%s/", ntmp);
+  r_inputs = getMap (request_inputs, "Identifier");
+  char *ttmp = zStrdup (tmps1);
+  snprintf (tmps1, 1024, "%s/%s.zcfg", ttmp, r_inputs->value);
+  free (ttmp);
+#ifdef DEBUG
+  fprintf (stderr, "Trying to load %s\n", tmps1);
+#endif
+  if (strstr (r_inputs->value, ".") != NULL)
+    {
+      char *identifier = zStrdup (r_inputs->value);
+      parseIdentifier (m, conf_dir, identifier, tmps1);
+      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
+      if (tmpMap != NULL)
+        addToMap (request_inputs, "metapath", tmpMap->value);
+      free (identifier);
+    }
+  else
+    {
+      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
+      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
+    }
+
+  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
+  int saved_stdout = dup (fileno (stdout));
+  dup2 (fileno (stderr), fileno (stdout));
+  t = readServiceFile (m, tmps1, &s1, r_inputs->value);
+  inheritance(zooRegistry,&s1);
+  if(zooRegistry!=NULL){
+    freeRegistry(&zooRegistry);
+    free(zooRegistry);
+  }
+  fflush (stdout);
+  dup2 (saved_stdout, fileno (stdout));
+  if (t < 0)
+    {
+      char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
+      sprintf (tmpMsg,
+               _
+               ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
+               r_inputs->value);
+      errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
+      free (tmpMsg);
+      free (s1);
+      freeMaps (&m);
+      free (m);
+      free (REQUEST);
+      free (SERVICE_URL);
+      return 0;
+    }
+  close (saved_stdout);
+
+#ifdef DEBUG
+  dumpService (s1);
+#endif
+  int j;
+
+
+  /**
+   * Create the input and output maps data structure
+   */
+  int i = 0;
+  HINTERNET hInternet;
+  HINTERNET res;
+  hInternet = InternetOpen (
+#ifndef WIN32
+			    (LPCTSTR)
+#endif
+			    "ZooWPSClient\0",
+			    INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+
+#ifndef WIN32
+  if (!CHECK_INET_HANDLE (hInternet))
+    fprintf (stderr, "WARNING : hInternet handle failed to initialize");
+#endif
+  maps *request_input_real_format = NULL;
+  maps *tmpmaps = request_input_real_format;
+
+
+  if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
+    freeMaps (&m);
+    free (m);
+    free (REQUEST);
+    free (SERVICE_URL);
+    InternetCloseHandle (&hInternet);
+    freeService (&s1);
+    free (s1);
+    return 0;
+  }
+
+
+  // Define each env variable in runing environment
+  maps *curs = getMaps (m, "env");
+  if (curs != NULL)
+    {
+      map *mapcs = curs->content;
+      while (mapcs != NULLMAP)
+        {
+#ifndef WIN32
+          setenv (mapcs->name, mapcs->value, 1);
+#else
+#ifdef DEBUG
+          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
+                   mapcs->value);
+#endif
+          if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
+            {
+#ifdef DEBUG
+              fprintf (stderr, "[ZOO: Env var finish with \r]\n");
+#endif
+              mapcs->value[strlen (mapcs->value) - 1] = 0;
+            }
+#ifdef DEBUG
+          if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
+            {
+              fflush (stderr);
+              fprintf (stderr, "setting variable... %s\n", "OK");
+            }
+          else
+            {
+              fflush (stderr);
+              fprintf (stderr, "setting variable... %s\n", "OK");
+            }
+#else
+
+
+          SetEnvironmentVariable (mapcs->name, mapcs->value);
+#endif
+          char *toto =
+            (char *)
+            malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
+                     2) * sizeof (char));
+          sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
+          putenv (toto);
+#ifdef DEBUG
+          fflush (stderr);
+#endif
+#endif
+#ifdef DEBUG
+          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
+                   mapcs->value);
+          fflush (stderr);
+#endif
+          mapcs = mapcs->next;
+        }
+    }
+
+#ifdef DEBUG
+  dumpMap (request_inputs);
+#endif
+
+  map *status = getMap (request_inputs, "status");
+  if(vid==0){
+    // Need to check if we need to fork to load a status enabled 
+    r_inputs = NULL;
+    map *store = getMap (request_inputs, "storeExecuteResponse");
+    /**
+     * 05-007r7 WPS 1.0.0 page 57 :
+     * 'If status="true" and storeExecuteResponse is "false" then the service 
+     * shall raise an exception.'
+     */
+    if (status != NULL && strcmp (status->value, "true") == 0 &&
+	store != NULL && strcmp (store->value, "false") == 0)
+      {
+	errorException (m,
+			_
+			("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
+			"InvalidParameterValue", "storeExecuteResponse");
+	freeService (&s1);
+	free (s1);
+	freeMaps (&m);
+	free (m);
+	
+	freeMaps (&request_input_real_format);
+	free (request_input_real_format);
+	
+	freeMaps (&request_output_real_format);
+	free (request_output_real_format);
+
+	free (REQUEST);
+	free (SERVICE_URL);
+	return 1;
+      }
+    r_inputs = getMap (request_inputs, "storeExecuteResponse");
+  }else{
+    // Define status depending on the WPS 2.0.0 mode attribute
+    status = getMap (request_inputs, "mode");
+    map* mode=getMap(s1->content,"mode");
+    if(strcasecmp(status->value,"async")==0){
+      if(mode!=NULL && strcasecmp(mode->value,"async")==0)
+	addToMap(request_inputs,"status","true");
+      else{
+	if(mode!=NULL){
+	  // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
+	  errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value);  
+	  fflush (stdout);
+	  freeMaps (&m);
+	  free (m);
+	  if(zooRegistry!=NULL){
+	    freeRegistry(&zooRegistry);
+	    free(zooRegistry);
+	  }
+	  freeMaps (&request_input_real_format);
+	  free (request_input_real_format);
+	  freeMaps (&request_output_real_format);
+	  free (request_output_real_format);
+	  free (REQUEST);
+	  free (SERVICE_URL);
+	  return 0;
+	}else
+	  addToMap(request_inputs,"status","true");
+      }
+    }
+    else{
+      if(strcasecmp(status->value,"auto")==0){
+	if(mode!=NULL){
+	  if(strcasecmp(mode->value,"async")==0)
+	    addToMap(request_inputs,"status","false");
+	  else
+	    addToMap(request_inputs,"status","true");
+	}
+	else
+	  addToMap(request_inputs,"status","false");
+      }else
+	addToMap(request_inputs,"status","false");
+    }
+    status = getMap (request_inputs, "status");
+  }
+
+  int eres = SERVICE_STARTED;
+  int cpid = getpid ();
+
+  /**
+   * Initialize the specific [lenv] section which contains runtime variables:
+   * 
+   *  - usid : it is an unique identification number 
+   *  - sid : it is the process idenfitication number (OS)
+   *  - uusid : it is an universally unique identification number 
+   *  - status : value between 0 and 100 to express the  completude of 
+   * the operations of the running service 
+   *  - message : is a string where you can store error messages, in case 
+   * service is failing, or o provide details on the ongoing operation.
+   *  - cwd : is the current working directory
+   *  - soap : is a boolean value, true if the request was contained in a SOAP 
+   * Envelop 
+   *  - sessid : string storing the session identifier (only when cookie is 
+   * used)
+   *  - cgiSid : only defined on Window platforms (for being able to identify 
+   * the created process)
+   *
+   */
+  maps *_tmpMaps = (maps *) malloc (MAPS_SIZE);
+  _tmpMaps->name = zStrdup ("lenv");
+  char tmpBuff[100];
+  struct ztimeval tp;
+  if (zGettimeofday (&tp, NULL) == 0)
+    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
+  else
+    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
+  _tmpMaps->content = createMap ("osid", tmpBuff);
+  _tmpMaps->next = NULL;
+  sprintf (tmpBuff, "%i", cpid);
+  addToMap (_tmpMaps->content, "sid", tmpBuff);
+  char* tmpUuid=get_uuid();
+  addToMap (_tmpMaps->content, "uusid", tmpUuid);
+  addToMap (_tmpMaps->content, "usid", tmpUuid);
+  free(tmpUuid);
+  addToMap (_tmpMaps->content, "status", "0");
+  addToMap (_tmpMaps->content, "cwd", ntmp);
+  addToMap (_tmpMaps->content, "message", _("No message provided"));
+  map *ltmp = getMap (request_inputs, "soap");
+  if (ltmp != NULL)
+    addToMap (_tmpMaps->content, "soap", ltmp->value);
+  else
+    addToMap (_tmpMaps->content, "soap", "false");
+
+  // Parse the session file and add it to the main maps 
+  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
+    {
+      int hasValidCookie = -1;
+      char *tcook = zStrdup (cgiCookie);
+      char *tmp = NULL;
+      map *testing = getMapFromMaps (m, "main", "cookiePrefix");
+      if (testing == NULL)
+        {
+          tmp = zStrdup ("ID=");
+        }
+      else
+        {
+          tmp =
+            (char *) malloc ((strlen (testing->value) + 2) * sizeof (char));
+          sprintf (tmp, "%s=", testing->value);
+        }
+      if (strstr (cgiCookie, ";") != NULL)
+        {
+          char *token, *saveptr;
+          token = strtok_r (cgiCookie, ";", &saveptr);
+          while (token != NULL)
+            {
+              if (strcasestr (token, tmp) != NULL)
+                {
+                  if (tcook != NULL)
+                    free (tcook);
+                  tcook = zStrdup (token);
+                  hasValidCookie = 1;
+                }
+              token = strtok_r (NULL, ";", &saveptr);
+            }
+        }
+      else
+        {
+          if (strstr (cgiCookie, "=") != NULL
+              && strcasestr (cgiCookie, tmp) != NULL)
+            {
+              tcook = zStrdup (cgiCookie);
+              hasValidCookie = 1;
+            }
+          if (tmp != NULL)
+            {
+              free (tmp);
+            }
+        }
+      if (hasValidCookie > 0)
+        {
+          addToMap (_tmpMaps->content, "sessid", strstr (tcook, "=") + 1);
+          char session_file_path[1024];
+          map *tmpPath = getMapFromMaps (m, "main", "sessPath");
+          if (tmpPath == NULL)
+            tmpPath = getMapFromMaps (m, "main", "tmpPath");
+          char *tmp1 = strtok (tcook, ";");
+          if (tmp1 != NULL)
+            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
+                     strstr (tmp1, "=") + 1);
+          else
+            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
+                     strstr (cgiCookie, "=") + 1);
+          free (tcook);
+          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
+          struct stat file_status;
+          int istat = stat (session_file_path, &file_status);
+          if (istat == 0 && file_status.st_size > 0)
+            {
+              conf_read (session_file_path, tmpSess);
+              addMapsToMaps (&m, tmpSess);
+              freeMaps (&tmpSess);
+              free (tmpSess);
+            }
+        }
+    }
+  addMapsToMaps (&m, _tmpMaps);
+  freeMaps (&_tmpMaps);
+  free (_tmpMaps);
+  maps* bmap=NULL;
+#ifdef DEBUG
+  dumpMap (request_inputs);
+#endif
+#ifdef WIN32
+  char *cgiSidL = NULL;
+  if (getenv ("CGISID") != NULL)
+    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
+
+  char* usidp;
+  if ( (usidp = getenv("USID")) != NULL ) {
+    setMapInMaps (m, "lenv", "usid", usidp);
+  }
+
+  map *test1 = getMap (request_inputs, "cgiSid");
+  if (test1 != NULL)
+    {
+      cgiSid = test1->value;
+      addToMap (request_inputs, "storeExecuteResponse", "true");
+      addToMap (request_inputs, "status", "true");
+      setMapInMaps (m, "lenv", "sid", test1->value);
+      status = getMap (request_inputs, "status");
+    }
+#endif
+  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
+  FILE *f0, *f1;
+  if (status != NULL)
+    if (strcasecmp (status->value, "false") == 0)
+      status = NULLMAP;
+  if (status == NULLMAP)
+    {
+      if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
+	freeService (&s1);
+	free (s1);
+	freeMaps (&m);
+	free (m);
+	free (REQUEST);
+	free (SERVICE_URL);
+	freeMaps (&request_input_real_format);
+	free (request_input_real_format);
+	freeMaps (&request_output_real_format);
+	free (request_output_real_format);
+	freeMaps (&tmpmaps);
+	free (tmpmaps);
+	return -1;
+      }
+
+      loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
+                         &request_output_real_format, &eres);
+    }
+  else
+    {
+      int pid;
+#ifdef DEBUG
+      fprintf (stderr, "\nPID : %d\n", cpid);
+#endif
+
+#ifndef WIN32
+      pid = fork ();
+#else
+      if (cgiSid == NULL)
+        {
+          createProcess (m, request_inputs, s1, NULL, cpid,
+                         request_input_real_format,
+                         request_output_real_format);
+          pid = cpid;
+        }
+      else
+        {
+          pid = 0;
+          cpid = atoi (cgiSid);
+        }
+#endif
+      if (pid > 0)
+        {
+	  /**
+	   * dady :
+	   * set status to SERVICE_ACCEPTED
+	   */
+#ifdef DEBUG
+          fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
+                   getpid ());
+#endif
+          eres = SERVICE_ACCEPTED;
+        }
+      else if (pid == 0)
+        {
+	  /**
+	   * son : have to close the stdout, stdin and stderr to let the parent
+	   * process answer to http client.
+	   */
+	  map* usid = getMapFromMaps (m, "lenv", "uusid");
+          map* tmpm = getMapFromMaps (m, "lenv", "osid");
+          int cpid = atoi (tmpm->value);
+          r_inputs = getMapFromMaps (m, "main", "tmpPath");
+	  map* r_inputs1 = createMap("ServiceName", s1->name);
+
+	  // Create the filename for the result file (.res)
+          fbkpres =
+            (char *)
+            malloc ((strlen (r_inputs->value) +
+                     strlen (usid->value) + 7) * sizeof (char));
+          sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
+	  bmap = (maps *) malloc (MAPS_SIZE);
+	  bmap->name=zStrdup("status");
+	  bmap->content=createMap("usid",usid->value);
+	  bmap->next=NULL;
+	  addToMap(bmap->content,"sid",tmpm->value);
+	  addIntToMap(bmap->content,"pid",getpid());
+	  
+	  // Create PID file referencing the OS process identifier
+          fbkpid =
+            (char *)
+            malloc ((strlen (r_inputs->value) +
+                     strlen (usid->value) + 7) * sizeof (char));
+          sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
+
+          f0 = freopen (fbkpid, "w+", stdout);
+	  fprintf(stdout,"%d",getpid());
+	  fflush(stdout);
+
+	  // Create SID file referencing the semaphore name
+          fbkp =
+            (char *)
+            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+                     strlen (usid->value) + 7) * sizeof (char));
+          sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
+
+          FILE* f2 = fopen (fbkp, "w+");
+	  fprintf(f2,"%s",tmpm->value);
+	  fflush(f2);
+	  fclose(f2);
+	  free(fbkp);
+
+          fbkp =
+            (char *)
+            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+                     strlen (usid->value) + 7) * sizeof (char));
+          sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
+                   usid->value);
+          flog =
+            (char *)
+            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+                     strlen (usid->value) + 13) * sizeof (char));
+          sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
+                   r_inputs1->value, usid->value);
+#ifdef DEBUG
+          fprintf (stderr, "RUN IN BACKGROUND MODE \n");
+          fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
+                   getpid ());
+          fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
+#endif
+          freopen (flog, "w+", stderr);
+          fflush (stderr);
+	  f0 = freopen (fbkp, "w+", stdout);
+	  rewind (stdout);
+#ifndef WIN32
+	  fclose (stdin);
+#endif
+
+#ifdef RELY_ON_DB
+	  init_sql(m);
+	  recordServiceStatus(m);
+#endif
+	  if(vid==0){
+	    /**
+	     * set status to SERVICE_STARTED and flush stdout to ensure full 
+	     * content was outputed (the file used to store the ResponseDocument).
+	     * The rewind stdout to restart writing from the bgining of the file,
+	     * this way the data will be updated at the end of the process run.
+	     */
+	    printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
+				  SERVICE_STARTED, request_input_real_format,
+				  request_output_real_format);
+	    fflush (stdout);
+#ifdef RELY_ON_DB
+	    recordResponse(m,fbkp);
+#endif
+	  }
+
+          fflush (stderr);
+
+          fbkp1 =
+            (char *)
+            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+                     strlen (usid->value) + 13) * sizeof (char));
+          sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
+                   r_inputs1->value, usid->value);
+
+          f1 = freopen (fbkp1, "w+", stdout);
+
+	  if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
+	    freeService (&s1);
+	    free (s1);
+	    freeMaps (&m);
+	    free (m);
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    freeMaps (&request_input_real_format);
+	    free (request_input_real_format);
+	    freeMaps (&request_output_real_format);
+	    free (request_output_real_format);
+	    freeMaps (&tmpmaps);
+	    free (tmpmaps);
+	    fflush (stdout);
+	    fflush (stderr);
+	    unhandleStatus (m);
+	    return -1;
+	  }
+          loadServiceAndRun (&m, s1, request_inputs,
+                             &request_input_real_format,
+                             &request_output_real_format, &eres);
+
+        }
+      else
+        {
+	  /**
+	   * error server don't accept the process need to output a valid 
+	   * error response here !!!
+	   */
+          eres = -1;
+          errorException (m, _("Unable to run the child process properly"),
+                          "InternalError", NULL);
+        }
+    }
+
+#ifdef DEBUG
+  dumpMaps (request_output_real_format);
+#endif
+  if (eres != -1)
+    outputResponse (s1, request_input_real_format,
+                    request_output_real_format, request_inputs,
+                    cpid, m, eres);
+  fflush (stdout);
+  
+  /**
+   * Ensure that if error occurs when freeing memory, no signal will return
+   * an ExceptionReport document as the result was already returned to the 
+   * client.
+   */
+#ifndef USE_GDB
+  signal (SIGSEGV, donothing);
+  signal (SIGTERM, donothing);
+  signal (SIGINT, donothing);
+  signal (SIGILL, donothing);
+  signal (SIGFPE, donothing);
+  signal (SIGABRT, donothing);
+#endif
+  if (((int) getpid ()) != cpid || cgiSid != NULL)
+    {
+      fclose (stdout);
+      //fclose (stderr);
+      /**
+       * Dump back the final file fbkp1 to fbkp
+       */
+      fclose (f0);
+      fclose (f1);
+
+      FILE *f2 = fopen (fbkp1, "rb");
+#ifndef RELY_ON_DB
+      semid lid = getShmLockId (m, 1);
+      if (lid < 0)
+        return -1;
+      lockShm (lid);
+#endif
+      fclose(f0);
+      FILE *f3 = fopen (fbkp, "wb+");
+      free (fbkp);
+      fseek (f2, 0, SEEK_END);
+      long flen = ftell (f2);
+      fseek (f2, 0, SEEK_SET);
+      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
+      fread (tmps1, flen, 1, f2);
+      fwrite (tmps1, 1, flen, f3);
+      fclose (f2);
+      fclose (f3);
+      unlink (fbkpid);
+      switch(eres){
+      default:
+      case SERVICE_FAILED:
+	setMapInMaps(bmap,"status","status",wpsStatus[1]);
+	setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
+	break;
+      case SERVICE_SUCCEEDED:
+	setMapInMaps(bmap,"status","status",wpsStatus[0]);
+	setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
+	break;
+      }
+#ifndef RELY_ON_DB
+      dumpMapsToFile(bmap,fbkpres);
+      removeShmLock (m, 1);
+#else
+      recordResponse(m,fbkp1);
+#endif
+      freeMaps(&bmap);
+      free(bmap);
+      unlink (fbkp1);
+      unlink (flog);
+      unhandleStatus (m);
+      free(fbkpid);
+      free(fbkpres);
+      free (flog);
+      free (fbkp1);
+      free (tmps1);
+    }
+
+  freeService (&s1);
+  free (s1);
+  freeMaps (&m);
+  free (m);
+
+  freeMaps (&request_input_real_format);
+  free (request_input_real_format);
+
+  freeMaps (&request_output_real_format);
+  free (request_output_real_format);
+
+  free (REQUEST);
+  free (SERVICE_URL);
+#ifdef DEBUG
+  fprintf (stderr, "Processed response \n");
+  fflush (stdout);
+  fflush (stderr);
+#endif
+
+  if (((int) getpid ()) != cpid || cgiSid != NULL)
+    {
+      exit (0);
+    }
+
+  return 0;
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/Makefile	(revision 672)
@@ -0,0 +1,8 @@
+CFLAGS=-I../../zoo-kernel/ -I./ `xml2-config --cflags` `python-config --cflags`  `gdal-config --cflags`   -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/test_service.zo: test_service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/test_service.zo ./test_service.c -lzoo_service
+
+clean:
+	rm -f cgi-env/test_service.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/cgi-env/Multiply.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/cgi-env/Multiply.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/cgi-env/Multiply.zcfg	(revision 672)
@@ -0,0 +1,43 @@
+[Multiply]
+ Title = Multiply two values
+ Abstract = Multiply two values and stor the result in Result.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = test_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [A]
+   Title = first value
+   Abstract = The value used to multiply by B.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = float
+    <Default>
+    </Default>
+   </LiteralData>
+  [B]
+   Title = second value
+   Abstract = The value used to multiply by A.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = float
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = A x B 
+   Abstract = The value of A x B.
+   <LiteralOutput>
+    DataType = float
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/makefile.vc	(revision 672)
@@ -0,0 +1,12 @@
+TROOT= ../
+!INCLUDE ../../zoo-kernel/nmake.opt
+
+#CFLAGS=-I$(GEODIR)/include -I$(TOOLS)/include -I../../zoo-kernel/ -I./ -DLINUX_FREE_ISSUE -DDEBUG -DWIN32
+#CPP=cl /TP 
+
+cgi-env/test_service.zo: test_service.c
+	$(CPP) -DWIN32 -DZOO_SERVICE -DNEED_STRCASESTR $(CFLAGS) /c test_service.c
+	link /dll /out:cgi-env/test_service.zo ../../zoo-kernel/service_internal.obj ../../zoo-kernel/ulinet.obj ../../zoo-kernel/service_internal_ms.obj ../../zoo-kernel/service_internal_js.obj ./test_service.obj $(LDFLAGS)
+
+clean:
+	erase cgi-env\demo_service.*
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/test_service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/test_service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/arithmetics/test_service.c	(revision 672)
@@ -0,0 +1,42 @@
+#include "service.h"
+
+extern "C" {
+
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+  int Multiply(maps*& conf,maps*& inputs,maps*& outputs){
+  	fprintf(stderr,"\nService internal print\n");
+  	maps* cursor=inputs;
+	int A,B,res;
+	A=0;B=0;
+	if(cursor!=NULL){
+		fprintf(stderr,"\nService internal print\n");
+		dumpMaps(cursor);
+		maps* tmp=getMaps(inputs,"A");
+		if(tmp==NULL)
+			return SERVICE_FAILED;
+		fprintf(stderr,"\nService internal print\n");
+		dumpMap(tmp->content);
+		map* tmpv=getMap(tmp->content,"value");
+		fprintf(stderr,"\nService internal print\n");
+		A=atoi(tmpv->value);
+		fprintf(stderr,"\nService internal print (A value: %i)\n",A);
+		cursor=cursor->next;
+	}
+	if(cursor!=NULL){
+		maps* tmp=getMaps(cursor,"B");
+		map* tmpv=getMap(tmp->content,"value");
+		if(tmpv==NULL)
+			return SERVICE_FAILED;
+		B=atoi(tmpv->value);
+		fprintf(stderr,"\nService internal print (B value: %i)\n",B);
+	}
+	res=A*B;
+	char tmp[256];
+	sprintf(tmp,"%i",res);
+	setMapInMaps(outputs,"Result","value",tmp);
+	return SERVICE_SUCCEEDED;
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/Makefile	(revision 672)
@@ -0,0 +1,19 @@
+ZRPATH=../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} ${CGAL_CFLAGS} -frounding-math -fPIC -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/cgal_service.zo: delaunay.c voronoi.c cgal_service.o
+	g++ ${CFLAGS} -c ./delaunay.c
+	g++ ${CFLAGS} -c ./voronoi.c
+	g++ ${CFLAGS} -shared -o cgi-env/cgal_service.zo ./delaunay.o ./voronoi.o ./cgal_service.o ${GDAL_LIBS} ${MACOS_LD_FLAGS} ${CGAL_LDFLAGS} -lCGAL -lgmp -lgdal -lzoo_service
+
+cgal_service.o: cgal_service.c cgal_service.h
+	g++ ${CFLAGS} -c ./cgal_service.c
+
+install:
+	install -d ${CGI_DIR}/cgal
+	install cgi-env/* ${CGI_DIR}/cgal/
+
+clean:
+	rm -f cgi-env/*.zo *.o
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.c	(revision 672)
@@ -0,0 +1,81 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "cgal_service.h"
+
+int parseInput(maps* conf,maps* inputs, std::vector<Point>* points,char* filename){
+  map* tmpm=NULL;
+  tmpm=getMapFromMaps(inputs,"InputPoints","value");
+  VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmpm->value,strlen(tmpm->value),FALSE);
+  VSIFCloseL(ifile);
+  OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+  if( ipoDS == NULL )
+    {
+      OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+      
+      fprintf( stderr, "FAILURE:\n"
+	       "Unable to open datasource `%s' with the following drivers.\n",
+	       filename );
+      
+      for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+        {
+	  fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+        }
+      char tmp[1024];
+      sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return SERVICE_FAILED;
+    }
+  for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+       iLayer++ )
+    {
+      OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+      
+      if( poLayer == NULL )
+	{
+	  fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		   iLayer );
+#ifdef ZOO_SERVICE
+	  char tmp[1024];
+	  sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return SERVICE_FAILED;
+#else
+	  exit( 1 );
+#endif
+	}
+      
+      OGRFeature  *poFeature;
+      while(TRUE){
+	poFeature = poLayer->GetNextFeature();
+	if( poFeature == NULL )
+	  break;
+	if(poFeature->GetGeometryRef() != NULL){
+	  points->push_back(Point(OGR_G_GetX(poFeature->GetGeometryRef(),0),OGR_G_GetY(poFeature->GetGeometryRef(),0)));
+	}
+      }
+    }
+  return SERVICE_SUCCEEDED;
+}
+
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.h
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.h	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgal_service.h	(revision 672)
@@ -0,0 +1,45 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_CGAL_SERVICE_H
+#define ZOO_CGAL_SERVICE_H
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+#include <vector>
+
+#include "cpl_minixml.h"
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+#include "service.h"
+#include "service_internal.h"
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel            Kernel;
+typedef Kernel::Point_2                                                Point;
+
+int parseInput(maps*,maps*, std::vector<Point>*,char*);
+
+#endif
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Delaunay.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Delaunay.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Delaunay.zcfg	(revision 672)
@@ -0,0 +1,55 @@
+[Delaunay]
+ Title = Delaunay Triangulation. 
+ Abstract = Computes the edges of a Delaunay triangulation for a set of data points.
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = cgal_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPoints]
+   Title = Data points
+   Abstract = The set of data points.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Delaunay Triangulation
+   Abstract = JSON String / GML Entity of the Delaunay Triangulation.
+   <ComplexOutput>
+    <Default>
+     mimeType = application/json
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+    <Supported>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     asReference = true	
+    </Supported>
+   </ComplexOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Voronoi.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Voronoi.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/cgi-env/Voronoi.zcfg	(revision 672)
@@ -0,0 +1,59 @@
+[Voronoi]
+ Title = Voronoi Diagram. 
+ Abstract = Computes the edges of Voronoi diagram for a set of data points.
+ Profile = urn:ogc:wps:1.0.0:voronoi
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = cgal_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPoints]
+   Title = Data points
+   Abstract = The set of data points.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Voronoi Diagram.
+   Abstract = JSON String / GML Entity of the Voronoi Diagram.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexOutput>
+    <Default>
+     mimeType = application/json
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+    <Supported>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     asReference = true	
+    </Supported>
+   </ComplexOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/delaunay.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/delaunay.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/delaunay.c	(revision 672)
@@ -0,0 +1,187 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "cgal_service.h"
+typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
+typedef CGAL::Triangulation_data_structure_2<Vb>                       Tds;
+typedef CGAL::Delaunay_triangulation_2<Kernel, Tds>                    DelaunayT;
+
+extern "C" {
+
+  int Delaunay(maps*& conf,maps*& inputs,maps*& outputs){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\nStarting\n");
+#endif
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    int bufferDistance;
+    map* tmpm=NULL;
+    OGRRegisterAll();
+
+    std::vector<Point> points;
+    if(int res=parseInput(conf,inputs,&points,"/vsimem/tmp")!=SERVICE_SUCCEEDED)
+      return res;
+
+    DelaunayT T;
+    T.insert(points.begin(), points.end());
+
+    /* -------------------------------------------------------------------- */
+    /*      Try opening the output datasource as an existing, writable      */
+    /* -------------------------------------------------------------------- */
+    OGRDataSource       *poODS;
+    
+    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+    OGRSFDriver          *poDriver = NULL;
+    int                  iDriver;
+
+    map *tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    if(tmpMap!=NULL){
+      if(strcmp(tmpMap->value,"text/xml")==0){
+	oDriver="GML";
+      }
+    }
+    
+    for( iDriver = 0;
+	 iDriver < poR->GetDriverCount() && poDriver == NULL;
+	 iDriver++ )
+      {
+#ifdef DEBUG
+	fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
+#endif
+	if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver) )
+	  {
+	    poDriver = poR->GetDriver(iDriver);
+	  }
+      }
+
+    if( poDriver == NULL )
+      {
+	char emessage[8192];
+	sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+        
+	for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	  }
+
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+
+      }
+
+    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+      char emessage[1024];
+      sprintf( emessage,  "%s driver does not support data source creation.\n",
+	       "json" );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the output data source.                                  */
+    /* -------------------------------------------------------------------- */
+    char *pszDestDataSource=(char*)malloc(100);
+    char **papszDSCO=NULL;
+    sprintf(pszDestDataSource,"/vsimem/result_%d",getpid());
+    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+    if( poODS == NULL ){
+      char emessage[1024];      
+      sprintf( emessage,  "%s driver failed to create %s\n", 
+	       "json", pszDestDataSource );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the layer.                                               */
+    /* -------------------------------------------------------------------- */
+    if( !poODS->TestCapability( ODsCCreateLayer ) )
+      {
+	char emessage[1024];
+	sprintf( emessage, 
+		 "Layer %s not found, and CreateLayer not supported by driver.", 
+		 "Result" );
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+      }
+    
+    CPLErrorReset();
+    
+    OGRLayer *poDstLayer = poODS->CreateLayer( "Result", NULL,wkbPolygon,NULL);
+    if( poDstLayer == NULL ){
+      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+      return SERVICE_FAILED;
+    }
+
+
+    for(DelaunayT::Finite_faces_iterator fit = T.finite_faces_begin();
+	fit != T.finite_faces_end(); ++fit) {
+      DelaunayT::Face_handle face = fit;
+      OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+      OGRGeometryH hCollection = OGR_G_CreateGeometry( wkbGeometryCollection );
+      OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLinearRing);
+      OGRGeometryH currPoly=OGR_G_CreateGeometry(wkbPolygon);
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[0].x(),T.triangle(face)[0].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[1].x(),T.triangle(face)[1].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[2].x(),T.triangle(face)[2].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[0].x(),T.triangle(face)[0].y());
+      OGR_G_AddGeometryDirectly( currPoly, currLine ); 
+      OGR_G_AddGeometryDirectly( hCollection, currPoly ); 
+      OGR_F_SetGeometry( hFeature, hCollection ); 
+      OGR_G_DestroyGeometry(hCollection);
+      if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	return SERVICE_FAILED;
+      }
+      OGR_F_Destroy( hFeature );
+    }
+    OGR_DS_Destroy( poODS );
+
+#ifdef DEBUG
+    std::cerr << "The Voronoi diagram has " << ns << " finite edges "
+	      << " and " << nr << " rays" << std::endl;
+#endif
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+
+    if(strcmp(oDriver,"GML")==0)
+      setMapInMaps(outputs,"Result","mimeType","text/xml");
+    else
+      setMapInMaps(outputs,"Result","mimeType","application/json");
+
+    setMapInMaps(outputs,"Result","encoding","UTF-8");
+    OGRCleanupAll();
+    
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/voronoi.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/voronoi.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/cgal/voronoi.c	(revision 672)
@@ -0,0 +1,228 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_conformer_2.h>
+#include <CGAL/Triangulation_face_base_2.h>
+
+#include <fstream>
+
+#include "cpl_minixml.h"
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+#include "service.h"
+#include "cgal_service.h"
+
+typedef CGAL::Delaunay_triangulation_2<Kernel>  Triangulation;
+typedef Triangulation::Edge_iterator  Edge_iterator;
+typedef Triangulation::Vertex_circulator Vertex_circulator;
+
+extern "C" {
+
+  int Voronoi(maps*& conf,maps*& inputs,maps*& outputs){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\nStarting\n");
+#endif
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    int bufferDistance;
+    map* tmpm=NULL;
+    tmpm=getMapFromMaps(inputs,"InputPoints","value");
+
+    OGRRegisterAll();
+
+    std::vector<Point> points;
+    if(int res=parseInput(conf,inputs,&points,"/vsimem/tmp")!=SERVICE_SUCCEEDED)
+      return res;
+    
+    Triangulation T;
+    T.insert(points.begin(), points.end());
+
+    OGRRegisterAll();
+    /* -------------------------------------------------------------------- */
+    /*      Try opening the output datasource as an existing, writable      */
+    /* -------------------------------------------------------------------- */
+    OGRDataSource       *poODS;
+    
+    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+    OGRSFDriver          *poDriver = NULL;
+    int                  iDriver;
+
+    map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    if(tmpMap!=NULL){
+      if(strcmp(tmpMap->value,"text/xml")==0){
+	oDriver="GML";
+      }
+    }
+    
+    for( iDriver = 0;
+	 iDriver < poR->GetDriverCount() && poDriver == NULL;
+	 iDriver++ )
+      {
+#ifdef DEBUG
+	fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
+#endif
+	if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver) )
+	  {
+	    poDriver = poR->GetDriver(iDriver);
+	  }
+      }
+
+    if( poDriver == NULL )
+      {
+	char emessage[8192];
+	sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+        
+	for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	  }
+
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+
+      }
+
+    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+      char emessage[1024];
+      sprintf( emessage,  "%s driver does not support data source creation.\n",
+	       "json" );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the output data source.                                  */
+    /* -------------------------------------------------------------------- */
+    map* tpath=getMapFromMaps(conf,"main","tmpPath");
+    char *pszDestDataSource=(char*)malloc(100);
+    char **papszDSCO=NULL;
+    sprintf(pszDestDataSource,"/vsimem/result_%d.json",tpath->value,getpid());
+    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+    if( poODS == NULL ){
+      char emessage[1024];      
+      sprintf( emessage,  "%s driver failed to create %s\n", 
+	       "json", pszDestDataSource );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the layer.                                               */
+    /* -------------------------------------------------------------------- */
+    if( !poODS->TestCapability( ODsCCreateLayer ) )
+      {
+	char emessage[1024];
+	sprintf( emessage, 
+		 "Layer %s not found, and CreateLayer not supported by driver.", 
+		 "Result" );
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+      }
+    
+    CPLErrorReset();
+    
+    OGRLayer *poDstLayer = poODS->CreateLayer( "Result", NULL,wkbLineString,NULL);
+    if( poDstLayer == NULL ){
+      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+      return SERVICE_FAILED;
+    }
+
+
+    int ns = 0;
+    int nr = 0;
+    Edge_iterator eit =T.edges_begin();
+    for ( ; eit !=T.edges_end(); ++eit) {
+      CGAL::Object o = T.dual(eit);
+      if (const Kernel::Segment_2 *tmp=CGAL::object_cast<Kernel::Segment_2>(&o)) {
+	const Point p1=tmp->source();
+	const Point p2=tmp->target();
+#ifdef DEBUG
+	fprintf(stderr,"P1 %d %d | P2 %d %d\n",p1.x(),p1.y(),p2.x(),p2.y());
+#endif
+	OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+	OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLineString);
+	OGR_G_AddPoint_2D(currLine,p1.x(),p1.y());
+	OGR_G_AddPoint_2D(currLine,p2.x(),p2.y());
+	OGR_F_SetGeometry( hFeature, currLine ); 
+	OGR_G_DestroyGeometry(currLine);
+	if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	  setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	  return SERVICE_FAILED;
+	}
+	OGR_F_Destroy( hFeature );
+	++ns ;
+      }
+      else if (const Kernel::Ray_2 *tmp=CGAL::object_cast<Kernel::Ray_2>(&o)) { 
+	const Point p1=tmp->source();
+	const Point p2=tmp->point(2);
+	OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+	OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLineString);
+	OGR_G_AddPoint_2D(currLine,p1.x(),p1.y());
+	OGR_G_AddPoint_2D(currLine,p2.x(),p2.y());
+	OGR_F_SetGeometry( hFeature, currLine );
+	OGR_G_DestroyGeometry(currLine);
+	if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	  setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	  return SERVICE_FAILED;
+	}
+	OGR_F_Destroy( hFeature );
+	++nr; 
+      }
+    }
+    OGR_DS_Destroy( poODS );
+
+#ifdef DEBUG
+    std::cerr << "The Voronoi diagram has " << ns << " finite edges "
+	      << " and " << nr << " rays" << std::endl;
+    sprintf(tmp1,"%d finite edges, %d rays",ns,nr);
+#endif
+    
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    
+    setMapInMaps(outputs,"Result","value",res1);
+    
+    if(strcmp(oDriver,"GML")==0)
+      setMapInMaps(outputs,"Result","mimeType","text/xml");
+    else
+      setMapInMaps(outputs,"Result","mimeType","application/json");
+
+    setMapInMaps(outputs,"Result","encoding","UTF-8");
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\n===\n");
+#endif
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/Makefile	(revision 672)
@@ -0,0 +1,13 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=-DZOO_SERVICE ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/contour_service.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/contour_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+install:
+	install -d ${CGI_DIR}/gdal/contour
+	install cgi-env/* ${CGI_DIR}/gdal/contour
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/cgi-env/Gdal_Contour.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/cgi-env/Gdal_Contour.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/cgi-env/Gdal_Contour.zcfg	(revision 672)
@@ -0,0 +1,65 @@
+[Gdal_Contour]
+ Title = Builds vector contour lines from a raster elevation model.
+ Abstract = http://www.gdal.org/gdal_contour.html
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = contour_service.zo
+ <DataInputs>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data source name.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [i]
+   Title = An interval value
+   Abstract = The elevation interval between contours.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [a]
+   Title = Attribute name
+   Abstract = provides a name for the attribute in which to put the elevation. If not provided no elevation attribute is attached.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [b]
+   Title = The band number
+   Abstract = A particular band, defaults to band 1.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = integer
+    <Default />
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/makefile.vc	(revision 672)
@@ -0,0 +1,25 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IF DEFINED(MS_DIR)
+MS_BASE=$(MS_DIR)
+!INCLUDE $(MS_DIR)\nmake.opt
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/contour_service.zo: service.c
+	$(CPP)  /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/vrt -I$(GDAL_DIR)/alg $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/contour_service.zo  $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/contour/service.c	(revision 672)
@@ -0,0 +1,401 @@
+/******************************************************************************
+ * $Id: gdal_contour.cpp 25643 2013-02-12 13:50:42Z bishop $
+ *
+ * Project:  Contour Generator
+ * Purpose:  Contour Generator mainline.
+ * Author:   Frank Warmerdam <warmerdam@pobox.com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2003, Applied Coherent Technology (www.actgate.com). 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "gdal.h"
+#include "gdal_alg.h"
+#include "cpl_conv.h"
+#include "cpl_string.h"
+#include "ogr_api.h"
+#include "ogr_srs_api.h"
+#ifdef ZOO_SERVICE
+#include "service.h"
+#endif
+CPL_CVSID("$Id: gdal_contour.cpp 25643 2013-02-12 13:50:42Z bishop $");
+
+#ifdef ZOO_SERVICE
+extern "C" {
+#endif
+
+/************************************************************************/
+/*                            ArgIsNumeric()                            */
+/************************************************************************/
+
+static int ArgIsNumeric( const char *pszArg )
+
+{
+    return CPLGetValueType(pszArg) != CPL_VALUE_STRING;
+}
+
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage(const char* pszErrorMsg = NULL)
+
+{
+    printf( 
+        "Usage: gdal_contour [-b <band>] [-a <attribute_name>] [-3d] [-inodata]\n"
+        "                    [-snodata n] [-f <formatname>] [-i <interval>]\n"
+        "                    [-f <formatname>] [[-dsco NAME=VALUE] ...] [[-lco NAME=VALUE] ...]\n"   
+        "                    [-off <offset>] [-fl <level> <level>...]\n" 
+        "                    [-nln <outlayername>] [-q]\n"
+        "                    <src_filename> <dst_filename>\n" );
+
+    if( pszErrorMsg != NULL )
+        fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
+
+    exit( 1 );
+}
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+
+#define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
+    do { if (i + nExtraArg >= argc) \
+        Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
+
+#ifndef ZOO_SERVICE
+int main( int argc, char ** argv )
+#else
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+  int Gdal_Contour(maps*& conf,maps*& inputs,maps*& outputs)
+#endif
+{
+    fprintf(stderr,"DEBUG HELLO %f %d\n",__FILE__,__LINE__);
+    fflush(stderr);
+    GDALDatasetH	hSrcDS;
+    int i, b3D = FALSE, bNoDataSet = FALSE, bIgnoreNoData = FALSE;
+    int nBandIn = 1;
+    double dfInterval = 0.0, dfNoData = 0.0, dfOffset = 0.0;
+    const char *pszSrcFilename = NULL;
+    const char *pszDstFilename = NULL;
+    const char *pszElevAttrib = NULL;
+    const char *pszFormat = "ESRI Shapefile";
+    char        **papszDSCO = NULL, **papszLCO = NULL;
+    double adfFixedLevels[1000];
+    int    nFixedLevelCount = 0;
+    const char *pszNewLayerName = "contour";
+    int bQuiet = FALSE;
+    GDALProgressFunc pfnProgress = NULL;
+    fprintf(stderr,"DEBUG HELLO %f %d\n",__FILE__,__LINE__);
+    fflush(stderr);
+#ifndef ZOO_SERVICE
+    /* Check that we are running against at least GDAL 1.4 */
+    /* Note to developers : if we use newer API, please change the requirement */
+    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
+    {
+        fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
+                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
+        exit(1);
+    }
+#endif
+    GDALAllRegister();
+    OGRRegisterAll();
+
+#ifndef ZOO_SERVICE
+    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
+
+/* -------------------------------------------------------------------- */
+/*      Parse arguments.                                                */
+/* -------------------------------------------------------------------- */
+    for( i = 1; i < argc; i++ )
+    {
+        if( EQUAL(argv[i], "--utility_version") )
+        {
+            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
+                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
+            return 0;
+        }
+        else if( EQUAL(argv[i], "--help") )
+            Usage();
+        else if( EQUAL(argv[i],"-a") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            pszElevAttrib = argv[++i];
+        }
+        else if( EQUAL(argv[i],"-off") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            dfOffset = atof(argv[++i]);
+        }
+        else if( EQUAL(argv[i],"-i") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            dfInterval = atof(argv[++i]);
+        }
+        else if( EQUAL(argv[i],"-fl") )
+        {
+            if( i >= argc-1 )
+                Usage(CPLSPrintf("%s option requires at least 1 argument", argv[i]));
+            while( i < argc-1 
+                   && nFixedLevelCount 
+                             < (int)(sizeof(adfFixedLevels)/sizeof(double))
+                   && ArgIsNumeric(argv[i+1]) )
+                adfFixedLevels[nFixedLevelCount++] = atof(argv[++i]);
+        }
+        else if( EQUAL(argv[i],"-b") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            nBandIn = atoi(argv[++i]);
+        }
+        else if( EQUAL(argv[i],"-f") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            pszFormat = argv[++i];
+        }
+        else if( EQUAL(argv[i],"-dsco") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            papszDSCO = CSLAddString(papszDSCO, argv[++i] );
+        }
+        else if( EQUAL(argv[i],"-lco") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            papszLCO = CSLAddString(papszLCO, argv[++i] );
+        }
+        else if( EQUAL(argv[i],"-3d")  )
+        {
+            b3D = TRUE;
+        }
+        else if( EQUAL(argv[i],"-snodata") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            bNoDataSet = TRUE;
+            dfNoData = atof(argv[++i]);
+        }
+        else if( EQUAL(argv[i],"-nln") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            pszNewLayerName = argv[++i];
+        }
+        else if( EQUAL(argv[i],"-inodata") )
+        {
+            bIgnoreNoData = TRUE;
+        }
+        else if ( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
+        {
+            bQuiet = TRUE;
+        }
+        else if( pszSrcFilename == NULL )
+        {
+            pszSrcFilename = argv[i];
+        }
+        else if( pszDstFilename == NULL )
+        {
+            pszDstFilename = argv[i];
+        }
+        else
+            Usage("Too many command options.");
+    }
+#else
+    bQuiet = TRUE;
+    bIgnoreNoData = TRUE;
+    map* tmpMap=NULL;
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"a","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      pszElevAttrib = strdup(tmpMap->value);
+    }
+    tmpMap=getMapFromMaps(inputs,"off","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      dfOffset = atof(tmpMap->value);
+    }
+    tmpMap=getMapFromMaps(inputs,"i","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      dfInterval = atof(tmpMap->value);
+    }
+    tmpMap=getMapFromMaps(inputs,"b","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      nBandIn = atoi(tmpMap->value);
+    }
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      pszSrcFilename = strdup(tmpMap->value);
+    }
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL && strncmp(tmpMap->value,"NULL",4)!=0){
+      pszDstFilename = strdup(tmpMap->value);
+    }
+#endif
+    if( dfInterval == 0.0 && nFixedLevelCount == 0 )
+    {
+        Usage("Neither -i nor -fl are specified.");
+    }
+
+    if (pszSrcFilename == NULL)
+    {
+        Usage("Missing source filename.");
+    }
+
+    if (pszDstFilename == NULL)
+    {
+        Usage("Missing destination filename.");
+    }
+    
+    if (!bQuiet)
+        pfnProgress = GDALTermProgress;
+
+/* -------------------------------------------------------------------- */
+/*      Open source raster file.                                        */
+/* -------------------------------------------------------------------- */
+    GDALRasterBandH hBand;
+
+    hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
+    if( hSrcDS == NULL ){
+#ifndef ZOO_SERVICE
+        exit( 2 );
+#else
+	setMapInMaps(conf,"lenv","message","Unable to open the file");
+#endif
+    }
+    hBand = GDALGetRasterBand( hSrcDS, nBandIn );
+    if( hBand == NULL )
+    {
+#ifndef ZOO_SERVICE
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Band %d does not exist on dataset.", 
+                  nBandIn );
+        exit(2);
+#else
+	char tmp[1024];
+	sprintf(tmp,"Band %d does not exist on dataset.",nBandIn);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+#endif
+    }
+
+    if( !bNoDataSet && !bIgnoreNoData )
+        dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet );
+
+/* -------------------------------------------------------------------- */
+/*      Try to get a coordinate system from the raster.                 */
+/* -------------------------------------------------------------------- */
+    OGRSpatialReferenceH hSRS = NULL;
+
+    const char *pszWKT = GDALGetProjectionRef( hSrcDS );
+
+    if( pszWKT != NULL && strlen(pszWKT) != 0 )
+        hSRS = OSRNewSpatialReference( pszWKT );
+
+/* -------------------------------------------------------------------- */
+/*      Create the outputfile.                                          */
+/* -------------------------------------------------------------------- */
+    OGRDataSourceH hDS;
+    OGRSFDriverH hDriver = OGRGetDriverByName( pszFormat );
+    OGRFieldDefnH hFld;
+    OGRLayerH hLayer;
+
+    if( hDriver == NULL )
+    {
+#ifndef ZOO_SERVICE
+        fprintf( stderr, "Unable to find format driver named %s.\n", 
+                 pszFormat );
+        exit( 10 );
+#else
+	char tmp[1024];
+        sprintf( tmp, "Unable to find format driver named %s.\n", pszFormat );	
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+#endif
+    }
+
+    hDS = OGR_Dr_CreateDataSource( hDriver, pszDstFilename, papszDSCO );
+    if( hDS == NULL ){
+#ifndef ZOO_SERVICE
+        exit( 1 );
+#else
+	setMapInMaps(conf,"lenv","message","Unable to create the file");
+	return SERVICE_FAILED;
+#endif
+    }
+
+    hLayer = OGR_DS_CreateLayer( hDS, pszNewLayerName, hSRS, 
+                                 b3D ? wkbLineString25D : wkbLineString,
+                                 papszLCO );
+    if( hLayer == NULL )
+        exit( 1 );
+
+    hFld = OGR_Fld_Create( "ID", OFTInteger );
+    OGR_Fld_SetWidth( hFld, 8 );
+    OGR_L_CreateField( hLayer, hFld, FALSE );
+    OGR_Fld_Destroy( hFld );
+
+    if( pszElevAttrib )
+    {
+        hFld = OGR_Fld_Create( pszElevAttrib, OFTReal );
+        OGR_Fld_SetWidth( hFld, 12 );
+        OGR_Fld_SetPrecision( hFld, 3 );
+        OGR_L_CreateField( hLayer, hFld, FALSE );
+        OGR_Fld_Destroy( hFld );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Invoke.                                                         */
+/* -------------------------------------------------------------------- */
+    CPLErr eErr;
+    
+    eErr = GDALContourGenerate( hBand, dfInterval, dfOffset, 
+                         nFixedLevelCount, adfFixedLevels,
+                         bNoDataSet, dfNoData, hLayer, 
+                         OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ), 
+                                               "ID" ), 
+                         (pszElevAttrib == NULL) ? -1 :
+                                 OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hLayer ), 
+                                                       pszElevAttrib ), 
+                         pfnProgress, NULL );
+
+    OGR_DS_Destroy( hDS );
+    GDALClose( hSrcDS );
+
+    if (hSRS)
+        OSRDestroySpatialReference( hSRS );
+
+#ifndef ZOO_SERVICE
+    CSLDestroy( argv );
+    CSLDestroy( papszDSCO );
+    CSLDestroy( papszLCO );
+    GDALDestroyDriverManager();
+    OGRCleanupAll();
+    return 0;
+#else
+    GDALDestroyDriverManager();
+    OGRCleanupAll();
+    char tmp[1024];
+    sprintf(tmp,"File %s successfully created.",pszDstFilename);
+    setMapInMaps(outputs,"Result","value",tmp);
+    return SERVICE_SUCCEEDED;
+#endif
+}
+
+#ifdef ZOO_SERVICE
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/Makefile	(revision 672)
@@ -0,0 +1,15 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=-DZOO_SERVICE ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/dem_service.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/dem_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/gdal/dem
+	install cgi-env/* ${CGI_DIR}/gdal/dem
+
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/cgi-env/Gdal_Dem.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/cgi-env/Gdal_Dem.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/cgi-env/Gdal_Dem.zcfg	(revision 672)
@@ -0,0 +1,56 @@
+[Gdal_Dem]
+ Title = Tools to analyze and visualize DEMs.
+ Abstract = http://www.gdal.org/gdaldem.html
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = dem_service.zo
+ <DataInputs>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data source name.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [utility]
+   Title = The mode
+   Abstract = This service has 7 different modes :  hillshade,  slope,  aspect, color-relief, TRI, TPI, roughness
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [s]
+   Title = The scale
+   Abstract = Scale is the ratio of vertical units to horizontal, for Feet:Latlong use 370400, for Meters:LatLong use 111120
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/makefile.vc	(revision 672)
@@ -0,0 +1,23 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/dem_service.zo: service.c
+	$(CPP)  /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/vrt $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/dem_service.zo  $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/dem/service.c	(revision 672)
@@ -0,0 +1,2899 @@
+/******************************************************************************
+ * $Id$
+ *
+ * Project:  GDAL DEM Utilities
+ * Purpose:  
+ * Authors:  Matthew Perry, perrygeo at gmail.com
+ *           Even Rouault, even dot rouault at mines dash paris dot org
+ *           Howard Butler, hobu.inc at gmail.com
+ *           Chris Yesson, chris dot yesson at ioz dot ac dot uk
+ *
+ ******************************************************************************
+ * Copyright (c) 2006, 2009 Matthew Perry 
+ * Copyright (c) 2009 Even Rouault
+ * Portions derived from GRASS 4.1 (public domain) See 
+ * http://trac.osgeo.org/gdal/ticket/2975 for more information regarding 
+ * history of this code
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************
+ *
+ * Slope and aspect calculations based on original method for GRASS GIS 4.1
+ * by Michael Shapiro, U.S.Army Construction Engineering Research Laboratory
+ *    Olga Waupotitsch, U.S.Army Construction Engineering Research Laboratory
+ *    Marjorie Larson, U.S.Army Construction Engineering Research Laboratory
+ * as found in GRASS's r.slope.aspect module.
+ *
+ * Horn's formula is used to find the first order derivatives in x and y directions
+ * for slope and aspect calculations: Horn, B. K. P. (1981).
+ * "Hill Shading and the Reflectance Map", Proceedings of the IEEE, 69(1):14-47. 
+ *
+ * Other reference :
+ * Burrough, P.A. and McDonell, R.A., 1998. Principles of Geographical Information
+ * Systems. p. 190.
+ *
+ * Shaded relief based on original method for GRASS GIS 4.1 by Jim Westervelt,
+ * U.S. Army Construction Engineering Research Laboratory
+ * as found in GRASS's r.shaded.relief (formerly shade.rel.sh) module.
+ * ref: "r.mapcalc: An Algebra for GIS and Image Processing",
+ * by Michael Shapiro and Jim Westervelt, U.S. Army Construction Engineering
+ * Research Laboratory (March/1991)
+ *
+ * Color table of named colors and lookup code derived from src/libes/gis/named_colr.c
+ * of GRASS 4.1
+ *
+ * TRI - Terrain Ruggedness Index is as descibed in Wilson et al (2007)
+ * this is based on the method of Valentine et al. (2004)  
+ * 
+ * TPI - Topographic Position Index follows the description in Wilson et al (2007), following Weiss (2001)
+ * The radius is fixed at 1 cell width/height
+ * 
+ * Roughness - follows the definition in Wilson et al. (2007), which follows Dartnell (2000)
+ *
+ * References for TRI/TPI/Roughness:
+ * Dartnell, P. 2000. Applying Remote Sensing Techniques to map Seafloor 
+ *  Geology/Habitat Relationships. Masters Thesis, San Francisco State 
+ *  University, pp. 108.
+ * Valentine, P. C., S. J. Fuller, L. A. Scully. 2004. Terrain Ruggedness 
+ *  Analysis and Distribution of Boulder Ridges in the Stellwagen Bank National
+ *  Marine Sanctuary Region (poster). Galway, Ireland: 5th International 
+ *  Symposium on Marine Geological and Biological Habitat Mapping (GeoHAB), 
+ *  May 2004.
+ * Weiss, A. D. 2001. Topographic Positions and Landforms Analysis (poster), 
+ *  ESRI International User Conference, July 2001. San Diego, CA: ESRI.
+ * Wilson, M. F. J.; O'Connell, B.; Brown, C.; Guinan, J. C. & Grehan, A. J. 
+ *  Multiscale terrain analysis of multibeam bathymetry data for habitat mapping
+ *  on the continental slope Marine Geodesy, 2007, 30, 3-35
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "cpl_conv.h"
+#include "cpl_string.h"
+#include "gdal.h"
+#include "gdal_priv.h"
+#ifndef ZOO_SERVICE
+#include "commonutils.h"
+#else
+#include "service.h"
+#endif
+
+CPL_CVSID("$Id$");
+
+#ifdef WIN32
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp 
+#endif
+
+#ifdef ZOO_SERVICE
+extern "C" {
+#endif
+
+#ifndef M_PI
+# define M_PI  3.1415926535897932384626433832795
+#endif
+
+#define INTERPOL(a,b) ((bSrcHasNoData && (ARE_REAL_EQUAL(a, fSrcNoDataValue) || ARE_REAL_EQUAL(b, fSrcNoDataValue))) ? fSrcNoDataValue : 2 * (a) - (b))
+
+#ifdef ZOO_SERVICE
+static int Usage(maps*& conf, const char* pszErrorMsg = NULL){
+      setMapInMaps(conf,"lenv","message","Missing source.");
+      return SERVICE_FAILED;
+}
+#else
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage(const char* pszErrorMsg = NULL)
+
+{
+    printf( " Usage: \n"
+            " - To generate a shaded relief map from any GDAL-supported elevation raster : \n\n"
+            "     gdaldem hillshade input_dem output_hillshade \n"
+            "                 [-z ZFactor (default=1)] [-s scale* (default=1)] \n"
+            "                 [-az Azimuth (default=315)] [-alt Altitude (default=45)]\n"
+            "                 [-alg ZevenbergenThorne] [-combined]\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " - To generates a slope map from any GDAL-supported elevation raster :\n\n"
+            "     gdaldem slope input_dem output_slope_map \n"
+            "                 [-p use percent slope (default=degrees)] [-s scale* (default=1)]\n"
+            "                 [-alg ZevenbergenThorne]\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " - To generate an aspect map from any GDAL-supported elevation raster\n"
+            "   Outputs a 32-bit float tiff with pixel values from 0-360 indicating azimuth :\n\n"
+            "     gdaldem aspect input_dem output_aspect_map \n"
+            "                 [-trigonometric] [-zero_for_flat]\n"
+            "                 [-alg ZevenbergenThorne]\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " - To generate a color relief map from any GDAL-supported elevation raster\n"
+            "     gdaldem color-relief input_dem color_text_file output_color_relief_map\n"
+            "                 [-alpha] [-exact_color_entry | -nearest_color_entry]\n"
+            "                 [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "     where color_text_file contains lines of the format \"elevation_value red green blue\"\n"
+            "\n"
+            " - To generate a Terrain Ruggedness Index (TRI) map from any GDAL-supported elevation raster\n"
+            "     gdaldem TRI input_dem output_TRI_map\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " - To generate a Topographic Position Index (TPI) map from any GDAL-supported elevation raster\n"
+            "     gdaldem TPI input_dem output_TPI_map\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " - To generate a roughness map from any GDAL-supported elevation raster\n"
+            "     gdaldem roughness input_dem output_roughness_map\n"
+            "                 [-compute_edges] [-b Band (default=1)] [-of format] [-co \"NAME=VALUE\"]* [-q]\n"
+            "\n"
+            " Notes : \n"
+            "   Scale is the ratio of vertical units to horizontal\n"
+            "    for Feet:Latlong use scale=370400, for Meters:LatLong use scale=111120 \n\n");
+
+    if( pszErrorMsg != NULL )
+        fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
+
+    exit( 1 );
+}
+#endif
+/************************************************************************/
+/*                          ComputeVal()                                */
+/************************************************************************/
+
+typedef float (*GDALGeneric3x3ProcessingAlg) (float* pafWindow, float fDstNoDataValue, void* pData);
+
+static float ComputeVal(int bSrcHasNoData, float fSrcNoDataValue,
+                        float* afWin, float fDstNoDataValue,
+                        GDALGeneric3x3ProcessingAlg pfnAlg,
+                        void* pData,
+                        int bComputeAtEdges)
+{
+    if (bSrcHasNoData && ARE_REAL_EQUAL(afWin[4], fSrcNoDataValue))
+    {
+        return fDstNoDataValue;
+    }
+    else if (bSrcHasNoData)
+    {
+        int k;
+        for(k=0;k<9;k++)
+        {
+            if (ARE_REAL_EQUAL(afWin[k], fSrcNoDataValue))
+            {
+                if (bComputeAtEdges)
+                    afWin[k] = afWin[4];
+                else
+                    return fDstNoDataValue;
+            }
+        }
+    }
+
+    return pfnAlg(afWin, fDstNoDataValue, pData);
+}
+
+/************************************************************************/
+/*                  GDALGeneric3x3Processing()                          */
+/************************************************************************/
+
+CPLErr GDALGeneric3x3Processing  ( GDALRasterBandH hSrcBand,
+                                   GDALRasterBandH hDstBand,
+                                   GDALGeneric3x3ProcessingAlg pfnAlg,
+                                   void* pData,
+                                   int bComputeAtEdges,
+                                   GDALProgressFunc pfnProgress,
+                                   void * pProgressData)
+{
+    CPLErr eErr;
+    float *pafThreeLineWin; /* 3 line rotating source buffer */
+    float *pafOutputBuf;     /* 1 line destination buffer */
+    int i, j;
+
+    int bSrcHasNoData, bDstHasNoData;
+    float fSrcNoDataValue = 0.0, fDstNoDataValue = 0.0;
+
+    int nXSize = GDALGetRasterBandXSize(hSrcBand);
+    int nYSize = GDALGetRasterBandYSize(hSrcBand);
+
+    if (pfnProgress == NULL)
+        pfnProgress = GDALDummyProgress;
+
+/* -------------------------------------------------------------------- */
+/*      Initialize progress counter.                                    */
+/* -------------------------------------------------------------------- */
+    if( !pfnProgress( 0.0, NULL, pProgressData ) )
+    {
+        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+        return CE_Failure;
+    }
+
+    pafOutputBuf = (float *) CPLMalloc(sizeof(float)*nXSize);
+    pafThreeLineWin  = (float *) CPLMalloc(3*sizeof(float)*(nXSize+1));
+
+    fSrcNoDataValue = (float) GDALGetRasterNoDataValue(hSrcBand, &bSrcHasNoData);
+    fDstNoDataValue = (float) GDALGetRasterNoDataValue(hDstBand, &bDstHasNoData);
+    if (!bDstHasNoData)
+        fDstNoDataValue = 0.0;
+
+    // Move a 3x3 pafWindow over each cell 
+    // (where the cell in question is #4)
+    // 
+    //      0 1 2
+    //      3 4 5
+    //      6 7 8
+
+    /* Preload the first 2 lines */
+    for ( i = 0; i < 2 && i < nYSize; i++)
+    {
+        GDALRasterIO(   hSrcBand,
+                        GF_Read,
+                        0, i,
+                        nXSize, 1,
+                        pafThreeLineWin + i * nXSize,
+                        nXSize, 1,
+                        GDT_Float32,
+                        0, 0);
+    }
+    
+    if (bComputeAtEdges && nXSize >= 2 && nYSize >= 2)
+    {
+        for (j = 0; j < nXSize; j++)
+        {
+            float afWin[9];
+            int jmin = (j == 0) ? j : j - 1;
+            int jmax = (j == nXSize - 1) ? j : j + 1;
+
+            afWin[0] = INTERPOL(pafThreeLineWin[jmin], pafThreeLineWin[nXSize + jmin]);
+            afWin[1] = INTERPOL(pafThreeLineWin[j],    pafThreeLineWin[nXSize + j]);
+            afWin[2] = INTERPOL(pafThreeLineWin[jmax], pafThreeLineWin[nXSize + jmax]);
+            afWin[3] = pafThreeLineWin[jmin];
+            afWin[4] = pafThreeLineWin[j];
+            afWin[5] = pafThreeLineWin[jmax];
+            afWin[6] = pafThreeLineWin[nXSize + jmin];
+            afWin[7] = pafThreeLineWin[nXSize + j];
+            afWin[8] = pafThreeLineWin[nXSize + jmax];
+
+            pafOutputBuf[j] = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                         afWin, fDstNoDataValue,
+                                         pfnAlg, pData, bComputeAtEdges);
+        }
+        GDALRasterIO(hDstBand, GF_Write,
+                    0, 0, nXSize, 1,
+                    pafOutputBuf, nXSize, 1, GDT_Float32, 0, 0);
+    }
+    else
+    {
+        // Exclude the edges
+        for (j = 0; j < nXSize; j++)
+        {
+            pafOutputBuf[j] = fDstNoDataValue;
+        }
+        GDALRasterIO(hDstBand, GF_Write,
+                    0, 0, nXSize, 1,
+                    pafOutputBuf, nXSize, 1, GDT_Float32, 0, 0);
+    
+        if (nYSize > 1)
+        {
+            GDALRasterIO(hDstBand, GF_Write,
+                        0, nYSize - 1, nXSize, 1,
+                        pafOutputBuf, nXSize, 1, GDT_Float32, 0, 0);
+        }
+    }
+    
+    int nLine1Off = 0*nXSize;
+    int nLine2Off = 1*nXSize;
+    int nLine3Off = 2*nXSize;
+
+    for ( i = 1; i < nYSize-1; i++)
+    {
+        /* Read third line of the line buffer */
+        eErr = GDALRasterIO(   hSrcBand,
+                        GF_Read,
+                        0, i+1,
+                        nXSize, 1,
+                        pafThreeLineWin + nLine3Off,
+                        nXSize, 1,
+                        GDT_Float32,
+                        0, 0);
+        if (eErr != CE_None)
+            goto end;
+
+        if (bComputeAtEdges && nXSize >= 2)
+        {
+            float afWin[9];
+
+            j = 0;
+            afWin[0] = INTERPOL(pafThreeLineWin[nLine1Off + j], pafThreeLineWin[nLine1Off + j+1]);
+            afWin[1] = pafThreeLineWin[nLine1Off + j];
+            afWin[2] = pafThreeLineWin[nLine1Off + j+1];
+            afWin[3] = INTERPOL(pafThreeLineWin[nLine2Off + j], pafThreeLineWin[nLine2Off + j+1]);
+            afWin[4] = pafThreeLineWin[nLine2Off + j];
+            afWin[5] = pafThreeLineWin[nLine2Off + j+1];
+            afWin[6] = INTERPOL(pafThreeLineWin[nLine3Off + j], pafThreeLineWin[nLine3Off + j+1]);
+            afWin[7] = pafThreeLineWin[nLine3Off + j];
+            afWin[8] = pafThreeLineWin[nLine3Off + j+1];
+
+            pafOutputBuf[j] = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                         afWin, fDstNoDataValue,
+                                         pfnAlg, pData, bComputeAtEdges);
+            j = nXSize - 1;
+
+            afWin[0] = pafThreeLineWin[nLine1Off + j-1];
+            afWin[1] = pafThreeLineWin[nLine1Off + j];
+            afWin[2] = INTERPOL(pafThreeLineWin[nLine1Off + j], pafThreeLineWin[nLine1Off + j-1]);
+            afWin[3] = pafThreeLineWin[nLine2Off + j-1];
+            afWin[4] = pafThreeLineWin[nLine2Off + j];
+            afWin[5] = INTERPOL(pafThreeLineWin[nLine2Off + j], pafThreeLineWin[nLine2Off + j-1]);
+            afWin[6] = pafThreeLineWin[nLine3Off + j-1];
+            afWin[7] = pafThreeLineWin[nLine3Off + j];
+            afWin[8] = INTERPOL(pafThreeLineWin[nLine3Off + j], pafThreeLineWin[nLine3Off + j-1]);
+
+            pafOutputBuf[j] = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                         afWin, fDstNoDataValue,
+                                         pfnAlg, pData, bComputeAtEdges);
+        }
+        else
+        {
+            // Exclude the edges
+            pafOutputBuf[0] = fDstNoDataValue;
+            if (nXSize > 1)
+                pafOutputBuf[nXSize - 1] = fDstNoDataValue;
+        }
+
+        for (j = 1; j < nXSize - 1; j++)
+        {
+            float afWin[9];
+            afWin[0] = pafThreeLineWin[nLine1Off + j-1];
+            afWin[1] = pafThreeLineWin[nLine1Off + j];
+            afWin[2] = pafThreeLineWin[nLine1Off + j+1];
+            afWin[3] = pafThreeLineWin[nLine2Off + j-1];
+            afWin[4] = pafThreeLineWin[nLine2Off + j];
+            afWin[5] = pafThreeLineWin[nLine2Off + j+1];
+            afWin[6] = pafThreeLineWin[nLine3Off + j-1];
+            afWin[7] = pafThreeLineWin[nLine3Off + j];
+            afWin[8] = pafThreeLineWin[nLine3Off + j+1];
+
+            pafOutputBuf[j] = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                         afWin, fDstNoDataValue,
+                                         pfnAlg, pData, bComputeAtEdges);
+        }
+
+        /* -----------------------------------------
+         * Write Line to Raster
+         */
+        eErr = GDALRasterIO(hDstBand, GF_Write, 0, i, nXSize, 1,
+                     pafOutputBuf, nXSize, 1, GDT_Float32, 0, 0);
+        if (eErr != CE_None)
+            goto end;
+
+        if( !pfnProgress( 1.0 * (i+1) / nYSize, NULL, pProgressData ) )
+        {
+            CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+            eErr = CE_Failure;
+            goto end;
+        }
+        
+        int nTemp = nLine1Off;
+        nLine1Off = nLine2Off;
+        nLine2Off = nLine3Off;
+        nLine3Off = nTemp;
+    }
+
+    if (bComputeAtEdges && nXSize >= 2 && nYSize >= 2)
+    {
+        for (j = 0; j < nXSize; j++)
+        {
+            float afWin[9];
+            int jmin = (j == 0) ? j : j - 1;
+            int jmax = (j == nXSize - 1) ? j : j + 1;
+
+            afWin[0] = pafThreeLineWin[nLine1Off + jmin];
+            afWin[1] = pafThreeLineWin[nLine1Off + j];
+            afWin[2] = pafThreeLineWin[nLine1Off + jmax];
+            afWin[3] = pafThreeLineWin[nLine2Off + jmin];
+            afWin[4] = pafThreeLineWin[nLine2Off + j];
+            afWin[5] = pafThreeLineWin[nLine2Off + jmax];
+            afWin[6] = INTERPOL(pafThreeLineWin[nLine2Off + jmin], pafThreeLineWin[nLine1Off + jmin]);
+            afWin[7] = INTERPOL(pafThreeLineWin[nLine2Off + j],    pafThreeLineWin[nLine1Off + j]);
+            afWin[8] = INTERPOL(pafThreeLineWin[nLine2Off + jmax], pafThreeLineWin[nLine1Off + jmax]);
+
+            pafOutputBuf[j] = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                         afWin, fDstNoDataValue,
+                                         pfnAlg, pData, bComputeAtEdges);
+        }
+        GDALRasterIO(hDstBand, GF_Write,
+                     0, i, nXSize, 1,
+                     pafOutputBuf, nXSize, 1, GDT_Float32, 0, 0);
+    }
+
+    pfnProgress( 1.0, NULL, pProgressData );
+    eErr = CE_None;
+
+end:
+    CPLFree(pafOutputBuf);
+    CPLFree(pafThreeLineWin);
+
+    return eErr;
+}
+
+
+/************************************************************************/
+/*                         GDALHillshade()                              */
+/************************************************************************/
+
+typedef struct
+{
+    double nsres;
+    double ewres;
+    double sin_altRadians;
+    double cos_altRadians_mul_z_scale_factor;
+    double azRadians;
+    double square_z_scale_factor;
+    double square_M_PI_2;
+} GDALHillshadeAlgData;
+
+/* Unoptimized formulas are :
+    x = psData->z*((afWin[0] + afWin[3] + afWin[3] + afWin[6]) -
+        (afWin[2] + afWin[5] + afWin[5] + afWin[8])) /
+        (8.0 * psData->ewres * psData->scale);
+
+    y = psData->z*((afWin[6] + afWin[7] + afWin[7] + afWin[8]) -
+        (afWin[0] + afWin[1] + afWin[1] + afWin[2])) /
+        (8.0 * psData->nsres * psData->scale);
+
+    slope = M_PI / 2 - atan(sqrt(x*x + y*y));
+
+    aspect = atan2(y,x);
+
+    cang = sin(alt * degreesToRadians) * sin(slope) +
+           cos(alt * degreesToRadians) * cos(slope) *
+           cos(az * degreesToRadians - M_PI/2 - aspect);
+*/
+
+float GDALHillshadeAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    GDALHillshadeAlgData* psData = (GDALHillshadeAlgData*)pData;
+    double x, y, aspect, xx_plus_yy, cang;
+    
+    // First Slope ...
+    x = ((afWin[0] + afWin[3] + afWin[3] + afWin[6]) -
+        (afWin[2] + afWin[5] + afWin[5] + afWin[8])) / psData->ewres;
+
+    y = ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) -
+        (afWin[0] + afWin[1] + afWin[1] + afWin[2])) / psData->nsres;
+
+    xx_plus_yy = x * x + y * y;
+
+    // ... then aspect...
+    aspect = atan2(y,x);
+
+    // ... then the shade value
+    cang = (psData->sin_altRadians -
+           psData->cos_altRadians_mul_z_scale_factor * sqrt(xx_plus_yy) *
+           sin(aspect - psData->azRadians)) /
+           sqrt(1 + psData->square_z_scale_factor * xx_plus_yy);
+
+    if (cang <= 0.0) 
+        cang = 1.0;
+    else
+        cang = 1.0 + (254.0 * cang);
+        
+    return (float) cang;
+}
+
+float GDALHillshadeCombinedAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    GDALHillshadeAlgData* psData = (GDALHillshadeAlgData*)pData;
+    double x, y, aspect, xx_plus_yy, cang;
+    
+    // First Slope ...
+    x = ((afWin[0] + afWin[3] + afWin[3] + afWin[6]) -
+        (afWin[2] + afWin[5] + afWin[5] + afWin[8])) / psData->ewres;
+
+    y = ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) -
+        (afWin[0] + afWin[1] + afWin[1] + afWin[2])) / psData->nsres;
+
+    xx_plus_yy = x * x + y * y;
+
+    // ... then aspect...
+    aspect = atan2(y,x);
+    double slope = xx_plus_yy * psData->square_z_scale_factor;
+
+    // ... then the shade value
+    cang = acos((psData->sin_altRadians -
+           psData->cos_altRadians_mul_z_scale_factor * sqrt(xx_plus_yy) *
+           sin(aspect - psData->azRadians)) /
+           sqrt(1 + slope));
+
+    // combined shading
+    cang = 1 - cang * atan(sqrt(slope)) / psData->square_M_PI_2;
+
+    if (cang <= 0.0) 
+        cang = 1.0;
+    else
+        cang = 1.0 + (254.0 * cang);
+        
+    return (float) cang;
+}
+
+float GDALHillshadeZevenbergenThorneAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    GDALHillshadeAlgData* psData = (GDALHillshadeAlgData*)pData;
+    double x, y, aspect, xx_plus_yy, cang;
+    
+    // First Slope ...
+    x = (afWin[3] - afWin[5]) / psData->ewres;
+
+    y = (afWin[7] - afWin[1]) / psData->nsres;
+
+    xx_plus_yy = x * x + y * y;
+
+    // ... then aspect...
+    aspect = atan2(y,x);
+
+    // ... then the shade value
+    cang = (psData->sin_altRadians -
+           psData->cos_altRadians_mul_z_scale_factor * sqrt(xx_plus_yy) *
+           sin(aspect - psData->azRadians)) /
+           sqrt(1 + psData->square_z_scale_factor * xx_plus_yy);
+
+    if (cang <= 0.0) 
+        cang = 1.0;
+    else
+        cang = 1.0 + (254.0 * cang);
+        
+    return (float) cang;
+}
+
+float GDALHillshadeZevenbergenThorneCombinedAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    GDALHillshadeAlgData* psData = (GDALHillshadeAlgData*)pData;
+    double x, y, aspect, xx_plus_yy, cang;
+    
+    // First Slope ...
+    x = (afWin[3] - afWin[5]) / psData->ewres;
+
+    y = (afWin[7] - afWin[1]) / psData->nsres;
+
+    xx_plus_yy = x * x + y * y;
+
+    // ... then aspect...
+    aspect = atan2(y,x);
+    double slope = xx_plus_yy * psData->square_z_scale_factor;
+
+    // ... then the shade value
+    cang = acos((psData->sin_altRadians -
+           psData->cos_altRadians_mul_z_scale_factor * sqrt(xx_plus_yy) *
+           sin(aspect - psData->azRadians)) /
+           sqrt(1 + slope));
+
+    // combined shading
+    cang = 1 - cang * atan(sqrt(slope)) / psData->square_M_PI_2;
+
+    if (cang <= 0.0) 
+        cang = 1.0;
+    else
+        cang = 1.0 + (254.0 * cang);
+        
+    return (float) cang;
+}
+
+void*  GDALCreateHillshadeData(double* adfGeoTransform,
+                               double z,
+                               double scale,
+                               double alt,
+                               double az,
+                               int bZevenbergenThorne)
+{
+    GDALHillshadeAlgData* pData =
+        (GDALHillshadeAlgData*)CPLMalloc(sizeof(GDALHillshadeAlgData));
+        
+    const double degreesToRadians = M_PI / 180.0;
+    pData->nsres = adfGeoTransform[5];
+    pData->ewres = adfGeoTransform[1];
+    pData->sin_altRadians = sin(alt * degreesToRadians);
+    pData->azRadians = az * degreesToRadians;
+    double z_scale_factor = z / (((bZevenbergenThorne) ? 2 : 8) * scale);
+    pData->cos_altRadians_mul_z_scale_factor =
+        cos(alt * degreesToRadians) * z_scale_factor;
+    pData->square_z_scale_factor = z_scale_factor * z_scale_factor;
+    pData->square_M_PI_2 = (M_PI*M_PI)/4;
+    return pData;
+}
+
+/************************************************************************/
+/*                         GDALSlope()                                  */
+/************************************************************************/
+
+typedef struct
+{
+    double nsres;
+    double ewres;
+    double scale;
+    int    slopeFormat;
+} GDALSlopeAlgData;
+
+float GDALSlopeHornAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    const double radiansToDegrees = 180.0 / M_PI;
+    GDALSlopeAlgData* psData = (GDALSlopeAlgData*)pData;
+    double dx, dy, key;
+    
+    dx = ((afWin[0] + afWin[3] + afWin[3] + afWin[6]) - 
+          (afWin[2] + afWin[5] + afWin[5] + afWin[8]))/psData->ewres;
+
+    dy = ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) - 
+          (afWin[0] + afWin[1] + afWin[1] + afWin[2]))/psData->nsres;
+
+    key = (dx * dx + dy * dy);
+
+    if (psData->slopeFormat == 1) 
+        return (float) (atan(sqrt(key) / (8*psData->scale)) * radiansToDegrees);
+    else
+        return (float) (100*(sqrt(key) / (8*psData->scale)));
+}
+
+float GDALSlopeZevenbergenThorneAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    const double radiansToDegrees = 180.0 / M_PI;
+    GDALSlopeAlgData* psData = (GDALSlopeAlgData*)pData;
+    double dx, dy, key;
+    
+    dx = (afWin[3] - afWin[5])/psData->ewres;
+
+    dy = (afWin[7] - afWin[1])/psData->nsres;
+
+    key = (dx * dx + dy * dy);
+
+    if (psData->slopeFormat == 1) 
+        return (float) (atan(sqrt(key) / (2*psData->scale)) * radiansToDegrees);
+    else
+        return (float) (100*(sqrt(key) / (2*psData->scale)));
+}
+
+void*  GDALCreateSlopeData(double* adfGeoTransform,
+                           double scale,
+                           int slopeFormat)
+{
+    GDALSlopeAlgData* pData =
+        (GDALSlopeAlgData*)CPLMalloc(sizeof(GDALSlopeAlgData));
+        
+    pData->nsres = adfGeoTransform[5];
+    pData->ewres = adfGeoTransform[1];
+    pData->scale = scale;
+    pData->slopeFormat = slopeFormat;
+    return pData;
+}
+
+/************************************************************************/
+/*                         GDALAspect()                                 */
+/************************************************************************/
+
+typedef struct
+{
+    int bAngleAsAzimuth;
+} GDALAspectAlgData;
+
+float GDALAspectAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    const double degreesToRadians = M_PI / 180.0;
+    GDALAspectAlgData* psData = (GDALAspectAlgData*)pData;
+    double dx, dy;
+    float aspect;
+    
+    dx = ((afWin[2] + afWin[5] + afWin[5] + afWin[8]) -
+          (afWin[0] + afWin[3] + afWin[3] + afWin[6]));
+
+    dy = ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) - 
+          (afWin[0] + afWin[1] + afWin[1] + afWin[2]));
+
+    aspect = (float) (atan2(dy,-dx) / degreesToRadians);
+
+    if (dx == 0 && dy == 0)
+    {
+        /* Flat area */
+        aspect = fDstNoDataValue;
+    } 
+    else if ( psData->bAngleAsAzimuth )
+    {
+        if (aspect > 90.0) 
+            aspect = 450.0f - aspect;
+        else
+            aspect = 90.0f - aspect;
+    }
+    else
+    {
+        if (aspect < 0)
+            aspect += 360.0;
+    }
+
+    if (aspect == 360.0) 
+        aspect = 0.0;
+
+    return aspect;
+}
+
+float GDALAspectZevenbergenThorneAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    const double degreesToRadians = M_PI / 180.0;
+    GDALAspectAlgData* psData = (GDALAspectAlgData*)pData;
+    double dx, dy;
+    float aspect;
+    
+    dx = (afWin[5] - afWin[3]);
+
+    dy = (afWin[7] - afWin[1]);
+
+    aspect = (float) (atan2(dy,-dx) / degreesToRadians);
+
+    if (dx == 0 && dy == 0)
+    {
+        /* Flat area */
+        aspect = fDstNoDataValue;
+    } 
+    else if ( psData->bAngleAsAzimuth )
+    {
+        if (aspect > 90.0) 
+            aspect = 450.0f - aspect;
+        else
+            aspect = 90.0f - aspect;
+    }
+    else
+    {
+        if (aspect < 0)
+            aspect += 360.0;
+    }
+
+    if (aspect == 360.0) 
+        aspect = 0.0;
+
+    return aspect;
+}
+void*  GDALCreateAspectData(int bAngleAsAzimuth)
+{
+    GDALAspectAlgData* pData =
+        (GDALAspectAlgData*)CPLMalloc(sizeof(GDALAspectAlgData));
+        
+    pData->bAngleAsAzimuth = bAngleAsAzimuth;
+    return pData;
+}
+
+/************************************************************************/
+/*                      GDALColorRelief()                               */
+/************************************************************************/
+
+typedef struct
+{
+    double dfVal;
+    int nR;
+    int nG;
+    int nB;
+    int nA;
+} ColorAssociation;
+
+static int GDALColorReliefSortColors(const void* pA, const void* pB)
+{
+    ColorAssociation* pC1 = (ColorAssociation*)pA;
+    ColorAssociation* pC2 = (ColorAssociation*)pB;
+    return (pC1->dfVal < pC2->dfVal) ? -1 :
+           (pC1->dfVal == pC2->dfVal) ? 0 : 1;
+}
+
+typedef enum
+{
+    COLOR_SELECTION_INTERPOLATE,
+    COLOR_SELECTION_NEAREST_ENTRY,
+    COLOR_SELECTION_EXACT_ENTRY
+} ColorSelectionMode;
+
+static int GDALColorReliefGetRGBA (ColorAssociation* pasColorAssociation,
+                                   int nColorAssociation,
+                                   double dfVal,
+                                   ColorSelectionMode eColorSelectionMode,
+                                   int* pnR,
+                                   int* pnG,
+                                   int* pnB,
+                                   int* pnA)
+{
+    int i;
+    int lower = 0;
+    int upper = nColorAssociation - 1;
+    int mid;
+
+    /* Find the index of the first element in the LUT input array that */
+    /* is not smaller than the dfVal value. */
+    while(TRUE)
+    {
+        mid = (lower + upper) / 2;
+        if (upper - lower <= 1)
+        {
+            if (dfVal < pasColorAssociation[lower].dfVal)
+                i = lower;
+            else if (dfVal < pasColorAssociation[upper].dfVal)
+                i = upper;
+            else
+                i = upper + 1;
+            break;
+        }
+        else if (pasColorAssociation[mid].dfVal >= dfVal)
+        {
+            upper = mid;
+        }
+        else
+        {
+            lower = mid;
+        }
+    }
+
+    if (i == 0)
+    {
+        if (eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
+            pasColorAssociation[0].dfVal != dfVal)
+        {
+            *pnR = 0;
+            *pnG = 0;
+            *pnB = 0;
+            *pnA = 0;
+            return FALSE;
+        }
+        else
+        {
+            *pnR = pasColorAssociation[0].nR;
+            *pnG = pasColorAssociation[0].nG;
+            *pnB = pasColorAssociation[0].nB;
+            *pnA = pasColorAssociation[0].nA;
+            return TRUE;
+        }
+    }
+    else if (i == nColorAssociation)
+    {
+        if (eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
+            pasColorAssociation[i-1].dfVal != dfVal)
+        {
+            *pnR = 0;
+            *pnG = 0;
+            *pnB = 0;
+            *pnA = 0;
+            return FALSE;
+        }
+        else
+        {
+            *pnR = pasColorAssociation[i-1].nR;
+            *pnG = pasColorAssociation[i-1].nG;
+            *pnB = pasColorAssociation[i-1].nB;
+            *pnA = pasColorAssociation[i-1].nA;
+            return TRUE;
+        }
+    }
+    else
+    {
+        if (eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
+            pasColorAssociation[i-1].dfVal != dfVal)
+        {
+            *pnR = 0;
+            *pnG = 0;
+            *pnB = 0;
+            *pnA = 0;
+            return FALSE;
+        }
+        
+        if (eColorSelectionMode == COLOR_SELECTION_NEAREST_ENTRY &&
+            pasColorAssociation[i-1].dfVal != dfVal)
+        {
+            int index;
+            if (dfVal - pasColorAssociation[i-1].dfVal <
+                pasColorAssociation[i].dfVal - dfVal)
+                index = i -1;
+            else
+                index = i;
+
+            *pnR = pasColorAssociation[index].nR;
+            *pnG = pasColorAssociation[index].nG;
+            *pnB = pasColorAssociation[index].nB;
+            *pnA = pasColorAssociation[index].nA;
+            return TRUE;
+        }
+        
+        double dfRatio = (dfVal - pasColorAssociation[i-1].dfVal) /
+            (pasColorAssociation[i].dfVal - pasColorAssociation[i-1].dfVal);
+        *pnR = (int)(0.45 + pasColorAssociation[i-1].nR + dfRatio *
+                (pasColorAssociation[i].nR - pasColorAssociation[i-1].nR));
+        if (*pnR < 0) *pnR = 0;
+        else if (*pnR > 255) *pnR = 255;
+        *pnG = (int)(0.45 + pasColorAssociation[i-1].nG + dfRatio *
+                (pasColorAssociation[i].nG - pasColorAssociation[i-1].nG));
+        if (*pnG < 0) *pnG = 0;
+        else if (*pnG > 255) *pnG = 255;
+        *pnB = (int)(0.45 + pasColorAssociation[i-1].nB + dfRatio *
+                (pasColorAssociation[i].nB - pasColorAssociation[i-1].nB));
+        if (*pnB < 0) *pnB = 0;
+        else if (*pnB > 255) *pnB = 255;
+        *pnA = (int)(0.45 + pasColorAssociation[i-1].nA + dfRatio *
+                (pasColorAssociation[i].nA - pasColorAssociation[i-1].nA));
+        if (*pnA < 0) *pnA = 0;
+        else if (*pnA > 255) *pnA = 255;
+        
+        return TRUE;
+    }
+}
+
+/* dfPct : percentage between 0 and 1 */
+static double GDALColorReliefGetAbsoluteValFromPct(GDALRasterBandH hSrcBand,
+                                                   double dfPct)
+{
+    double dfMin, dfMax;
+    int bSuccessMin, bSuccessMax;
+    dfMin = GDALGetRasterMinimum(hSrcBand, &bSuccessMin);
+    dfMax = GDALGetRasterMaximum(hSrcBand, &bSuccessMax);
+    if (!bSuccessMin || !bSuccessMax)
+    {
+        double dfMean, dfStdDev;
+        fprintf(stderr, "Computing source raster statistics...\n");
+        GDALComputeRasterStatistics(hSrcBand, FALSE, &dfMin, &dfMax,
+                                    &dfMean, &dfStdDev, NULL, NULL);
+    }
+    return dfMin + dfPct * (dfMax - dfMin);
+}
+
+typedef struct
+{
+    const char *name;
+    float r, g, b;
+} NamedColor;
+
+static const NamedColor namedColors[] = {
+    { "white",  1.00, 1.00, 1.00 },
+    { "black",  0.00, 0.00, 0.00 },
+    { "red",    1.00, 0.00, 0.00 },
+    { "green",  0.00, 1.00, 0.00 },
+    { "blue",   0.00, 0.00, 1.00 },
+    { "yellow", 1.00, 1.00, 0.00 },
+    { "magenta",1.00, 0.00, 1.00 },
+    { "cyan",   0.00, 1.00, 1.00 },
+    { "aqua",   0.00, 0.75, 0.75 },
+    { "grey",   0.75, 0.75, 0.75 },
+    { "gray",   0.75, 0.75, 0.75 },
+    { "orange", 1.00, 0.50, 0.00 },
+    { "brown",  0.75, 0.50, 0.25 },
+    { "purple", 0.50, 0.00, 1.00 },
+    { "violet", 0.50, 0.00, 1.00 },
+    { "indigo", 0.00, 0.50, 1.00 },
+};
+
+static
+int GDALColorReliefFindNamedColor(const char *pszColorName, int *pnR, int *pnG, int *pnB)
+{
+    unsigned int i;
+
+    *pnR = *pnG = *pnB = 0;
+    for (i = 0; i < sizeof(namedColors) / sizeof(namedColors[0]); i++)
+    {
+        if (EQUAL(pszColorName, namedColors[i].name))
+        {
+            *pnR = (int)(255. * namedColors[i].r);
+            *pnG = (int)(255. * namedColors[i].g);
+            *pnB = (int)(255. * namedColors[i].b);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static
+ColorAssociation* GDALColorReliefParseColorFile(GDALRasterBandH hSrcBand,
+                                                const char* pszColorFilename,
+                                                int* pnColors)
+{
+    VSILFILE* fpColorFile = VSIFOpenL(pszColorFilename, "rt");
+    if (fpColorFile == NULL)
+    {
+        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find %s", pszColorFilename);
+        *pnColors = 0;
+        return NULL;
+    }
+
+    ColorAssociation* pasColorAssociation = NULL;
+    int nColorAssociation = 0;
+
+    int bSrcHasNoData = FALSE;
+    double dfSrcNoDataValue = GDALGetRasterNoDataValue(hSrcBand, &bSrcHasNoData);
+
+    const char* pszLine;
+    int bIsGMT_CPT = FALSE;
+    while ((pszLine = CPLReadLineL(fpColorFile)) != NULL)
+    {
+        if (pszLine[0] == '#' && strstr(pszLine, "COLOR_MODEL"))
+        {
+            if (strstr(pszLine, "COLOR_MODEL = RGB") == NULL)
+            {
+                CPLError(CE_Failure, CPLE_AppDefined, "Only COLOR_MODEL = RGB is supported");
+                CPLFree(pasColorAssociation);
+                *pnColors = 0;
+                return NULL;
+            }
+            bIsGMT_CPT = TRUE;
+        }
+
+        char** papszFields = CSLTokenizeStringComplex(pszLine, " ,\t:", 
+                                                      FALSE, FALSE );
+        /* Skip comment lines */
+        int nTokens = CSLCount(papszFields);
+        if (nTokens >= 1 && (papszFields[0][0] == '#' ||
+                             papszFields[0][0] == '/'))
+        {
+            CSLDestroy(papszFields);
+            continue;
+        }
+
+        if (bIsGMT_CPT && nTokens == 8)
+        {
+            pasColorAssociation =
+                    (ColorAssociation*)CPLRealloc(pasColorAssociation,
+                           (nColorAssociation + 2) * sizeof(ColorAssociation));
+
+            pasColorAssociation[nColorAssociation].dfVal = atof(papszFields[0]);
+            pasColorAssociation[nColorAssociation].nR = atoi(papszFields[1]);
+            pasColorAssociation[nColorAssociation].nG = atoi(papszFields[2]);
+            pasColorAssociation[nColorAssociation].nB = atoi(papszFields[3]);
+            pasColorAssociation[nColorAssociation].nA = 255;
+            nColorAssociation++;
+
+            pasColorAssociation[nColorAssociation].dfVal = atof(papszFields[4]);
+            pasColorAssociation[nColorAssociation].nR = atoi(papszFields[5]);
+            pasColorAssociation[nColorAssociation].nG = atoi(papszFields[6]);
+            pasColorAssociation[nColorAssociation].nB = atoi(papszFields[7]);
+            pasColorAssociation[nColorAssociation].nA = 255;
+            nColorAssociation++;
+        }
+        else if (bIsGMT_CPT && nTokens == 4)
+        {
+            /* The first token might be B (background), F (foreground) or N (nodata) */
+            /* Just interested in N */
+            if (EQUAL(papszFields[0], "N") && bSrcHasNoData)
+            {
+                 pasColorAssociation =
+                    (ColorAssociation*)CPLRealloc(pasColorAssociation,
+                           (nColorAssociation + 1) * sizeof(ColorAssociation));
+
+                pasColorAssociation[nColorAssociation].dfVal = dfSrcNoDataValue;
+                pasColorAssociation[nColorAssociation].nR = atoi(papszFields[1]);
+                pasColorAssociation[nColorAssociation].nG = atoi(papszFields[2]);
+                pasColorAssociation[nColorAssociation].nB = atoi(papszFields[3]);
+                pasColorAssociation[nColorAssociation].nA = 255;
+                nColorAssociation++;
+            }
+        }
+        else if (!bIsGMT_CPT && nTokens >= 2)
+        {
+            pasColorAssociation =
+                    (ColorAssociation*)CPLRealloc(pasColorAssociation,
+                           (nColorAssociation + 1) * sizeof(ColorAssociation));
+            if (EQUAL(papszFields[0], "nv") && bSrcHasNoData)
+                pasColorAssociation[nColorAssociation].dfVal = dfSrcNoDataValue;
+            else if (strlen(papszFields[0]) > 1 && papszFields[0][strlen(papszFields[0])-1] == '%')
+            {
+                double dfPct = atof(papszFields[0]) / 100.;
+                if (dfPct < 0.0 || dfPct > 1.0)
+                {
+                    CPLError(CE_Failure, CPLE_AppDefined,
+                             "Wrong value for a percentage : %s", papszFields[0]);
+                    CSLDestroy(papszFields);
+                    VSIFCloseL(fpColorFile);
+                    CPLFree(pasColorAssociation);
+                    *pnColors = 0;
+                    return NULL;
+                }
+                pasColorAssociation[nColorAssociation].dfVal =
+                        GDALColorReliefGetAbsoluteValFromPct(hSrcBand, dfPct);
+            }
+            else
+                pasColorAssociation[nColorAssociation].dfVal = atof(papszFields[0]);
+
+            if (nTokens >= 4)
+            {
+                pasColorAssociation[nColorAssociation].nR = atoi(papszFields[1]);
+                pasColorAssociation[nColorAssociation].nG = atoi(papszFields[2]);
+                pasColorAssociation[nColorAssociation].nB = atoi(papszFields[3]);
+                pasColorAssociation[nColorAssociation].nA =
+                        (CSLCount(papszFields) >= 5 ) ? atoi(papszFields[4]) : 255;
+            }
+            else
+            {
+                int nR, nG, nB;
+                if (!GDALColorReliefFindNamedColor(papszFields[1], &nR, &nG, &nB))
+                {
+                    CPLError(CE_Failure, CPLE_AppDefined,
+                             "Unknown color : %s", papszFields[1]);
+                    CSLDestroy(papszFields);
+                    VSIFCloseL(fpColorFile);
+                    CPLFree(pasColorAssociation);
+                    *pnColors = 0;
+                    return NULL;
+                }
+                pasColorAssociation[nColorAssociation].nR = nR;
+                pasColorAssociation[nColorAssociation].nG = nG;
+                pasColorAssociation[nColorAssociation].nB = nB;
+                            pasColorAssociation[nColorAssociation].nA =
+                    (CSLCount(papszFields) >= 3 ) ? atoi(papszFields[2]) : 255;
+            }
+
+            nColorAssociation ++;
+        }
+        CSLDestroy(papszFields);
+    }
+    VSIFCloseL(fpColorFile);
+
+    if (nColorAssociation == 0)
+    {
+        CPLError(CE_Failure, CPLE_AppDefined,
+                 "No color association found in %s", pszColorFilename);
+        *pnColors = 0;
+        return NULL;
+    }
+
+    qsort(pasColorAssociation, nColorAssociation,
+          sizeof(ColorAssociation), GDALColorReliefSortColors);
+
+    *pnColors = nColorAssociation;
+    return pasColorAssociation;
+}
+
+static
+GByte* GDALColorReliefPrecompute(GDALRasterBandH hSrcBand,
+                                 ColorAssociation* pasColorAssociation,
+                                 int nColorAssociation,
+                                 ColorSelectionMode eColorSelectionMode,
+                                 int* pnIndexOffset)
+{
+    GDALDataType eDT = GDALGetRasterDataType(hSrcBand);
+    GByte* pabyPrecomputed = NULL;
+    int nIndexOffset = (eDT == GDT_Int16) ? 32768 : 0;
+    *pnIndexOffset = nIndexOffset;
+    int nXSize = GDALGetRasterBandXSize(hSrcBand);
+    int nYSize = GDALGetRasterBandXSize(hSrcBand);
+    if (eDT == GDT_Byte ||
+        ((eDT == GDT_Int16 || eDT == GDT_UInt16) && nXSize * nYSize > 65536))
+    {
+        int iMax = (eDT == GDT_Byte) ? 256: 65536;
+        pabyPrecomputed = (GByte*) VSIMalloc(4 * iMax);
+        if (pabyPrecomputed)
+        {
+            int i;
+            for(i=0;i<iMax;i++)
+            {
+                int nR, nG, nB, nA;
+                GDALColorReliefGetRGBA  (pasColorAssociation,
+                                         nColorAssociation,
+                                         i - nIndexOffset,
+                                         eColorSelectionMode,
+                                         &nR, &nG, &nB, &nA);
+                pabyPrecomputed[4 * i] = (GByte) nR;
+                pabyPrecomputed[4 * i + 1] = (GByte) nG;
+                pabyPrecomputed[4 * i + 2] = (GByte) nB;
+                pabyPrecomputed[4 * i + 3] = (GByte) nA;
+            }
+        }
+    }
+    return pabyPrecomputed;
+}
+
+/************************************************************************/
+/* ==================================================================== */
+/*                       GDALColorReliefDataset                        */
+/* ==================================================================== */
+/************************************************************************/
+
+class GDALColorReliefRasterBand;
+
+class GDALColorReliefDataset : public GDALDataset
+{
+    friend class GDALColorReliefRasterBand;
+
+    GDALDatasetH       hSrcDS;
+    GDALRasterBandH    hSrcBand;
+    int                nColorAssociation;
+    ColorAssociation*  pasColorAssociation;
+    ColorSelectionMode eColorSelectionMode;
+    GByte*             pabyPrecomputed;
+    int                nIndexOffset;
+    float*             pafSourceBuf;
+    int*               panSourceBuf;
+    int                nCurBlockXOff;
+    int                nCurBlockYOff;
+
+  public:
+                        GDALColorReliefDataset(GDALDatasetH hSrcDS,
+                                            GDALRasterBandH hSrcBand,
+                                            const char* pszColorFilename,
+                                            ColorSelectionMode eColorSelectionMode,
+                                            int bAlpha);
+                       ~GDALColorReliefDataset();
+
+    CPLErr      GetGeoTransform( double * padfGeoTransform );
+    const char *GetProjectionRef();
+};
+
+/************************************************************************/
+/* ==================================================================== */
+/*                    GDALColorReliefRasterBand                       */
+/* ==================================================================== */
+/************************************************************************/
+
+class GDALColorReliefRasterBand : public GDALRasterBand
+{
+    friend class GDALColorReliefDataset;
+
+    
+  public:
+                 GDALColorReliefRasterBand( GDALColorReliefDataset *, int );
+    
+    virtual CPLErr          IReadBlock( int, int, void * );
+    virtual GDALColorInterp GetColorInterpretation();
+};
+
+GDALColorReliefDataset::GDALColorReliefDataset(
+                                     GDALDatasetH hSrcDS,
+                                     GDALRasterBandH hSrcBand,
+                                     const char* pszColorFilename,
+                                     ColorSelectionMode eColorSelectionMode,
+                                     int bAlpha)
+{
+    this->hSrcDS = hSrcDS;
+    this->hSrcBand = hSrcBand;
+    nColorAssociation = 0;
+    pasColorAssociation =
+            GDALColorReliefParseColorFile(hSrcBand, pszColorFilename,
+                                          &nColorAssociation);
+    this->eColorSelectionMode = eColorSelectionMode;
+    
+    nRasterXSize = GDALGetRasterXSize(hSrcDS);
+    nRasterYSize = GDALGetRasterYSize(hSrcDS);
+    
+    int nBlockXSize, nBlockYSize;
+    GDALGetBlockSize( hSrcBand, &nBlockXSize, &nBlockYSize);
+    
+    nIndexOffset = 0;
+    pabyPrecomputed =
+        GDALColorReliefPrecompute(hSrcBand,
+                                  pasColorAssociation,
+                                  nColorAssociation,
+                                  eColorSelectionMode,
+                                  &nIndexOffset);
+    
+    int i;
+    for(i=0;i<((bAlpha) ? 4 : 3);i++)
+    {
+        SetBand(i + 1, new GDALColorReliefRasterBand(this, i+1));
+    }
+    
+    pafSourceBuf = NULL;
+    panSourceBuf = NULL;
+    if (pabyPrecomputed)
+        panSourceBuf = (int *) CPLMalloc(sizeof(int)*nBlockXSize*nBlockYSize);
+    else
+        pafSourceBuf = (float *) CPLMalloc(sizeof(float)*nBlockXSize*nBlockYSize);
+    nCurBlockXOff = -1;
+    nCurBlockYOff = -1;
+}
+
+GDALColorReliefDataset::~GDALColorReliefDataset()
+{
+    CPLFree(pasColorAssociation);
+    CPLFree(pabyPrecomputed);
+    CPLFree(panSourceBuf);
+    CPLFree(pafSourceBuf);
+}
+
+CPLErr GDALColorReliefDataset::GetGeoTransform( double * padfGeoTransform )
+{
+    return GDALGetGeoTransform(hSrcDS, padfGeoTransform);
+}
+
+const char *GDALColorReliefDataset::GetProjectionRef()
+{
+    return GDALGetProjectionRef(hSrcDS);
+}
+
+GDALColorReliefRasterBand::GDALColorReliefRasterBand(
+                                    GDALColorReliefDataset * poDS, int nBand)
+{
+    this->poDS = poDS;
+    this->nBand = nBand;
+    eDataType = GDT_Byte;
+    GDALGetBlockSize( poDS->hSrcBand, &nBlockXSize, &nBlockYSize);
+}
+
+CPLErr GDALColorReliefRasterBand::IReadBlock( int nBlockXOff,
+                                              int nBlockYOff,
+                                              void *pImage )
+{
+    GDALColorReliefDataset * poGDS = (GDALColorReliefDataset *) poDS;
+    int nReqXSize, nReqYSize;
+
+    if ((nBlockXOff + 1) * nBlockXSize >= nRasterXSize)
+        nReqXSize = nRasterXSize - nBlockXOff * nBlockXSize;
+    else
+        nReqXSize = nBlockXSize;
+        
+    if ((nBlockYOff + 1) * nBlockYSize >= nRasterYSize)
+        nReqYSize = nRasterYSize - nBlockYOff * nBlockYSize;
+    else
+        nReqYSize = nBlockYSize;
+
+    if ( poGDS->nCurBlockXOff != nBlockXOff ||
+         poGDS->nCurBlockYOff != nBlockYOff )
+    {
+        poGDS->nCurBlockXOff = nBlockXOff;
+        poGDS->nCurBlockYOff = nBlockYOff;
+        
+        CPLErr eErr = GDALRasterIO( poGDS->hSrcBand,
+                            GF_Read,
+                            nBlockXOff * nBlockXSize,
+                            nBlockYOff * nBlockYSize,
+                            nReqXSize, nReqYSize,
+                            (poGDS->panSourceBuf) ?
+                                (void*) poGDS->panSourceBuf :
+                                (void* )poGDS->pafSourceBuf,
+                            nReqXSize, nReqYSize,
+                            (poGDS->panSourceBuf) ? GDT_Int32 : GDT_Float32,
+                            0, 0);
+        if (eErr != CE_None)
+        {
+            memset(pImage, 0, nBlockXSize * nBlockYSize);
+            return eErr;
+        }
+    }
+
+    int x, y, j = 0;
+    if (poGDS->panSourceBuf)
+    {
+        for( y = 0; y < nReqYSize; y++ )
+        {
+            for( x = 0; x < nReqXSize; x++ )
+            {
+                int nIndex = poGDS->panSourceBuf[j] + poGDS->nIndexOffset;
+                ((GByte*)pImage)[y * nBlockXSize + x] = poGDS->pabyPrecomputed[4*nIndex + nBand-1];
+                j++;
+            }
+        }
+    }
+    else
+    {
+        int anComponents[4];
+        for( y = 0; y < nReqYSize; y++ )
+        {
+            for( x = 0; x < nReqXSize; x++ )
+            {
+                GDALColorReliefGetRGBA  (poGDS->pasColorAssociation,
+                                        poGDS->nColorAssociation,
+                                        poGDS->pafSourceBuf[j],
+                                        poGDS->eColorSelectionMode,
+                                        &anComponents[0],
+                                        &anComponents[1],
+                                        &anComponents[2],
+                                        &anComponents[3]);
+                ((GByte*)pImage)[y * nBlockXSize + x] = (GByte) anComponents[nBand-1];
+                j++;
+            }
+        }
+    }
+    
+    return CE_None;
+}
+
+GDALColorInterp GDALColorReliefRasterBand::GetColorInterpretation()
+{
+    return (GDALColorInterp)(GCI_RedBand + nBand - 1);
+}
+
+
+CPLErr GDALColorRelief (GDALRasterBandH hSrcBand,
+                        GDALRasterBandH hDstBand1,
+                        GDALRasterBandH hDstBand2,
+                        GDALRasterBandH hDstBand3,
+                        GDALRasterBandH hDstBand4,
+                        const char* pszColorFilename,
+                        ColorSelectionMode eColorSelectionMode,
+                        GDALProgressFunc pfnProgress,
+                        void * pProgressData)
+{
+    CPLErr eErr;
+    
+    if (hSrcBand == NULL || hDstBand1 == NULL || hDstBand2 == NULL ||
+        hDstBand3 == NULL)
+        return CE_Failure;
+
+    int nColorAssociation = 0;
+    ColorAssociation* pasColorAssociation =
+            GDALColorReliefParseColorFile(hSrcBand, pszColorFilename,
+                                          &nColorAssociation);
+    if (pasColorAssociation == NULL)
+        return CE_Failure;
+
+    int nXSize = GDALGetRasterBandXSize(hSrcBand);
+    int nYSize = GDALGetRasterBandYSize(hSrcBand);
+
+    if (pfnProgress == NULL)
+        pfnProgress = GDALDummyProgress;
+        
+    int nR = 0, nG = 0, nB = 0, nA = 0;
+    
+/* -------------------------------------------------------------------- */
+/*      Precompute the map from values to RGBA quadruplets              */
+/*      for GDT_Byte, GDT_Int16 or GDT_UInt16                           */
+/* -------------------------------------------------------------------- */
+    int nIndexOffset = 0;
+    GByte* pabyPrecomputed =
+        GDALColorReliefPrecompute(hSrcBand,
+                                  pasColorAssociation,
+                                  nColorAssociation,
+                                  eColorSelectionMode,
+                                  &nIndexOffset);
+
+/* -------------------------------------------------------------------- */
+/*      Initialize progress counter.                                    */
+/* -------------------------------------------------------------------- */
+
+    float* pafSourceBuf = NULL;
+    int* panSourceBuf = NULL;
+    if (pabyPrecomputed)
+        panSourceBuf = (int *) CPLMalloc(sizeof(int)*nXSize);
+    else
+        pafSourceBuf = (float *) CPLMalloc(sizeof(float)*nXSize);
+    GByte* pabyDestBuf1  = (GByte*) CPLMalloc( 4 * nXSize );
+    GByte* pabyDestBuf2  =  pabyDestBuf1 + nXSize;
+    GByte* pabyDestBuf3  =  pabyDestBuf2 + nXSize;
+    GByte* pabyDestBuf4  =  pabyDestBuf3 + nXSize;
+    int i, j;
+
+    if( !pfnProgress( 0.0, NULL, pProgressData ) )
+    {
+        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+        eErr = CE_Failure;
+        goto end;
+    }
+
+    for ( i = 0; i < nYSize; i++)
+    {
+        /* Read source buffer */
+        eErr = GDALRasterIO(   hSrcBand,
+                        GF_Read,
+                        0, i,
+                        nXSize, 1,
+                        (panSourceBuf) ? (void*) panSourceBuf : (void* )pafSourceBuf,
+                        nXSize, 1,
+                        (panSourceBuf) ? GDT_Int32 : GDT_Float32,
+                        0, 0);
+        if (eErr != CE_None)
+            goto end;
+
+        if (panSourceBuf)
+        {
+            for ( j = 0; j < nXSize; j++)
+            {
+                int nIndex = panSourceBuf[j] + nIndexOffset;
+                pabyDestBuf1[j] = pabyPrecomputed[4 * nIndex];
+                pabyDestBuf2[j] = pabyPrecomputed[4 * nIndex + 1];
+                pabyDestBuf3[j] = pabyPrecomputed[4 * nIndex + 2];
+                pabyDestBuf4[j] = pabyPrecomputed[4 * nIndex + 3];
+            }
+        }
+        else
+        {
+            for ( j = 0; j < nXSize; j++)
+            {
+                GDALColorReliefGetRGBA  (pasColorAssociation,
+                                         nColorAssociation,
+                                         pafSourceBuf[j],
+                                         eColorSelectionMode,
+                                         &nR,
+                                         &nG,
+                                         &nB,
+                                         &nA);
+                pabyDestBuf1[j] = (GByte) nR;
+                pabyDestBuf2[j] = (GByte) nG;
+                pabyDestBuf3[j] = (GByte) nB;
+                pabyDestBuf4[j] = (GByte) nA;
+            }
+        }
+        
+        /* -----------------------------------------
+         * Write Line to Raster
+         */
+        eErr = GDALRasterIO(hDstBand1,
+                      GF_Write,
+                      0, i, nXSize,
+                      1, pabyDestBuf1, nXSize, 1, GDT_Byte, 0, 0);
+        if (eErr != CE_None)
+            goto end;
+
+        eErr = GDALRasterIO(hDstBand2,
+                      GF_Write,
+                      0, i, nXSize,
+                      1, pabyDestBuf2, nXSize, 1, GDT_Byte, 0, 0);
+        if (eErr != CE_None)
+            goto end;
+            
+        eErr = GDALRasterIO(hDstBand3,
+                      GF_Write,
+                      0, i, nXSize,
+                      1, pabyDestBuf3, nXSize, 1, GDT_Byte, 0, 0);
+        if (eErr != CE_None)
+            goto end;
+            
+        if (hDstBand4)
+        {
+            eErr = GDALRasterIO(hDstBand4,
+                        GF_Write,
+                        0, i, nXSize,
+                        1, pabyDestBuf4, nXSize, 1, GDT_Byte, 0, 0);
+            if (eErr != CE_None)
+                goto end;
+        }
+
+        if( !pfnProgress( 1.0 * (i+1) / nYSize, NULL, pProgressData ) )
+        {
+            CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+            eErr = CE_Failure;
+            goto end;
+        }
+    }
+    pfnProgress( 1.0, NULL, pProgressData );
+    eErr = CE_None;
+
+end:
+    VSIFree(pabyPrecomputed);
+    CPLFree(pafSourceBuf);
+    CPLFree(panSourceBuf);
+    CPLFree(pabyDestBuf1);
+    CPLFree(pasColorAssociation);
+
+    return eErr;
+}
+
+/************************************************************************/
+/*                     GDALGenerateVRTColorRelief()                     */
+/************************************************************************/
+
+CPLErr GDALGenerateVRTColorRelief(const char* pszDstFilename,
+                               GDALDatasetH hSrcDataset,
+                               GDALRasterBandH hSrcBand,
+                               const char* pszColorFilename,
+                               ColorSelectionMode eColorSelectionMode,
+                               int bAddAlpha)
+{
+
+    int nColorAssociation = 0;
+    ColorAssociation* pasColorAssociation =
+            GDALColorReliefParseColorFile(hSrcBand, pszColorFilename,
+                                          &nColorAssociation);
+    if (pasColorAssociation == NULL)
+        return CE_Failure;
+
+    int nXSize = GDALGetRasterBandXSize(hSrcBand);
+    int nYSize = GDALGetRasterBandYSize(hSrcBand);
+
+    VSILFILE* fp = VSIFOpenL(pszDstFilename, "wt");
+    if (fp == NULL)
+    {
+        CPLFree(pasColorAssociation);
+        return CE_Failure;
+    }
+
+    VSIFPrintfL(fp, "<VRTDataset rasterXSize=\"%d\" rasterYSize=\"%d\">\n", nXSize, nYSize);
+    const char* pszProjectionRef = GDALGetProjectionRef(hSrcDataset);
+    if (pszProjectionRef && pszProjectionRef[0] != '\0')
+    {
+        char* pszEscapedString = CPLEscapeString(pszProjectionRef, -1, CPLES_XML);
+        VSIFPrintfL(fp, "  <SRS>%s</SRS>\n", pszEscapedString);
+        VSIFree(pszEscapedString);
+    }
+    double adfGT[6];
+    if (GDALGetGeoTransform(hSrcDataset, adfGT) == CE_None)
+    {
+        VSIFPrintfL(fp, "  <GeoTransform> %.16g, %.16g, %.16g, "
+                        "%.16g, %.16g, %.16g</GeoTransform>\n",
+                        adfGT[0], adfGT[1], adfGT[2], adfGT[3], adfGT[4], adfGT[5]);
+    }
+    int nBands = 3 + (bAddAlpha ? 1 : 0);
+    int iBand;
+
+    int nBlockXSize, nBlockYSize;
+    GDALGetBlockSize(hSrcBand, &nBlockXSize, &nBlockYSize);
+    
+    int bRelativeToVRT;
+    CPLString osPath = CPLGetPath(pszDstFilename);
+    char* pszSourceFilename = CPLStrdup(
+        CPLExtractRelativePath( osPath.c_str(), GDALGetDescription(hSrcDataset), 
+                                &bRelativeToVRT ));
+
+    for(iBand = 0; iBand < nBands; iBand++)
+    {
+        VSIFPrintfL(fp, "  <VRTRasterBand dataType=\"Byte\" band=\"%d\">\n", iBand + 1);
+        VSIFPrintfL(fp, "    <ColorInterp>%s</ColorInterp>\n",
+                    GDALGetColorInterpretationName((GDALColorInterp)(GCI_RedBand + iBand)));
+        VSIFPrintfL(fp, "    <ComplexSource>\n");
+        VSIFPrintfL(fp, "      <SourceFilename relativeToVRT=\"%d\">%s</SourceFilename>\n",
+                        bRelativeToVRT, pszSourceFilename);
+        VSIFPrintfL(fp, "      <SourceBand>%d</SourceBand>\n", GDALGetBandNumber(hSrcBand));
+        VSIFPrintfL(fp, "      <SourceProperties RasterXSize=\"%d\" "
+                        "RasterYSize=\"%d\" DataType=\"%s\" "
+                        "BlockXSize=\"%d\" BlockYSize=\"%d\"/>\n",
+                        nXSize, nYSize,
+                        GDALGetDataTypeName(GDALGetRasterDataType(hSrcBand)),
+                        nBlockXSize, nBlockYSize);
+        VSIFPrintfL(fp, "      <SrcRect xOff=\"0\" yOff=\"0\" xSize=\"%d\" ySize=\"%d\"/>\n",
+                        nXSize, nYSize);
+        VSIFPrintfL(fp, "      <DstRect xOff=\"0\" yOff=\"0\" xSize=\"%d\" ySize=\"%d\"/>\n",
+                        nXSize, nYSize);
+
+        VSIFPrintfL(fp, "      <LUT>");
+        int iColor;
+#define EPSILON 1e-8
+        for(iColor=0;iColor<nColorAssociation;iColor++)
+        {
+            if (eColorSelectionMode == COLOR_SELECTION_NEAREST_ENTRY)
+            {
+                if (iColor > 1)
+                    VSIFPrintfL(fp, ",");
+            }
+            else if (iColor > 0)
+                VSIFPrintfL(fp, ",");
+
+            double dfVal = pasColorAssociation[iColor].dfVal;
+
+            if (eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY)
+            {
+                VSIFPrintfL(fp, "%.12g:0,", dfVal - EPSILON);
+            }
+            else if (iColor > 0 &&
+                     eColorSelectionMode == COLOR_SELECTION_NEAREST_ENTRY)
+            {
+                double dfMidVal = (dfVal + pasColorAssociation[iColor-1].dfVal) / 2;
+                VSIFPrintfL(fp, "%.12g:%d", dfMidVal - EPSILON,
+                        (iBand == 0) ? pasColorAssociation[iColor-1].nR :
+                        (iBand == 1) ? pasColorAssociation[iColor-1].nG :
+                        (iBand == 2) ? pasColorAssociation[iColor-1].nB :
+                                       pasColorAssociation[iColor-1].nA);
+                VSIFPrintfL(fp, ",%.12g:%d", dfMidVal ,
+                        (iBand == 0) ? pasColorAssociation[iColor].nR :
+                        (iBand == 1) ? pasColorAssociation[iColor].nG :
+                        (iBand == 2) ? pasColorAssociation[iColor].nB :
+                                       pasColorAssociation[iColor].nA);
+
+            }
+
+            if (eColorSelectionMode != COLOR_SELECTION_NEAREST_ENTRY)
+            {
+                if (dfVal != (double)(int)dfVal)
+                    VSIFPrintfL(fp, "%.12g", dfVal);
+                else
+                    VSIFPrintfL(fp, "%d", (int)dfVal);
+                VSIFPrintfL(fp, ":%d",
+                            (iBand == 0) ? pasColorAssociation[iColor].nR :
+                            (iBand == 1) ? pasColorAssociation[iColor].nG :
+                            (iBand == 2) ? pasColorAssociation[iColor].nB :
+                                           pasColorAssociation[iColor].nA);
+            }
+
+            if (eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY)
+            {
+                VSIFPrintfL(fp, ",%.12g:0", dfVal + EPSILON);
+            }
+
+        }
+        VSIFPrintfL(fp, "</LUT>\n");
+
+        VSIFPrintfL(fp, "    </ComplexSource>\n");
+        VSIFPrintfL(fp, "  </VRTRasterBand>\n");
+    }
+
+    CPLFree(pszSourceFilename);
+
+    VSIFPrintfL(fp, "</VRTDataset>\n");
+
+    VSIFCloseL(fp);
+
+    CPLFree(pasColorAssociation);
+
+    return CE_None;
+}
+
+
+/************************************************************************/
+/*                         GDALTRIAlg()                                 */
+/************************************************************************/
+
+float GDALTRIAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    // Terrain Ruggedness is average difference in height
+    return (fabs(afWin[0]-afWin[4]) +
+            fabs(afWin[1]-afWin[4]) +
+            fabs(afWin[2]-afWin[4]) +
+            fabs(afWin[3]-afWin[4]) +
+            fabs(afWin[5]-afWin[4]) +
+            fabs(afWin[6]-afWin[4]) +
+            fabs(afWin[7]-afWin[4]) +
+            fabs(afWin[8]-afWin[4]))/8;
+}
+
+
+/************************************************************************/
+/*                         GDALTPIAlg()                                 */
+/************************************************************************/
+
+float GDALTPIAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    // Terrain Position is the difference between
+    // The central cell and the mean of the surrounding cells
+    return afWin[4] - 
+            ((afWin[0]+
+              afWin[1]+
+              afWin[2]+
+              afWin[3]+
+              afWin[5]+
+              afWin[6]+
+              afWin[7]+
+              afWin[8])/8);
+}
+
+/************************************************************************/
+/*                     GDALRoughnessAlg()                               */
+/************************************************************************/
+
+float GDALRoughnessAlg (float* afWin, float fDstNoDataValue, void* pData)
+{
+    // Roughness is the largest difference
+    //  between any two cells
+
+    float pafRoughnessMin = afWin[0];
+    float pafRoughnessMax = afWin[0];
+
+    for ( int k = 1; k < 9; k++)
+    {
+        if (afWin[k] > pafRoughnessMax)
+        {
+            pafRoughnessMax=afWin[k];
+        }
+        if (afWin[k] < pafRoughnessMin)
+        {
+            pafRoughnessMin=afWin[k];
+        }
+    }
+    return pafRoughnessMax - pafRoughnessMin;
+}
+
+/************************************************************************/
+/* ==================================================================== */
+/*                       GDALGeneric3x3Dataset                        */
+/* ==================================================================== */
+/************************************************************************/
+
+class GDALGeneric3x3RasterBand;
+
+class GDALGeneric3x3Dataset : public GDALDataset
+{
+    friend class GDALGeneric3x3RasterBand;
+
+    GDALGeneric3x3ProcessingAlg pfnAlg;
+    void*              pAlgData;
+    GDALDatasetH       hSrcDS;
+    GDALRasterBandH    hSrcBand;
+    float*             apafSourceBuf[3];
+    int                bDstHasNoData;
+    double             dfDstNoDataValue;
+    int                nCurLine;
+    int                bComputeAtEdges;
+
+  public:
+                        GDALGeneric3x3Dataset(GDALDatasetH hSrcDS,
+                                              GDALRasterBandH hSrcBand,
+                                              GDALDataType eDstDataType,
+                                              int bDstHasNoData,
+                                              double dfDstNoDataValue,
+                                              GDALGeneric3x3ProcessingAlg pfnAlg,
+                                              void* pAlgData,
+                                              int bComputeAtEdges);
+                       ~GDALGeneric3x3Dataset();
+
+    CPLErr      GetGeoTransform( double * padfGeoTransform );
+    const char *GetProjectionRef();
+};
+
+/************************************************************************/
+/* ==================================================================== */
+/*                    GDALGeneric3x3RasterBand                       */
+/* ==================================================================== */
+/************************************************************************/
+
+class GDALGeneric3x3RasterBand : public GDALRasterBand
+{
+    friend class GDALGeneric3x3Dataset;
+    int bSrcHasNoData;
+    float fSrcNoDataValue;
+    
+    void                    InitWidthNoData(void* pImage);
+    
+  public:
+                 GDALGeneric3x3RasterBand( GDALGeneric3x3Dataset *poDS,
+                                           GDALDataType eDstDataType );
+    
+    virtual CPLErr          IReadBlock( int, int, void * );
+    virtual double          GetNoDataValue( int* pbHasNoData );
+};
+
+GDALGeneric3x3Dataset::GDALGeneric3x3Dataset(
+                                     GDALDatasetH hSrcDS,
+                                     GDALRasterBandH hSrcBand,
+                                     GDALDataType eDstDataType,
+                                     int bDstHasNoData,
+                                     double dfDstNoDataValue,
+                                     GDALGeneric3x3ProcessingAlg pfnAlg,
+                                     void* pAlgData,
+                                     int bComputeAtEdges)
+{
+    this->hSrcDS = hSrcDS;
+    this->hSrcBand = hSrcBand;
+    this->pfnAlg = pfnAlg;
+    this->pAlgData = pAlgData;
+    this->bDstHasNoData = bDstHasNoData;
+    this->dfDstNoDataValue = dfDstNoDataValue;
+    this->bComputeAtEdges = bComputeAtEdges;
+    
+    CPLAssert(eDstDataType == GDT_Byte || eDstDataType == GDT_Float32);
+
+    nRasterXSize = GDALGetRasterXSize(hSrcDS);
+    nRasterYSize = GDALGetRasterYSize(hSrcDS);
+    
+    SetBand(1, new GDALGeneric3x3RasterBand(this, eDstDataType));
+    
+    apafSourceBuf[0] = (float *) CPLMalloc(sizeof(float)*nRasterXSize);
+    apafSourceBuf[1] = (float *) CPLMalloc(sizeof(float)*nRasterXSize);
+    apafSourceBuf[2] = (float *) CPLMalloc(sizeof(float)*nRasterXSize);
+
+    nCurLine = -1;
+}
+
+GDALGeneric3x3Dataset::~GDALGeneric3x3Dataset()
+{
+    CPLFree(apafSourceBuf[0]);
+    CPLFree(apafSourceBuf[1]);
+    CPLFree(apafSourceBuf[2]);
+}
+
+CPLErr GDALGeneric3x3Dataset::GetGeoTransform( double * padfGeoTransform )
+{
+    return GDALGetGeoTransform(hSrcDS, padfGeoTransform);
+}
+
+const char *GDALGeneric3x3Dataset::GetProjectionRef()
+{
+    return GDALGetProjectionRef(hSrcDS);
+}
+
+GDALGeneric3x3RasterBand::GDALGeneric3x3RasterBand(GDALGeneric3x3Dataset *poDS,
+                                                   GDALDataType eDstDataType)
+{
+    this->poDS = poDS;
+    this->nBand = 1;
+    eDataType = eDstDataType;
+    nBlockXSize = poDS->GetRasterXSize();
+    nBlockYSize = 1;
+
+    bSrcHasNoData = FALSE;
+    fSrcNoDataValue = (float)GDALGetRasterNoDataValue(poDS->hSrcBand,
+                                                      &bSrcHasNoData);
+}
+
+void   GDALGeneric3x3RasterBand::InitWidthNoData(void* pImage)
+{
+    int j;
+    GDALGeneric3x3Dataset * poGDS = (GDALGeneric3x3Dataset *) poDS;
+    if (eDataType == GDT_Byte)
+    {
+        for(j=0;j<nBlockXSize;j++)
+            ((GByte*)pImage)[j] = (GByte) poGDS->dfDstNoDataValue;
+    }
+    else
+    {
+        for(j=0;j<nBlockXSize;j++)
+            ((float*)pImage)[j] = (float) poGDS->dfDstNoDataValue;
+    }
+}
+
+CPLErr GDALGeneric3x3RasterBand::IReadBlock( int nBlockXOff,
+                                             int nBlockYOff,
+                                             void *pImage )
+{
+    int i, j;
+    float fVal;
+    GDALGeneric3x3Dataset * poGDS = (GDALGeneric3x3Dataset *) poDS;
+
+    if (poGDS->bComputeAtEdges && nRasterXSize >= 2 && nRasterYSize >= 2)
+    {
+        if (nBlockYOff == 0)
+        {
+            for(i=0;i<2;i++)
+            {
+                CPLErr eErr = GDALRasterIO( poGDS->hSrcBand,
+                                    GF_Read,
+                                    0, i, nBlockXSize, 1,
+                                    poGDS->apafSourceBuf[i+1],
+                                    nBlockXSize, 1,
+                                    GDT_Float32,
+                                    0, 0);
+                if (eErr != CE_None)
+                {
+                    InitWidthNoData(pImage);
+                    return eErr;
+                }
+            }
+            poGDS->nCurLine = 0;
+
+            for (j = 0; j < nRasterXSize; j++)
+            {
+                float afWin[9];
+                int jmin = (j == 0) ? j : j - 1;
+                int jmax = (j == nRasterXSize - 1) ? j : j + 1;
+
+                afWin[0] = INTERPOL(poGDS->apafSourceBuf[1][jmin], poGDS->apafSourceBuf[2][jmin]);
+                afWin[1] = INTERPOL(poGDS->apafSourceBuf[1][j],    poGDS->apafSourceBuf[2][j]);
+                afWin[2] = INTERPOL(poGDS->apafSourceBuf[1][jmax], poGDS->apafSourceBuf[2][jmax]);
+                afWin[3] = poGDS->apafSourceBuf[1][jmin];
+                afWin[4] = poGDS->apafSourceBuf[1][j];
+                afWin[5] = poGDS->apafSourceBuf[1][jmax];
+                afWin[6] = poGDS->apafSourceBuf[2][jmin];
+                afWin[7] = poGDS->apafSourceBuf[2][j];
+                afWin[8] = poGDS->apafSourceBuf[2][jmax];
+
+                fVal = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                    afWin, (float) poGDS->dfDstNoDataValue,
+                                    poGDS->pfnAlg,
+                                    poGDS->pAlgData,
+                                    poGDS->bComputeAtEdges);
+
+                if (eDataType == GDT_Byte)
+                    ((GByte*)pImage)[j] = (GByte) (fVal + 0.5);
+                else
+                    ((float*)pImage)[j] = fVal;
+            }
+
+            return CE_None;
+        }
+        else if (nBlockYOff == nRasterYSize - 1)
+        {
+            if (poGDS->nCurLine != nRasterYSize - 2)
+            {
+                for(i=0;i<2;i++)
+                {
+                    CPLErr eErr = GDALRasterIO( poGDS->hSrcBand,
+                                        GF_Read,
+                                        0, nRasterYSize - 2 + i, nBlockXSize, 1,
+                                        poGDS->apafSourceBuf[i+1],
+                                        nBlockXSize, 1,
+                                        GDT_Float32,
+                                        0, 0);
+                    if (eErr != CE_None)
+                    {
+                        InitWidthNoData(pImage);
+                        return eErr;
+                    }
+                }
+            }
+
+            for (j = 0; j < nRasterXSize; j++)
+            {
+                float afWin[9];
+                int jmin = (j == 0) ? j : j - 1;
+                int jmax = (j == nRasterXSize - 1) ? j : j + 1;
+
+                afWin[0] = poGDS->apafSourceBuf[1][jmin];
+                afWin[1] = poGDS->apafSourceBuf[1][j];
+                afWin[2] = poGDS->apafSourceBuf[1][jmax];
+                afWin[3] = poGDS->apafSourceBuf[2][jmin];
+                afWin[4] = poGDS->apafSourceBuf[2][j];
+                afWin[5] = poGDS->apafSourceBuf[2][jmax];
+                afWin[6] = INTERPOL(poGDS->apafSourceBuf[2][jmin], poGDS->apafSourceBuf[1][jmin]);
+                afWin[7] = INTERPOL(poGDS->apafSourceBuf[2][j],    poGDS->apafSourceBuf[1][j]);
+                afWin[8] = INTERPOL(poGDS->apafSourceBuf[2][jmax], poGDS->apafSourceBuf[1][jmax]);
+
+                fVal = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                    afWin, (float) poGDS->dfDstNoDataValue,
+                                    poGDS->pfnAlg,
+                                    poGDS->pAlgData,
+                                    poGDS->bComputeAtEdges);
+
+                if (eDataType == GDT_Byte)
+                    ((GByte*)pImage)[j] = (GByte) (fVal + 0.5);
+                else
+                    ((float*)pImage)[j] = fVal;
+            }
+
+            return CE_None;
+        }
+    }
+    else if ( nBlockYOff == 0 || nBlockYOff == nRasterYSize - 1)
+    {
+        InitWidthNoData(pImage);
+        return CE_None;
+    }
+
+    if ( poGDS->nCurLine != nBlockYOff )
+    {
+        if (poGDS->nCurLine + 1 == nBlockYOff)
+        {
+            float* pafTmp =  poGDS->apafSourceBuf[0];
+            poGDS->apafSourceBuf[0] = poGDS->apafSourceBuf[1];
+            poGDS->apafSourceBuf[1] = poGDS->apafSourceBuf[2];
+            poGDS->apafSourceBuf[2] = pafTmp;
+
+            CPLErr eErr = GDALRasterIO( poGDS->hSrcBand,
+                                    GF_Read,
+                                    0, nBlockYOff + 1, nBlockXSize, 1,
+                                    poGDS->apafSourceBuf[2],
+                                    nBlockXSize, 1,
+                                    GDT_Float32,
+                                    0, 0);
+
+            if (eErr != CE_None)
+            {
+                InitWidthNoData(pImage);
+                return eErr;
+            }
+        }
+        else
+        {
+            for(i=0;i<3;i++)
+            {
+                CPLErr eErr = GDALRasterIO( poGDS->hSrcBand,
+                                    GF_Read,
+                                    0, nBlockYOff + i - 1, nBlockXSize, 1,
+                                    poGDS->apafSourceBuf[i],
+                                    nBlockXSize, 1,
+                                    GDT_Float32,
+                                    0, 0);
+                if (eErr != CE_None)
+                {
+                    InitWidthNoData(pImage);
+                    return eErr;
+                }
+            }
+        }
+
+        poGDS->nCurLine = nBlockYOff;
+    }
+
+    if (poGDS->bComputeAtEdges && nRasterXSize >= 2)
+    {
+        float afWin[9];
+
+        j = 0;
+        afWin[0] = INTERPOL(poGDS->apafSourceBuf[0][j], poGDS->apafSourceBuf[0][j+1]);
+        afWin[1] = poGDS->apafSourceBuf[0][j];
+        afWin[2] = poGDS->apafSourceBuf[0][j+1];
+        afWin[3] = INTERPOL(poGDS->apafSourceBuf[1][j], poGDS->apafSourceBuf[1][j+1]);
+        afWin[4] = poGDS->apafSourceBuf[1][j];
+        afWin[5] = poGDS->apafSourceBuf[1][j+1];
+        afWin[6] = INTERPOL(poGDS->apafSourceBuf[2][j], poGDS->apafSourceBuf[2][j+1]);
+        afWin[7] = poGDS->apafSourceBuf[2][j];
+        afWin[8] = poGDS->apafSourceBuf[2][j+1];
+
+        fVal = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                    afWin, (float) poGDS->dfDstNoDataValue,
+                                    poGDS->pfnAlg,
+                                    poGDS->pAlgData,
+                                    poGDS->bComputeAtEdges);
+
+        if (eDataType == GDT_Byte)
+            ((GByte*)pImage)[j] = (GByte) (fVal + 0.5);
+        else
+            ((float*)pImage)[j] = fVal;
+
+        j = nRasterXSize - 1;
+
+        afWin[0] = poGDS->apafSourceBuf[0][j-1];
+        afWin[1] = poGDS->apafSourceBuf[0][j];
+        afWin[2] = INTERPOL(poGDS->apafSourceBuf[0][j], poGDS->apafSourceBuf[0][j-1]);
+        afWin[3] = poGDS->apafSourceBuf[1][j-1];
+        afWin[4] = poGDS->apafSourceBuf[1][j];
+        afWin[5] = INTERPOL(poGDS->apafSourceBuf[1][j], poGDS->apafSourceBuf[1][j-1]);
+        afWin[6] = poGDS->apafSourceBuf[2][j-1];
+        afWin[7] = poGDS->apafSourceBuf[2][j];
+        afWin[8] = INTERPOL(poGDS->apafSourceBuf[2][j], poGDS->apafSourceBuf[2][j-1]);
+
+        fVal = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                    afWin, (float) poGDS->dfDstNoDataValue,
+                                    poGDS->pfnAlg,
+                                    poGDS->pAlgData,
+                                    poGDS->bComputeAtEdges);
+
+        if (eDataType == GDT_Byte)
+            ((GByte*)pImage)[j] = (GByte) (fVal + 0.5);
+        else
+            ((float*)pImage)[j] = fVal;
+    }
+    else
+    {
+        if (eDataType == GDT_Byte)
+        {
+            ((GByte*)pImage)[0] = (GByte) poGDS->dfDstNoDataValue;
+            if (nBlockXSize > 1)
+                ((GByte*)pImage)[nBlockXSize - 1] = (GByte) poGDS->dfDstNoDataValue;
+        }
+        else
+        {
+            ((float*)pImage)[0] = (float) poGDS->dfDstNoDataValue;
+            if (nBlockXSize > 1)
+                ((float*)pImage)[nBlockXSize - 1] = (float) poGDS->dfDstNoDataValue;
+        }
+    }
+
+
+    for(j=1;j<nBlockXSize - 1;j++)
+    {
+        float afWin[9];
+        afWin[0] = poGDS->apafSourceBuf[0][j-1];
+        afWin[1] = poGDS->apafSourceBuf[0][j];
+        afWin[2] = poGDS->apafSourceBuf[0][j+1];
+        afWin[3] = poGDS->apafSourceBuf[1][j-1];
+        afWin[4] = poGDS->apafSourceBuf[1][j];
+        afWin[5] = poGDS->apafSourceBuf[1][j+1];
+        afWin[6] = poGDS->apafSourceBuf[2][j-1];
+        afWin[7] = poGDS->apafSourceBuf[2][j];
+        afWin[8] = poGDS->apafSourceBuf[2][j+1];
+
+        fVal = ComputeVal(bSrcHasNoData, fSrcNoDataValue,
+                                afWin, (float) poGDS->dfDstNoDataValue,
+                                poGDS->pfnAlg,
+                                poGDS->pAlgData,
+                                poGDS->bComputeAtEdges);
+
+        if (eDataType == GDT_Byte)
+            ((GByte*)pImage)[j] = (GByte) (fVal + 0.5);
+        else
+            ((float*)pImage)[j] = fVal;
+
+    }
+
+    return CE_None;
+}
+
+double GDALGeneric3x3RasterBand::GetNoDataValue( int* pbHasNoData )
+{
+    GDALGeneric3x3Dataset * poGDS = (GDALGeneric3x3Dataset *) poDS;
+    if (pbHasNoData)
+        *pbHasNoData = poGDS->bDstHasNoData;
+    return poGDS->dfDstNoDataValue;
+}
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+
+typedef enum
+{
+    HILL_SHADE,
+    SLOPE,
+    ASPECT,
+    COLOR_RELIEF,
+    TRI,
+    TPI,
+    ROUGHNESS
+} Algorithm;
+
+#define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
+    do { if (i + nExtraArg >= argc) \
+        Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
+
+#ifndef ZOO_SERVICE
+int main( int argc, char ** argv )
+#else
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+  int Gdal_Dem(maps*& conf,maps*& inputs,maps*& outputs)
+#endif
+{
+    Algorithm eUtilityMode = HILL_SHADE;
+    double z = 1.0;
+    double scale = 1.0;
+    double az = 315.0;
+    double alt = 45.0;
+    // 0 = 'percent' or 1 = 'degrees'
+    int slopeFormat = 1; 
+    int bAddAlpha = FALSE;
+    int bZeroForFlat = FALSE;
+    int bAngleAsAzimuth = TRUE;
+    ColorSelectionMode eColorSelectionMode = COLOR_SELECTION_INTERPOLATE;
+    
+    int nBand = 1;
+    double  adfGeoTransform[6];
+
+    const char *pszSrcFilename = NULL;
+    const char *pszDstFilename = NULL;
+    const char *pszColorFilename = NULL;
+    const char *pszFormat = "GTiff";
+    int bFormatExplicitelySet = FALSE;
+    char **papszCreateOptions = NULL;
+    
+    GDALDatasetH hSrcDataset = NULL;
+    GDALDatasetH hDstDataset = NULL;
+    GDALRasterBandH hSrcBand = NULL;
+    GDALRasterBandH hDstBand = NULL;
+    GDALDriverH hDriver = NULL;
+
+    GDALProgressFunc pfnProgress = GDALTermProgress;
+    
+    int nXSize = 0;
+    int nYSize = 0;
+    
+    int bComputeAtEdges = FALSE;
+    int bZevenbergenThorne = FALSE;
+    int bCombined = FALSE;
+    int bQuiet = FALSE;
+    
+#ifndef ZOO_SERVICE
+    /* Check strict compilation and runtime library version as we use C++ API */
+    if (! GDAL_CHECK_VERSION(argv[0]))
+        exit(1);
+
+    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
+    if( argc < 2 )
+    {
+        Usage("Not enough arguments.");
+    }
+
+    if( EQUAL(argv[1], "--utility_version") || EQUAL(argv[1], "--utility-version") )
+    {
+        printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
+                argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
+        return 0;
+    }
+    else if( EQUAL(argv[1],"--help") )
+        Usage();
+    else if ( EQUAL(argv[1], "shade") || EQUAL(argv[1], "hillshade") )
+    {
+        eUtilityMode = HILL_SHADE;
+    }
+    else if ( EQUAL(argv[1], "slope") )
+    {
+        eUtilityMode = SLOPE;
+    }
+    else if ( EQUAL(argv[1], "aspect") )
+    {
+        eUtilityMode = ASPECT;
+    }
+    else if ( EQUAL(argv[1], "color-relief") )
+    {
+        eUtilityMode = COLOR_RELIEF;
+    }
+    else if ( EQUAL(argv[1], "TRI") )
+    {
+        eUtilityMode = TRI;
+    }
+    else if ( EQUAL(argv[1], "TPI") )
+    {
+        eUtilityMode = TPI;
+    }
+    else if ( EQUAL(argv[1], "roughness") )
+    {
+        eUtilityMode = ROUGHNESS;
+    }
+    else
+    {
+        Usage("Missing valid sub-utility mention.");
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse arguments.                                                */
+/* -------------------------------------------------------------------- */
+    for(int i = 2; i < argc; i++ )
+    {
+        if( eUtilityMode == HILL_SHADE &&
+            (EQUAL(argv[i], "--z") || EQUAL(argv[i], "-z")))
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            z = atof(argv[++i]);
+        }
+        else if ( eUtilityMode == SLOPE && EQUAL(argv[i], "-p"))
+        {
+            slopeFormat = 0;
+        }
+        else if ( (eUtilityMode == HILL_SHADE || eUtilityMode == SLOPE ||
+                   eUtilityMode == ASPECT) && EQUAL(argv[i], "-alg") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            i ++;
+            if (EQUAL(argv[i], "ZevenbergenThorne"))
+                bZevenbergenThorne = TRUE;
+            else if (!EQUAL(argv[i], "Horn"))
+            {
+                Usage(CPLSPrintf("Wrong value for alg : %s.", argv[i]));
+            }
+        }
+        else if ( eUtilityMode == ASPECT && EQUAL(argv[i], "-trigonometric"))
+        {
+            bAngleAsAzimuth = FALSE;
+        }
+        else if ( eUtilityMode == ASPECT && EQUAL(argv[i], "-zero_for_flat"))
+        {
+            bZeroForFlat = TRUE;
+        }
+        else if ( eUtilityMode == COLOR_RELIEF && EQUAL(argv[i], "-exact_color_entry"))
+        {
+            eColorSelectionMode = COLOR_SELECTION_EXACT_ENTRY;
+        }
+        else if ( eUtilityMode == COLOR_RELIEF && EQUAL(argv[i], "-nearest_color_entry"))
+        {
+            eColorSelectionMode = COLOR_SELECTION_NEAREST_ENTRY;
+        }
+        else if( 
+            (EQUAL(argv[i], "--s") || 
+             EQUAL(argv[i], "-s") ||
+             EQUAL(argv[i], "--scale") ||
+             EQUAL(argv[i], "-scale"))
+          )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            scale = atof(argv[++i]);
+        }
+        else if( eUtilityMode == HILL_SHADE &&
+            (EQUAL(argv[i], "--az") || 
+             EQUAL(argv[i], "-az") ||
+             EQUAL(argv[i], "--azimuth") ||
+             EQUAL(argv[i], "-azimuth"))
+          )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            az = atof(argv[++i]);
+        }
+        else if( eUtilityMode == HILL_SHADE &&
+            (EQUAL(argv[i], "--alt") || 
+             EQUAL(argv[i], "-alt") ||
+             EQUAL(argv[i], "--alt") ||
+             EQUAL(argv[i], "-alt"))
+          )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            alt = atof(argv[++i]);
+        }
+        else if( eUtilityMode == HILL_SHADE &&
+            (EQUAL(argv[i], "-combined") || 
+             EQUAL(argv[i], "--combined"))
+          )
+        {
+            bCombined = TRUE;
+        }
+        else if( eUtilityMode == COLOR_RELIEF &&
+                 EQUAL(argv[i], "-alpha"))
+        {
+            bAddAlpha = TRUE;
+        }
+        else if( eUtilityMode != COLOR_RELIEF &&
+                 EQUAL(argv[i], "-compute_edges"))
+        {
+            bComputeAtEdges = TRUE;
+        }
+        else if( i + 1 < argc &&
+            (EQUAL(argv[i], "--b") || 
+             EQUAL(argv[i], "-b"))
+          )
+        {
+            nBand = atoi(argv[++i]);
+        }
+        else if ( EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet") )
+        {
+            pfnProgress = GDALDummyProgress;
+            bQuiet = TRUE;
+        }
+        else if( EQUAL(argv[i],"-co") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
+        }
+        else if( EQUAL(argv[i],"-of") )
+        {
+            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
+            pszFormat = argv[++i];
+            bFormatExplicitelySet = TRUE;
+        }
+        else if( argv[i][0] == '-' )
+        {
+            Usage(CPLSPrintf("Unkown option name '%s'", argv[i]));
+        }
+        else if( pszSrcFilename == NULL )
+        {
+            pszSrcFilename = argv[i];
+        }
+        else if( eUtilityMode == COLOR_RELIEF && pszColorFilename == NULL )
+        {
+            pszColorFilename = argv[i];
+        }
+        else if( pszDstFilename == NULL )
+        {
+            pszDstFilename = argv[i];
+        }
+        else
+            Usage("Too many command options.");
+    }
+
+    if( pszSrcFilename == NULL )
+    {
+        Usage("Missing source.");
+    }
+    if ( eUtilityMode == COLOR_RELIEF && pszColorFilename == NULL )
+    {
+        Usage("Missing color file.");
+    }
+    if( pszDstFilename == NULL )
+    {
+        Usage("Missing destination.");
+    }
+#else
+    map* tmpMap=NULL;
+
+    pfnProgress = GDALDummyProgress;
+    bQuiet = TRUE;
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL){
+      pszSrcFilename=(char*)CPLMalloc(sizeof(char)*(strlen(tmpMap->value)+1));
+      sprintf((char*)pszSrcFilename,"%s",tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL){
+      pszDstFilename=(char*)CPLMalloc(sizeof(char)*(strlen(tmpMap->value)+1));
+      sprintf((char*)pszDstFilename,"%s",tmpMap->value);
+      setMapInMaps(outputs,"Result","value",tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"utility","value");
+    if(tmpMap!=NULL){
+      if ( EQUAL(tmpMap->value, "shade") || EQUAL(tmpMap->value, "hillshade") )
+	{
+	  eUtilityMode = HILL_SHADE;
+	  map* tmpMap1=getMapFromMaps(inputs,"z","value");
+	  if(tmpMap1==NULL)
+	    return Usage(conf,"Unable to parse your z value");
+	  z = atof(tmpMap1->value);
+
+	  tmpMap1=getMapFromMaps(inputs,"az","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"NULL")!=0 )
+	    az = atof(tmpMap1->value);
+
+	  tmpMap1=getMapFromMaps(inputs,"alt","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"NULL")!=0 )
+	    alt = atof(tmpMap1->value);
+
+	  tmpMap1=getMapFromMaps(inputs,"c","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0 )	  
+	    bCombined = TRUE;
+	}
+      else if ( EQUAL(tmpMap->value, "slope") )
+	{
+	  eUtilityMode = SLOPE;
+	  map* tmpMap1=getMapFromMaps(inputs,"p","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0)
+	    slopeFormat = 0;
+	}
+      else if ( EQUAL(tmpMap->value, "aspect") )
+	{
+	  eUtilityMode = ASPECT;
+	  map* tmpMap1=getMapFromMaps(inputs,"ece","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0)
+            eColorSelectionMode = COLOR_SELECTION_EXACT_ENTRY;
+	  tmpMap1=getMapFromMaps(inputs,"nce","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0)
+            eColorSelectionMode = COLOR_SELECTION_NEAREST_ENTRY;
+	}
+      else if ( EQUAL(tmpMap->value, "color-relief") )
+	{
+	  eUtilityMode = COLOR_RELIEF;
+	  map* tmpMap1=getMapFromMaps(inputs,"cfn","value");
+	  if(tmpMap!=NULL){
+	    pszColorFilename=strdup(tmpMap1->value);
+	  } 
+	  tmpMap1=getMapFromMaps(inputs,"a","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0)	  
+	    bAddAlpha = TRUE;
+	  tmpMap1=getMapFromMaps(inputs,"ce","value");
+	  if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"true")==0)	  
+	    bComputeAtEdges = TRUE;
+	}
+      else if ( EQUAL(tmpMap->value, "TRI") )
+	{
+	  eUtilityMode = TRI;
+	}
+      else if ( EQUAL(tmpMap->value, "TPI") )
+	{
+	  eUtilityMode = TPI;
+	}
+      else if ( EQUAL(tmpMap->value, "roughness") )
+	{
+	  eUtilityMode = ROUGHNESS;
+	}
+      else
+	{
+	  return Usage(conf,"Missing valid utility mention.");
+	}
+    }
+    map* tmpMap1=getMapFromMaps(inputs,"s","value");
+    if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"NULL")!=0 )
+      scale = atof(tmpMap1->value);
+    tmpMap1=getMapFromMaps(inputs,"b","value");
+    if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"NULL")!=0 )
+      nBand = atoi(tmpMap1->value);
+
+    if( pszSrcFilename == NULL )
+    {
+      return Usage(conf,"Missing source.");
+    }
+    if ( eUtilityMode == COLOR_RELIEF && pszColorFilename == NULL )
+    {
+      return Usage(conf,"Missing color file.");
+    }
+    if( pszDstFilename == NULL )
+    {
+      return Usage(conf,"Missing destination.");
+    }
+#endif
+
+    GDALAllRegister();
+
+    // Open Dataset and get raster band
+    hSrcDataset = GDALOpen( pszSrcFilename, GA_ReadOnly );
+    
+    if( hSrcDataset == NULL )
+    {
+        fprintf( stderr,
+                 "GDALOpen failed - %d\n%s\n",
+                 CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
+        GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+	char *tmp=(char*)malloc(1024*sizeof(char));
+	sprintf(tmp,"GDALOpen failed - %d\n%s\n",
+                 CPLGetLastErrorNo(), CPLGetLastErrorMsg());
+	return Usage(conf,"GDALOpen failed");
+#else
+        exit( 1 );
+#endif
+    }
+
+    nXSize = GDALGetRasterXSize(hSrcDataset);
+    nYSize = GDALGetRasterYSize(hSrcDataset);
+
+    if( nBand <= 0 || nBand > GDALGetRasterCount(hSrcDataset) )
+    {
+        fprintf( stderr,
+                 "Unable to fetch band #%d\n", nBand );
+        GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+	char *tmp=(char*)malloc(128*sizeof(char));
+	sprintf(tmp,"Unable to fetch band #%d\n", nBand );
+	return Usage(conf,tmp);
+#else
+        exit( 1 );
+#endif
+    }
+    hSrcBand = GDALGetRasterBand( hSrcDataset, nBand );
+
+    GDALGetGeoTransform(hSrcDataset, adfGeoTransform);
+
+    hDriver = GDALGetDriverByName(pszFormat);
+    if( hDriver == NULL 
+        || (GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL &&
+            GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) == NULL))
+    {
+        int	iDr;
+
+        fprintf( stderr, "Output driver `%s' not recognised to have\n", 
+                 pszFormat );
+        fprintf( stderr, "output support.  The following format drivers are configured\n"
+                "and support output:\n" );
+
+        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
+        {
+            GDALDriverH hDriver = GDALGetDriver(iDr);
+
+            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL ||
+                GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL )
+            {
+                printf( "  %s: %s\n",
+                        GDALGetDriverShortName( hDriver  ),
+                        GDALGetDriverLongName( hDriver ) );
+            }
+        }
+        GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+	return Usage(conf,"Output driver not recognised to have output support.");
+#else
+        exit( 1 );
+#endif
+    }
+
+#ifndef ZOO_SERVICE
+    if (!bQuiet && !bFormatExplicitelySet)
+        CheckExtensionConsistency(pszDstFilename, pszFormat);
+#endif
+
+    double dfDstNoDataValue = 0;
+    int bDstHasNoData = FALSE;
+    void* pData = NULL;
+    GDALGeneric3x3ProcessingAlg pfnAlg = NULL;
+
+    if (eUtilityMode == HILL_SHADE)
+    {
+        dfDstNoDataValue = 0;
+        bDstHasNoData = TRUE;
+        pData = GDALCreateHillshadeData   (adfGeoTransform,
+                                           z,
+                                           scale,
+                                           alt,
+                                           az,
+                                           bZevenbergenThorne);
+        if (bZevenbergenThorne)
+        {
+            if(!bCombined)
+                pfnAlg = GDALHillshadeZevenbergenThorneAlg;
+            else
+                pfnAlg = GDALHillshadeZevenbergenThorneCombinedAlg;
+        }
+        else
+        {
+            if(!bCombined)
+                pfnAlg = GDALHillshadeAlg;
+            else
+                pfnAlg = GDALHillshadeCombinedAlg;
+        }
+    }
+    else if (eUtilityMode == SLOPE)
+    {
+        dfDstNoDataValue = -9999;
+        bDstHasNoData = TRUE;
+
+        pData = GDALCreateSlopeData(adfGeoTransform, scale, slopeFormat);
+        if (bZevenbergenThorne)
+            pfnAlg = GDALSlopeZevenbergenThorneAlg;
+        else
+            pfnAlg = GDALSlopeHornAlg;
+    }
+
+    else if (eUtilityMode == ASPECT)
+    {
+        if (!bZeroForFlat)
+        {
+            dfDstNoDataValue = -9999;
+            bDstHasNoData = TRUE;
+        }
+
+        pData = GDALCreateAspectData(bAngleAsAzimuth);
+        if (bZevenbergenThorne)
+            pfnAlg = GDALAspectZevenbergenThorneAlg;
+        else
+            pfnAlg = GDALAspectAlg;
+    }
+    else if (eUtilityMode == TRI)
+    {
+        dfDstNoDataValue = -9999;
+        bDstHasNoData = TRUE;
+        pfnAlg = GDALTRIAlg;
+    }
+    else if (eUtilityMode == TPI)
+    {
+        dfDstNoDataValue = -9999;
+        bDstHasNoData = TRUE;
+        pfnAlg = GDALTPIAlg;
+    }
+    else if (eUtilityMode == ROUGHNESS)
+    {
+        dfDstNoDataValue = -9999;
+        bDstHasNoData = TRUE;
+        pfnAlg = GDALRoughnessAlg;
+    }
+    
+    GDALDataType eDstDataType = (eUtilityMode == HILL_SHADE ||
+                                 eUtilityMode == COLOR_RELIEF) ? GDT_Byte :
+                                                               GDT_Float32;
+
+    if( EQUAL(pszFormat, "VRT") )
+    {
+        if (eUtilityMode == COLOR_RELIEF)
+        {
+            GDALGenerateVRTColorRelief(pszDstFilename,
+                                       hSrcDataset,
+                                       hSrcBand,
+                                       pszColorFilename,
+                                       eColorSelectionMode,
+                                       bAddAlpha);
+            GDALClose(hSrcDataset);
+        
+            CPLFree(pData);
+
+            GDALDestroyDriverManager();
+#ifndef ZOO_SERVICE
+            CSLDestroy( argv );
+#endif
+            CSLDestroy( papszCreateOptions );    
+#ifdef ZOO_SERVICE
+	    return SERVICE_SUCCEEDED;
+#else
+            return 0;
+#endif
+        }
+        else
+        {
+            fprintf(stderr, "VRT driver can only be used with color-relief utility\n");
+            GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+	    return Usage(conf,"VRT driver can only be used with color-relief utility");
+#else
+            exit(1);
+#endif
+        }
+    }
+    
+    if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL &&
+        GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL)
+    {
+        GDALDatasetH hIntermediateDataset;
+        
+        if (eUtilityMode == COLOR_RELIEF)
+            hIntermediateDataset = (GDALDatasetH)
+                new GDALColorReliefDataset (hSrcDataset,
+                                            hSrcBand,
+                                            pszColorFilename,
+                                            eColorSelectionMode,
+                                            bAddAlpha);
+        else
+            hIntermediateDataset = (GDALDatasetH)
+                new GDALGeneric3x3Dataset(hSrcDataset, hSrcBand,
+                                          eDstDataType,
+                                          bDstHasNoData,
+                                          dfDstNoDataValue,
+                                          pfnAlg,
+                                          pData,
+                                          bComputeAtEdges);
+
+        GDALDatasetH hOutDS = GDALCreateCopy(
+                                 hDriver, pszDstFilename, hIntermediateDataset, 
+                                 TRUE, papszCreateOptions, 
+                                 pfnProgress, NULL );
+
+        if( hOutDS != NULL )
+            GDALClose( hOutDS );
+        GDALClose(hIntermediateDataset);
+        GDALClose(hSrcDataset);
+        
+        CPLFree(pData);
+
+        GDALDestroyDriverManager();
+#ifndef ZOO_SERVICE
+        CSLDestroy( argv );
+#endif
+        CSLDestroy( papszCreateOptions );
+        
+#ifdef ZOO_SERVICE
+	return SERVICE_SUCCEEDED;
+#else
+        return 0;
+#endif
+    }
+
+    int nDstBands;
+    if (eUtilityMode == COLOR_RELIEF)
+        nDstBands = (bAddAlpha) ? 4 : 3;
+    else
+        nDstBands = 1;
+
+    hDstDataset = GDALCreate(   hDriver,
+                                pszDstFilename,
+                                nXSize,
+                                nYSize,
+                                nDstBands,
+                                eDstDataType,
+                                papszCreateOptions);
+
+    if( hDstDataset == NULL )
+    {
+        fprintf( stderr,
+                 "Unable to create dataset %s %d\n%s\n", pszDstFilename,
+                 CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
+        GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+	char *tmp=(char*)malloc(1024*sizeof(char));
+        sprintf( tmp,
+                 "Unable to create dataset %s %d\n%s\n", pszDstFilename,
+                 CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
+	return Usage(conf,tmp);
+#else
+        exit( 1 );
+#endif
+    }
+    
+    hDstBand = GDALGetRasterBand( hDstDataset, 1 );
+
+    GDALSetGeoTransform(hDstDataset, adfGeoTransform);
+    GDALSetProjection(hDstDataset, GDALGetProjectionRef(hSrcDataset));
+    
+    if (eUtilityMode == COLOR_RELIEF)
+    {
+        GDALColorRelief (hSrcBand, 
+                         GDALGetRasterBand(hDstDataset, 1),
+                         GDALGetRasterBand(hDstDataset, 2),
+                         GDALGetRasterBand(hDstDataset, 3),
+                         (bAddAlpha) ? GDALGetRasterBand(hDstDataset, 4) : NULL,
+                         pszColorFilename,
+                         eColorSelectionMode,
+                         pfnProgress, NULL);
+    }
+    else
+    {
+        if (bDstHasNoData)
+            GDALSetRasterNoDataValue(hDstBand, dfDstNoDataValue);
+        
+        GDALGeneric3x3Processing(hSrcBand, hDstBand,
+                                 pfnAlg, pData,
+                                 bComputeAtEdges,
+                                 pfnProgress, NULL);
+                                    
+    }
+
+    GDALClose(hSrcDataset);
+    GDALClose(hDstDataset);
+    CPLFree(pData);
+
+    GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+    CSLDestroy( papszCreateOptions );
+    return SERVICE_SUCCEEDED;
+#else
+    CSLDestroy( argv );
+    CSLDestroy( papszCreateOptions );
+    return 0;
+#endif
+
+}
+
+#ifdef ZOO_SERVICE
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/Makefile	(revision 672)
@@ -0,0 +1,15 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/service.zo: service.c
+	g++  -DZOO_SERVICE ${CFLAGS} -shared -fpic -o cgi-env/gdal_grid_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/gdal/grid
+	install cgi-env/* ${CGI_DIR}/gdal/grid
+
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/cgi-env/Gdal_Grid.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/cgi-env/Gdal_Grid.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/cgi-env/Gdal_Grid.zcfg	(revision 672)
@@ -0,0 +1,69 @@
+[Gdal_Grid]
+ Title =  Computes a regular grid (raster) from scattered data read from a vector data source. 
+ Abstract = http://www.gdal.org/gdal_grid.html
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = gdal_grid_service.zo
+ <MetaData>
+   title = My Demo
+ </MetaData>
+ <DataInputs>
+  [OF]
+   Title = Format of the output data
+   Abstract = Select the output format.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value = AAIGrid
+    </Default>
+    <Supported>
+     value = AAIGrid
+    </Supported>
+   </LiteralData>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     uom = feet
+    </Default>	
+    <Supported>
+     value = AAIGrid
+    </Supported>
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     uom = feet
+    </Default>	
+    <Supported>
+     value = AAIGrid
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [OutputedDataSourceName]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+     uom = feet
+    </Default>	
+    <Supported>
+     value = AAIGrid
+    </Supported>
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/grid/service.c	(revision 672)
@@ -0,0 +1,1258 @@
+/* ****************************************************************************
+ * $Id: gdal_grid.cpp 15053 2008-07-27 17:29:27Z rouault $
+ *
+ * Project:  GDAL Utilities
+ * Purpose:  GDAL scattered data gridding (interpolation) tool
+ * Author:   Andrey Kiselev, dron@ak4719.spb.edu
+ *
+ * ****************************************************************************
+ * Copyright (c) 2007, Andrey Kiselev <dron@ak4719.spb.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include <vector>
+#include <algorithm>
+
+#include "cpl_string.h"
+#include "gdal.h"
+#include "gdal_alg.h"
+#include "ogr_spatialref.h"
+#include "ogr_api.h"
+
+#ifdef ZOO_SERVICE
+#include "service.h"
+#endif
+
+CPL_CVSID("$Id: gdal_grid.cpp 15053 2008-07-27 17:29:27Z rouault $");
+
+#ifdef ZOO_SERVICE
+extern "C" {
+#endif
+
+static const char szAlgNameInvDist[] = "invdist";
+static const char szAlgNameAverage[] = "average";
+static const char szAlgNameNearest[] = "nearest";
+static const char szAlgNameMinimum[] = "minimum";
+static const char szAlgNameMaximum[] = "maximum";
+static const char szAlgNameRange[] = "range";
+
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage()
+{
+#ifdef ZOO_SERVICE
+  fprintf(stderr,
+#else
+    printf( 
+#endif
+        "Usage: gdal_grid [--help-general] [--formats]\n"
+        "    [-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/\n"
+        "          CInt16/CInt32/CFloat32/CFloat64}]\n"
+        "    [-of format] [-co \"NAME=VALUE\"]\n"
+        "    [-zfield field_name]\n"
+        "    [-a_srs srs_def] [-spat xmin ymin xmax ymax]\n"
+        "    [-l layername]* [-where expression] [-sql select_statement]\n"
+        "    [-txe xmin xmax] [-tye ymin ymax] [-outsize xsize ysize]\n"
+        "    [-a algorithm[:parameter1=value1]*]"
+        "    [-quiet]\n"
+        "    <src_datasource> <dst_filename>\n"
+        "\n"
+        "Available algorithms and parameters with their defaults:\n"
+        "    Inverse distance to a power (default)\n"
+        "        invdist:power=2.0:smoothing=0.0:radius1=0.0:radius2=0.0:angle=0.0:max_points=0:min_points=0:nodata=0.0\n"
+        "    Moving average\n"
+        "        average:radius1=0.0:radius2=0.0:angle=0.0:min_points=0:nodata=0.0\n"
+        "    Nearest neighbor\n"
+        "        nearest:radius1=0.0:radius2=0.0:angle=0.0:nodata=0.0\n"
+        "    Various data metrics\n"
+        "        <metric name>:radius1=0.0:radius2=0.0:angle=0.0:min_points=0:nodata=0.0\n"
+        "        possible metrics are:\n"
+        "            minimum\n"
+        "            maximum\n"
+        "            range\n"
+        "\n");
+#ifndef ZOO_SERVICE
+    exit( 1 );
+#endif
+}
+
+/************************************************************************/
+/*                          GetAlgorithmName()                          */
+/*                                                                      */
+/*      Translates algortihm code into mnemonic name.                   */
+/************************************************************************/
+
+void PrintAlgorithmAndOptions(GDALGridAlgorithm eAlgorithm, void *pOptions)
+{
+    switch ( eAlgorithm )
+    {
+        case GGA_InverseDistanceToAPower:
+
+#ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+		   "Algorithm name: \"%s\".\n", szAlgNameInvDist );
+#ifdef ZOO_SERVICE
+		fprintf(stderr,
+#else
+			  printf( 
+#endif
+				 "Options are "
+				 "\"power=%f:smoothing=%f:radius1=%f:radius2=%f:angle=%f"
+                    ":max_points=%lu:min_points=%lu:nodata=%f\"\n",
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfPower,
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfSmoothing,
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfRadius1,
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfRadius2,
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfAngle,
+                (unsigned long)((GDALGridInverseDistanceToAPowerOptions *)pOptions)->nMaxPoints,
+                (unsigned long)((GDALGridInverseDistanceToAPowerOptions *)pOptions)->nMinPoints,
+                ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfNoDataValue);
+            break;
+        case GGA_MovingAverage:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm name: \"%s\".\n", szAlgNameAverage );
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Options are "
+                    "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
+                    ":nodata=%f\"\n",
+                ((GDALGridMovingAverageOptions *)pOptions)->dfRadius1,
+                ((GDALGridMovingAverageOptions *)pOptions)->dfRadius2,
+                ((GDALGridMovingAverageOptions *)pOptions)->dfAngle,
+                (unsigned long)((GDALGridMovingAverageOptions *)pOptions)->nMinPoints,
+                ((GDALGridMovingAverageOptions *)pOptions)->dfNoDataValue);
+            break;
+        case GGA_NearestNeighbor:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm name: \"%s\".\n", szAlgNameNearest );
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Options are "
+                    "\"radius1=%f:radius2=%f:angle=%f:nodata=%f\"\n",
+                ((GDALGridNearestNeighborOptions *)pOptions)->dfRadius1,
+                ((GDALGridNearestNeighborOptions *)pOptions)->dfRadius2,
+                ((GDALGridNearestNeighborOptions *)pOptions)->dfAngle,
+                ((GDALGridNearestNeighborOptions *)pOptions)->dfNoDataValue);
+            break;
+        case GGA_MetricMinimum:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm name: \"%s\".\n", szAlgNameMinimum );
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Options are "
+                    "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
+                    ":nodata=%f\"\n",
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
+                (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
+            break;
+        case GGA_MetricMaximum:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm name: \"%s\".\n", szAlgNameMaximum );
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Options are "
+                    "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
+                    ":nodata=%f\"\n",
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
+                (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
+            break;
+        case GGA_MetricRange:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm name: \"%s\".\n", szAlgNameRange );
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Options are "
+                    "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
+                    ":nodata=%f\"\n",
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
+                (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
+                ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
+            break;
+        default:
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Algorithm unknown.\n" );
+            break;
+    }
+}
+
+/************************************************************************/
+/*                      ParseAlgorithmAndOptions()                      */
+/*                                                                      */
+/*      Translates mnemonic gridding algorithm names into               */
+/*      GDALGridAlgorithm code, parse control parameters and assign     */
+/*      defaults.                                                       */
+/************************************************************************/
+
+static CPLErr ParseAlgorithmAndOptions( const char *pszAlgoritm,
+                                        GDALGridAlgorithm *peAlgorithm,
+                                        void **ppOptions )
+{
+    char **papszParms = CSLTokenizeString2( pszAlgoritm, ":", FALSE );
+
+    if ( CSLCount(papszParms) < 1 )
+        return CE_Failure;
+
+    if ( EQUAL(papszParms[0], szAlgNameInvDist) )
+        *peAlgorithm = GGA_InverseDistanceToAPower;
+    else if ( EQUAL(papszParms[0], szAlgNameAverage) )
+        *peAlgorithm = GGA_MovingAverage;
+    else if ( EQUAL(papszParms[0], szAlgNameNearest) )
+        *peAlgorithm = GGA_NearestNeighbor;
+    else if ( EQUAL(papszParms[0], szAlgNameMinimum) )
+        *peAlgorithm = GGA_MetricMinimum;
+    else if ( EQUAL(papszParms[0], szAlgNameMaximum) )
+        *peAlgorithm = GGA_MetricMaximum;
+    else if ( EQUAL(papszParms[0], szAlgNameRange) )
+        *peAlgorithm = GGA_MetricRange;
+    else
+    {
+        fprintf( stderr, "Unsupported gridding method \"%s\".\n",
+                 papszParms[0] );
+        CSLDestroy( papszParms );
+        return CE_Failure;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse algorithm parameters and assign defaults.                 */
+/* -------------------------------------------------------------------- */
+    const char  *pszValue;
+
+    switch ( *peAlgorithm )
+    {
+        case GGA_InverseDistanceToAPower:
+        default:
+            *ppOptions =
+                CPLMalloc( sizeof(GDALGridInverseDistanceToAPowerOptions) );
+
+            pszValue = CSLFetchNameValue( papszParms, "power" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfPower = (pszValue) ? atof(pszValue) : 2.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "smoothing" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfSmoothing = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "radius1" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfRadius1 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "radius2" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfRadius2 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "angle" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfAngle = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "max_points" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                nMaxPoints = (pszValue) ? atol(pszValue) : 0;
+
+            pszValue = CSLFetchNameValue( papszParms, "min_points" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                nMinPoints = (pszValue) ? atol(pszValue) : 0;
+
+            pszValue = CSLFetchNameValue( papszParms, "nodata" );
+            ((GDALGridInverseDistanceToAPowerOptions *)*ppOptions)->
+                dfNoDataValue = (pszValue) ? atof(pszValue) : 0.0;
+            break;
+
+        case GGA_MovingAverage:
+            *ppOptions =
+                CPLMalloc( sizeof(GDALGridMovingAverageOptions) );
+
+            pszValue = CSLFetchNameValue( papszParms, "radius1" );
+            ((GDALGridMovingAverageOptions *)*ppOptions)->
+                dfRadius1 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "radius2" );
+            ((GDALGridMovingAverageOptions *)*ppOptions)->
+                dfRadius2 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "angle" );
+            ((GDALGridMovingAverageOptions *)*ppOptions)->
+                dfAngle = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "min_points" );
+            ((GDALGridMovingAverageOptions *)*ppOptions)->
+                nMinPoints = (pszValue) ? atol(pszValue) : 0;
+
+            pszValue = CSLFetchNameValue( papszParms, "nodata" );
+            ((GDALGridMovingAverageOptions *)*ppOptions)->
+                dfNoDataValue = (pszValue) ? atof(pszValue) : 0.0;
+            break;
+
+        case GGA_NearestNeighbor:
+            *ppOptions =
+                CPLMalloc( sizeof(GDALGridNearestNeighborOptions) );
+
+            pszValue = CSLFetchNameValue( papszParms, "radius1" );
+            ((GDALGridNearestNeighborOptions *)*ppOptions)->
+                dfRadius1 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "radius2" );
+            ((GDALGridNearestNeighborOptions *)*ppOptions)->
+                dfRadius2 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "angle" );
+            ((GDALGridNearestNeighborOptions *)*ppOptions)->
+                dfAngle = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "nodata" );
+            ((GDALGridNearestNeighborOptions *)*ppOptions)->
+                dfNoDataValue = (pszValue) ? atof(pszValue) : 0.0;
+            break;
+
+        case GGA_MetricMinimum:
+        case GGA_MetricMaximum:
+        case GGA_MetricRange:
+            *ppOptions =
+                CPLMalloc( sizeof(GDALGridDataMetricsOptions) );
+
+            pszValue = CSLFetchNameValue( papszParms, "radius1" );
+            ((GDALGridDataMetricsOptions *)*ppOptions)->
+                dfRadius1 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "radius2" );
+            ((GDALGridDataMetricsOptions *)*ppOptions)->
+                dfRadius2 = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "angle" );
+            ((GDALGridDataMetricsOptions *)*ppOptions)->
+                dfAngle = (pszValue) ? atof(pszValue) : 0.0;
+
+            pszValue = CSLFetchNameValue( papszParms, "min_points" );
+            ((GDALGridDataMetricsOptions *)*ppOptions)->
+                nMinPoints = (pszValue) ? atol(pszValue) : 0;
+
+            pszValue = CSLFetchNameValue( papszParms, "nodata" );
+            ((GDALGridDataMetricsOptions *)*ppOptions)->
+                dfNoDataValue = (pszValue) ? atof(pszValue) : 0.0;
+            break;
+
+   }
+
+    CSLDestroy( papszParms );
+    return CE_None;
+}
+
+/************************************************************************/
+/*                            ProcessLayer()                            */
+/*                                                                      */
+/*      Process all the features in a layer selection, collecting       */
+/*      geometries and burn values.                                     */
+/************************************************************************/
+
+static void ProcessLayer( OGRLayerH hSrcLayer, GDALDatasetH hDstDS,
+                          GUInt32 nXSize, GUInt32 nYSize, int nBand,
+                          int& bIsXExtentSet, int& bIsYExtentSet,
+                          double& dfXMin, double& dfXMax,
+                          double& dfYMin, double& dfYMax,
+                          const char *pszBurnAttribute,
+                          GDALDataType eType,
+                          GDALGridAlgorithm eAlgorithm, void *pOptions,
+                          int bQuiet, GDALProgressFunc pfnProgress )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Get field index, and check.                                     */
+/* -------------------------------------------------------------------- */
+    int iBurnField = -1;
+
+    if ( pszBurnAttribute )
+    {
+        iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ),
+                                           pszBurnAttribute );
+        if( iBurnField == -1 )
+        {
+            #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Failed to find field %s on layer %s, skipping.\n",
+                    pszBurnAttribute, 
+                    OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
+            return;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Collect the geometries from this layer, and build list of       */
+/*      values to be interpolated.                                      */
+/* -------------------------------------------------------------------- */
+    OGRFeatureH hFeat;
+    std::vector<double> adfX, adfY, adfZ;
+
+    OGR_L_ResetReading( hSrcLayer );
+
+    while( (hFeat = OGR_L_GetNextFeature( hSrcLayer )) != NULL )
+    {
+        OGRGeometryH hGeom;
+
+        hGeom = OGR_F_GetGeometryRef( hFeat );
+
+        // FIXME: handle collections
+        if ( hGeom != NULL &&
+             (OGR_G_GetGeometryType( hGeom ) == wkbPoint
+              || OGR_G_GetGeometryType( hGeom ) == wkbPoint25D) )
+        {
+            adfX.push_back( OGR_G_GetX( hGeom, 0 ) );
+            adfY.push_back( OGR_G_GetY( hGeom, 0 ) );
+            if ( iBurnField < 0 )
+                adfZ.push_back( OGR_G_GetZ( hGeom, 0 ) );
+            else
+                adfZ.push_back( OGR_F_GetFieldAsDouble( hFeat, iBurnField ) );
+        }
+
+        
+        OGR_F_Destroy( hFeat );
+    }
+
+    if (adfX.size() == 0)
+    {
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "No point geometry found on layer %s, skipping.\n",
+                OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
+        return;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Compute grid geometry.                                          */
+/* -------------------------------------------------------------------- */
+
+    if ( !bIsXExtentSet )
+    {
+        dfXMin = *std::min_element(adfX.begin(), adfX.end());
+        dfXMax = *std::max_element(adfX.begin(), adfX.end());
+        bIsXExtentSet = TRUE;
+    }
+
+    if ( !bIsYExtentSet )
+    {
+        dfYMin = *std::min_element(adfY.begin(), adfY.end());
+        dfYMax = *std::max_element(adfY.begin(), adfY.end());
+        bIsYExtentSet = TRUE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Perform gridding.                                               */
+/* -------------------------------------------------------------------- */
+
+    const double    dfDeltaX = ( dfXMax - dfXMin ) / nXSize;
+    const double    dfDeltaY = ( dfYMax - dfYMin ) / nYSize;
+
+    if ( !bQuiet )
+    {
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Grid data type is \"%s\"\n", GDALGetDataTypeName(eType) );
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Grid size = (%lu %lu).\n",
+                (unsigned long)nXSize, (unsigned long)nYSize );
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Corner coordinates = (%f %f)-(%f %f).\n",
+                dfXMin - dfDeltaX / 2, dfYMax + dfDeltaY / 2,
+                dfXMax + dfDeltaX / 2, dfYMin - dfDeltaY / 2 );
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Grid cell size = (%f %f).\n", dfDeltaX, dfDeltaY );
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+ "Source point count = %lu.\n", (unsigned long)adfX.size() );
+        PrintAlgorithmAndOptions( eAlgorithm, pOptions );
+        #ifdef ZOO_SERVICE
+	  fprintf(stderr,
+#else
+            printf( 
+#endif
+"\n");
+    }
+
+    GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, nBand );
+
+    if (adfX.size() == 0)
+    {
+        // FIXME: Shoulda' set to nodata value instead
+        GDALFillRaster( hBand, 0.0 , 0.0 );
+        return;
+    }
+
+    GUInt32 nXOffset, nYOffset;
+    int     nBlockXSize, nBlockYSize;
+
+    GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
+    void    *pData =
+        CPLMalloc( nBlockXSize * nBlockYSize * GDALGetDataTypeSize(eType) );
+
+    GUInt32 nBlock = 0;
+    GUInt32 nBlockCount = ((nXSize + nBlockXSize - 1) / nBlockXSize)
+        * ((nYSize + nBlockYSize - 1) / nBlockYSize);
+
+    for ( nYOffset = 0; nYOffset < nYSize; nYOffset += nBlockYSize )
+    {
+        for ( nXOffset = 0; nXOffset < nXSize; nXOffset += nBlockXSize )
+        {
+            void *pScaledProgress;
+            pScaledProgress =
+                GDALCreateScaledProgress( 0.0,
+                                          (double)++nBlock / nBlockCount,
+                                          pfnProgress, NULL );
+
+            int nXRequest = nBlockXSize;
+            if (nXOffset + nXRequest > nXSize)
+                nXRequest = nXSize - nXOffset;
+
+            int nYRequest = nBlockYSize;
+            if (nYOffset + nYRequest > nYSize)
+                nYRequest = nYSize - nYOffset;
+
+            GDALGridCreate( eAlgorithm, pOptions,
+                            adfX.size(), &(adfX[0]), &(adfY[0]), &(adfZ[0]),
+                            dfXMin + dfDeltaX * nXOffset,
+                            dfXMin + dfDeltaX * (nXOffset + nXRequest),
+                            dfYMin + dfDeltaY * nYOffset,
+                            dfYMin + dfDeltaY * (nYOffset + nYRequest),
+                            nXRequest, nYRequest, eType, pData,
+                            GDALScaledProgress, pScaledProgress );
+
+            GDALRasterIO( hBand, GF_Write, nXOffset, nYOffset,
+                          nXRequest, nYRequest, pData,
+                          nXRequest, nYRequest, eType, 0, 0 );
+
+            GDALDestroyScaledProgress( pScaledProgress );
+        }
+    }
+
+    CPLFree( pData );
+}
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+#ifdef ZOO_SERVICE
+int Gdal_Grid(maps*& conf,maps*& inputs,maps*& outputs)
+#else
+int main( int argc, char ** argv )
+#endif
+{
+    GDALDriverH     hDriver;
+    const char      *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
+    char            **papszLayers = NULL;
+    const char      *pszBurnAttribute = NULL;
+    const char      *pszWHERE = NULL, *pszSQL = NULL;
+    GDALDataType    eOutputType = GDT_Float64;
+    char            **papszCreateOptions = NULL;
+    GUInt32         nXSize = 0, nYSize = 0;
+    double          dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0;
+    int             bIsXExtentSet = FALSE, bIsYExtentSet = FALSE;
+    GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower;
+    void            *pOptions = NULL;
+    char            *pszOutputSRS = NULL;
+    int             bQuiet = FALSE;
+    GDALProgressFunc pfnProgress = GDALTermProgress;
+    int             i;
+    OGRGeometryH    hSpatialFilter = NULL;
+
+    /* Check that we are running against at least GDAL 1.5 */
+    /* Note to developers : if we use newer API, please change the requirement */
+    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500)
+    {
+#ifdef ZOO_SERVICE
+        fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of this ZOO ServiceProvider, "
+                "which was compiled against GDAL %s\n", GDAL_RELEASE_NAME);
+#else
+        fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
+                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
+#endif
+	return SERVICE_FAILED;
+    }
+
+    GDALAllRegister();
+    OGRRegisterAll();
+
+#ifdef ZOO_SERVICE
+    bQuiet = TRUE;
+    pfnProgress = GDALDummyProgress;
+    map* tmpMap=NULL;
+
+    char dataPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","dataPath");
+    if(tmpMap!=NULL)
+      sprintf(dataPath,"%s",tmpMap->value);
+    tmpMap=NULL;
+
+    char tempPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","tmpPath");
+    if(tmpMap!=NULL){
+      sprintf(tempPath,"%s",tmpMap->value);
+    }
+    tmpMap=NULL;
+
+    tmpMap=getMapFromMaps(inputs,"OF","value");
+    if(tmpMap!=NULL){
+      pszFormat=tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OT","value");
+    if(tmpMap!=NULL){
+      int iType;      
+      for( iType = 1; iType < GDT_TypeCount; iType++ )
+	{
+	  if( GDALGetDataTypeName((GDALDataType)iType) != NULL
+	      && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
+                             tmpMap->value) )
+	    {
+	      eOutputType = (GDALDataType) iType;
+	    }
+	}
+      if( eOutputType == GDT_Unknown )
+	{
+	  fprintf( stderr, "Unknown output pixel type: %s\n", tmpMap->value );
+	  Usage();
+	  return SERVICE_FAILED;
+	}
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"TXE","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      while(t!=NULL){
+        switch(cnt){
+        case 0:
+          dfXMin = atof(t);
+          break;
+        case 1:
+          dfXMax = atof(t);
+          break;
+        }
+	t=strtok(NULL,",");
+	cnt++;
+      }
+      bIsXExtentSet = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"TYE","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      while(t!=NULL){
+        switch(cnt){
+        case 0:
+          dfYMin = atof(t);
+          break;
+        case 1:
+          dfYMax = atof(t);
+          break;
+        }
+	t=strtok(NULL,",");
+	cnt++;
+	
+      }
+      bIsYExtentSet = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OUTSIZE","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      while(t!=NULL){
+        switch(cnt){
+        case 0:
+          nXSize = atoi(t);
+          break;
+        case 1:
+          nYSize = atoi(t);
+          break;
+        }
+	cnt++;
+      }
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"CO","value");
+    if(tmpMap!=NULL){
+      papszCreateOptions = CSLAddString( papszCreateOptions, tmpMap->value );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"ZFIELD","value");
+    if(tmpMap!=NULL){
+      pszBurnAttribute = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"WHERE","value");
+    if(tmpMap!=NULL){
+      pszWHERE = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"L","value");
+    if(tmpMap!=NULL){
+      papszLayers = CSLAddString( papszLayers, tmpMap->value );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"SQL","value");
+    if(tmpMap!=NULL){
+      pszSQL = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"A","value");
+    if(tmpMap!=NULL){
+      if ( ParseAlgorithmAndOptions(tmpMap->value, &eAlgorithm, &pOptions )
+	   != CE_None )
+	{
+	  fprintf( stderr,
+		   "Failed to process algoritm name and parameters.\n" );
+	  return SERVICE_FAILED;
+	}
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"SPAT","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      double dfULX, dfULY, dfLRX, dfLRY;
+      while(t!=NULL){
+        switch(cnt){
+        case 0:
+          dfULX = atof(t);
+          break;
+        case 1:
+          dfULY = atof(t);
+          break;
+        case 2:
+          dfLRX = atof(t);
+          break;
+        case 3:
+          dfLRY = atof(t);
+          break;
+        }
+        fprintf(stderr,"%s\n\n",t);
+        fprintf(stderr,"%f - %f - %f - %f\n\n",dfULX,dfULY,dfLRX,dfLRY);
+        t=strtok(NULL,",");
+        cnt++;
+      }
+      OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );
+      
+      OGR_G_AddPoint_2D( hRing, dfULX, dfULY );
+      OGR_G_AddPoint_2D( hRing, dfULX, dfLRY );
+      OGR_G_AddPoint_2D( hRing, dfLRY, dfLRY );
+      OGR_G_AddPoint_2D( hRing, dfLRY, dfULY );
+      OGR_G_AddPoint_2D( hRing, dfULX, dfULY );
+      
+      hSpatialFilter = OGR_G_CreateGeometry( wkbPolygon );
+      OGR_G_AddGeometry( hSpatialFilter, hRing );
+	
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"A_SRS","value");
+    if(tmpMap!=NULL){
+      OGRSpatialReference oOutputSRS;
+      
+      if( oOutputSRS.SetFromUserInput( tmpMap->value ) != OGRERR_NONE )
+	{
+	  fprintf( stderr, "Failed to process SRS definition: %s\n", 
+		   tmpMap->value );
+	  GDALDestroyDriverManager();
+	  return SERVICE_FAILED;
+	}
+      
+      oOutputSRS.exportToWkt( &pszOutputSRS );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL){
+      pszSource=(char*)malloc(sizeof(char)*(strlen(dataPath)+strlen(tmpMap->value)+1));
+      sprintf((char*)pszSource,"%s/%s",dataPath,tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL){
+      pszDest=(char*)malloc(sizeof(char)*(strlen(tempPath)+strlen(tmpMap->value)+4));
+      char *ext=new char[4];
+      ext="tif";
+      if(strncasecmp(pszFormat,"AAIGRID",7)==0)
+        ext="csv";
+      else 
+        if(strncasecmp(pszFormat,"PNG",3)==0)
+          ext="png";
+        else
+          if(strncasecmp(pszFormat,"GIF",3)==0)
+            ext="gif";
+          else
+            if(strncasecmp(pszFormat,"JPEG",4)==0)
+              ext="jpg";
+      sprintf((char*)pszDest,"%s/%s.%s",tempPath,tmpMap->value,ext);
+    }
+
+#else
+    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
+    if( argc < 1 )
+        exit( -argc );
+
+/* -------------------------------------------------------------------- */
+/*      Parse arguments.                                                */
+/* -------------------------------------------------------------------- */
+    for( i = 1; i < argc; i++ )
+    {
+        if( EQUAL(argv[i], "--utility_version") )
+        {
+            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
+                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
+            return 0;
+        }
+        else if( EQUAL(argv[i],"-of") && i < argc-1 )
+        {
+            pszFormat = argv[++i];
+        }
+
+        else if( EQUAL(argv[i],"-quiet") )
+        {
+            bQuiet = TRUE;
+            pfnProgress = GDALDummyProgress;
+        }
+
+        else if( EQUAL(argv[i],"-ot") && i < argc-1 )
+        {
+            int	iType;
+            
+            for( iType = 1; iType < GDT_TypeCount; iType++ )
+            {
+                if( GDALGetDataTypeName((GDALDataType)iType) != NULL
+                    && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
+                             argv[i+1]) )
+                {
+                    eOutputType = (GDALDataType) iType;
+                }
+            }
+
+            if( eOutputType == GDT_Unknown )
+            {
+                fprintf( stderr, "Unknown output pixel type: %s\n", argv[i+1] );
+                Usage();
+                exit( 2 );
+            }
+            i++;
+        }
+
+        else if( EQUAL(argv[i],"-txe") && i < argc-2 )
+        {
+            dfXMin = atof(argv[++i]);
+            dfXMax = atof(argv[++i]);
+            bIsXExtentSet = TRUE;
+        }   
+
+        else if( EQUAL(argv[i],"-tye") && i < argc-2 )
+        {
+            dfYMin = atof(argv[++i]);
+            dfYMax = atof(argv[++i]);
+            bIsYExtentSet = TRUE;
+        }   
+
+        else if( EQUAL(argv[i],"-outsize") && i < argc-2 )
+        {
+            nXSize = atoi(argv[++i]);
+            nYSize = atoi(argv[++i]);
+        }   
+
+        else if( EQUAL(argv[i],"-co") && i < argc-1 )
+        {
+            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
+        }   
+
+        else if( EQUAL(argv[i],"-zfield") && i < argc-1 )
+        {
+            pszBurnAttribute = argv[++i];
+        }
+
+        else if( EQUAL(argv[i],"-where") && i < argc-1 )
+        {
+            pszWHERE = argv[++i];
+        }
+
+        else if( EQUAL(argv[i],"-l") && i < argc-1 )
+        {
+            papszLayers = CSLAddString( papszLayers, argv[++i] );
+        }
+
+        else if( EQUAL(argv[i],"-sql") && i < argc-1 )
+        {
+            pszSQL = argv[++i];
+        }
+
+        else if( EQUAL(argv[i],"-spat") 
+                 && argv[i+1] != NULL 
+                 && argv[i+2] != NULL 
+                 && argv[i+3] != NULL 
+                 && argv[i+4] != NULL )
+        {
+            OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );
+
+            OGR_G_AddPoint_2D( hRing, atof(argv[i+1]), atof(argv[i+2]) );
+            OGR_G_AddPoint_2D( hRing, atof(argv[i+1]), atof(argv[i+4]) );
+            OGR_G_AddPoint_2D( hRing, atof(argv[i+3]), atof(argv[i+4]) );
+            OGR_G_AddPoint_2D( hRing, atof(argv[i+3]), atof(argv[i+2]) );
+            OGR_G_AddPoint_2D( hRing, atof(argv[i+1]), atof(argv[i+2]) );
+
+            hSpatialFilter = OGR_G_CreateGeometry( wkbPolygon );
+            OGR_G_AddGeometry( hSpatialFilter, hRing );
+            i += 4;
+        }
+
+        else if( EQUAL(argv[i],"-a_srs") && i < argc-1 )
+        {
+            OGRSpatialReference oOutputSRS;
+
+            if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE )
+            {
+                fprintf( stderr, "Failed to process SRS definition: %s\n", 
+                         argv[i+1] );
+                GDALDestroyDriverManager();
+                exit( 1 );
+            }
+
+            oOutputSRS.exportToWkt( &pszOutputSRS );
+            i++;
+        }   
+
+        else if( EQUAL(argv[i],"-a") && i < argc-1 )
+        {
+            if ( ParseAlgorithmAndOptions( argv[++i], &eAlgorithm, &pOptions )
+                 != CE_None )
+            {
+                fprintf( stderr,
+                         "Failed to process algoritm name and parameters.\n" );
+                exit( 1 );
+            }
+        }
+
+        else if( argv[i][0] == '-' )
+        {
+            fprintf( stderr, "Option %s incomplete, or not recognised.\n\n", 
+                    argv[i] );
+            Usage();
+            GDALDestroyDriverManager();
+            exit( 2 );
+        }
+
+        else if( pszSource == NULL )
+        {
+            pszSource = argv[i];
+        }
+
+        else if( pszDest == NULL )
+        {
+            pszDest = argv[i];
+        }
+
+        else
+        {
+            fprintf( stderr, "Too many command options.\n\n" );
+            Usage();
+            GDALDestroyDriverManager();
+            exit( 2 );
+        }
+    }
+#endif
+
+    if( pszSource == NULL || pszDest == NULL
+        || (pszSQL == NULL && papszLayers == NULL) )
+    {
+        Usage();
+        GDALDestroyDriverManager();
+        exit( 2 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Find the output driver.                                         */
+/* -------------------------------------------------------------------- */
+    hDriver = GDALGetDriverByName( pszFormat );
+    if( hDriver == NULL )
+    {
+        int	iDr;
+        
+        fprintf( stderr, "Output driver `%s' not recognised.\n", pszFormat );
+        fprintf( stderr,
+        "The following format drivers are configured and support output:\n" );
+        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
+        {
+            GDALDriverH hDriver = GDALGetDriver(iDr);
+
+            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
+                || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
+                                        NULL ) != NULL )
+            {
+                fprintf( stderr, "  %s: %s\n",
+                         GDALGetDriverShortName( hDriver  ),
+                         GDALGetDriverLongName( hDriver ) );
+            }
+        }
+        printf( "\n" );
+        Usage();
+        
+        GDALDestroyDriverManager();
+#ifndef ZOO_SERVICE
+        CSLDestroy( argv );
+#endif
+        CSLDestroy( papszCreateOptions );
+	return SERVICE_FAILED;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open input datasource.                                          */
+/* -------------------------------------------------------------------- */
+    OGRDataSourceH hSrcDS;
+
+    hSrcDS = OGROpen( pszSource, FALSE, NULL );
+    if( hSrcDS == NULL )
+    {
+        fprintf( stderr, "Unable to open input datasource \"%s\".\n",
+                 pszSource );
+        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
+	return SERVICE_FAILED;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Create target raster file.                                      */
+/* -------------------------------------------------------------------- */
+    GDALDatasetH    hDstDS;
+    int             nLayerCount = CSLCount(papszLayers);
+    int             nBands = nLayerCount;
+
+    if ( pszSQL )
+        nBands++;
+
+    // FIXME
+    if ( nXSize == 0 )
+        nXSize = 256;
+    if ( nYSize == 0 )
+        nYSize = 256;
+
+    hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands,
+                         eOutputType, papszCreateOptions );
+    if ( hDstDS == NULL )
+    {
+        fprintf( stderr, "Unable to create target dataset \"%s\".\n",
+                 pszDest );
+        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
+	return SERVICE_FAILED;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If algorithm was not specified assigh default one.              */
+/* -------------------------------------------------------------------- */
+    if ( !pOptions )
+        ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions );
+
+/* -------------------------------------------------------------------- */
+/*      Process SQL request.                                            */
+/* -------------------------------------------------------------------- */
+    if( pszSQL != NULL )
+    {
+        OGRLayerH hLayer;
+
+        hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL, hSpatialFilter, NULL ); 
+        if( hLayer != NULL )
+        {
+            // Custom layer will be rasterized in the first band.
+            ProcessLayer( hLayer, hDstDS, nXSize, nYSize, 1,
+                          bIsXExtentSet, bIsYExtentSet,
+                          dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
+                          eOutputType, eAlgorithm, pOptions,
+                          bQuiet, pfnProgress );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Process each layer.                                             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nLayerCount; i++ )
+    {
+        OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i] );
+        if( hLayer == NULL )
+        {
+            fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", 
+                     papszLayers[i] );
+            continue;
+        }
+
+        if( pszWHERE )
+        {
+            if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE )
+                break;
+        }
+
+        if( hSpatialFilter != NULL )
+          OGR_L_SetSpatialFilter( hLayer, hSpatialFilter );
+
+        // Fetch the first meaningful SRS definition
+        if ( !pszOutputSRS )
+        {
+            OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer );
+            if ( hSRS )
+                OSRExportToWkt( hSRS, &pszOutputSRS );
+        }
+
+        ProcessLayer( hLayer, hDstDS, nXSize, nYSize,
+                      i + 1 + nBands - nLayerCount,
+                      bIsXExtentSet, bIsYExtentSet,
+                      dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
+                      eOutputType, eAlgorithm, pOptions,
+                      bQuiet, pfnProgress );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Apply geotransformation matrix.                                 */
+/* -------------------------------------------------------------------- */
+    double  adfGeoTransform[6];
+    adfGeoTransform[0] = dfXMin;
+    adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize;
+    adfGeoTransform[2] = 0.0;
+    adfGeoTransform[3] = dfYMin;
+    adfGeoTransform[4] = 0.0;
+    adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize;
+    GDALSetGeoTransform( hDstDS, adfGeoTransform );
+
+/* -------------------------------------------------------------------- */
+/*      Apply SRS definition if set.                                    */
+/* -------------------------------------------------------------------- */
+    if ( pszOutputSRS )
+    {
+        GDALSetProjection( hDstDS, pszOutputSRS );
+        CPLFree( pszOutputSRS );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Cleanup                                                         */
+/* -------------------------------------------------------------------- */
+    CSLDestroy( papszCreateOptions );
+    CPLFree( pOptions );
+    OGR_DS_Destroy( hSrcDS );
+    GDALClose( hDstDS );
+#ifndef ZOO_SERVICE
+    CSLDestroy( argv );
+#endif
+    CSLDestroy( papszLayers );
+    OGRCleanupAll();
+
+    GDALDestroyDriverManager();
+ 
+    outputs=(maps*)malloc(sizeof(maps*));
+    outputs->name="OutputedPolygon";
+    outputs->content=createMap("value",(char*)pszDest);
+    addMapToMap(&outputs->content,createMap("dataType","string"));
+    outputs->next=NULL;
+    return SERVICE_SUCCEEDED;
+}
+
+
+#ifdef ZOO_SERVICE
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ExtractNDVI.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ExtractNDVI.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ExtractNDVI.zcfg	(revision 672)
@@ -0,0 +1,58 @@
+[ExtractNDVI]
+ Title = Normalized Difference Vegetation Index. 
+ Abstract = Computes the Normalized Difference Vegetation Index in a new raster file. 
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ndvi
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [raster]
+   Title = The raster file to be used
+   Abstract = URI to a raster file that contains the mentionned two bands.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = image/tiff
+    </Default>
+   </ComplexData>
+  [red]
+   Title = The red band number
+   Abstract = The RED band number to use.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = int
+    <Default>
+     value = 1
+    </Default>
+   </LiteralData>
+  [nir]
+   Title = The NIR band number
+   Abstract = The NIR band number to use.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = int
+    <Default>
+     value = 2
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [raster]
+   Title = The resulting raster
+   Abstract = A single band raster containing the NDVI of the original raster using formula : (NIR - RED) / (NIR + RED) .
+   <ComplexData>
+    <Default>
+     mimeType = image/tiff
+     extension = tif
+    </Default>
+   </ComplexData>
+ </DataOutputs>  
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ndvi.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ndvi.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/ndvi/cgi-env/ndvi.py	(revision 672)
@@ -0,0 +1,107 @@
+#
+# Python Scripting for ArcGIS
+# by Dr Peter Bunting is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License -
+# See more at:
+# http://www.landmap.ac.uk/index.php/Learning-Materials/Python-Scripting/9.4-Calculate-NDVI-using-GDAL
+#
+
+import sys, os, struct
+
+import osgeo.gdal as gdal
+
+# Calculate and output NDVI from raster bands
+def ExtractNDVI(conf, inputs, outputs):
+    
+    # Open the input dataset
+    gdal.FileFromMemBuffer('/vsimem//temp.tif', inputs["raster"]["value"])
+    dataset = gdal.Open( '/vsimem//temp.tif')
+    if dataset is None:
+        conf["lenv"]["message"]="The dataset could not be openned properly"
+        return 4
+
+    # Create the output dataset
+    driver = gdal.GetDriverByName( "GTiff" )
+    # Get the spatial information from the input file
+    geoTransform=None
+    geoProjection=None
+    print >> sys.stderr,dir(dataset) 
+    try:
+        geoTransform = dataset.GetGeoTransform()
+    except:
+        print >> sys.stderr, "Unable to load geotransform"
+    try:
+        geoProjection = dataset.GetProjection()
+    except:
+        print >> sys.stderr, "Unable to load projection"
+
+    # Create an output file of the same size as the inputted 
+    # image but with only 1 output image band.
+    newDataset = driver.Create("/vsimem//output"+conf["lenv"]["sid"], \
+                               dataset.RasterXSize, dataset.RasterYSize,1, \
+                               gdal.GDT_Float32)
+    # Set spatial informations of the new image.
+    if geoTransform:
+        newDataset.SetGeoTransform(geoTransform)
+    if geoProjection:
+        newDataset.SetProjection(geoProjection)
+    if newDataset is None:
+        conf["lenv"]["message"]='Could not create output image'
+        return 4
+    
+    # Get the RED and NIR image bands of the image
+    red_id=int(inputs["red"]["value"])
+    nir_id=int(inputs["nir"]["value"])
+    red_band = dataset.GetRasterBand(red_id) # RED BAND
+    nir_band = dataset.GetRasterBand(nir_id) # NIR BAND
+
+    # Loop through each line in turn.
+    numLines = red_band.YSize
+    for line in range(numLines):
+        # Define variable for output line.
+        outputLine = ''
+        # Read in data for the current line from the 
+        # image band representing the red wavelength
+        red_scanline = red_band.ReadRaster( 0, line, red_band.XSize, 1, \
+                                          red_band.XSize, 1, gdal.GDT_Float32 )
+        # Unpack the line of data to be read as floating point data
+        red_tuple = struct.unpack('f' * red_band.XSize, red_scanline)
+            
+        # Read in data for the current line from the 
+        # image band representing the NIR wavelength
+        nir_scanline = nir_band.ReadRaster( 0, line, nir_band.XSize, 1, \
+                                          nir_band.XSize, 1, gdal.GDT_Float32 )
+        # Unpack the line of data to be read as floating point data
+        nir_tuple = struct.unpack('f' * nir_band.XSize, nir_scanline)
+
+        # Loop through the columns within the image
+        for i in range(len(red_tuple)):
+            # Calculate the NDVI for the current pixel.
+            ndvi_lower = (nir_tuple[i] + red_tuple[i])
+            ndvi_upper = (nir_tuple[i] - red_tuple[i])
+            ndvi = 0
+            # Becareful of zero divide 
+            if ndvi_lower == 0:
+                ndvi = 0
+            else:
+                ndvi = ndvi_upper/ndvi_lower
+            # Add the current pixel to the output line
+            outputLine = outputLine + struct.pack('f', ndvi)
+        # Write the completed line to the output image
+        newDataset.GetRasterBand(1).WriteRaster(0, line, red_band.XSize, 1, \
+                                         outputLine, buf_xsize=red_band.XSize, 
+                                         buf_ysize=1, buf_type=gdal.GDT_Float32)
+    
+        # Delete the output line following write
+        del outputLine
+    print >> sys.stderr,'NDVI Calculated and Outputted to File'
+    print >> sys.stderr,dir(newDataset)
+    newDataset.FlushCache()
+    vsiFile=gdal.VSIFOpenL("/vsimem//output"+conf["lenv"]["sid"],"r")
+    i=0
+    while gdal.VSIFSeekL(vsiFile,0,os.SEEK_END)>0:
+        i+=1
+    fileSize=gdal.VSIFTellL(vsiFile)
+    gdal.VSIFSeekL(vsiFile,0,os.SEEK_SET)
+    outputs["raster"]["value"]=gdal.VSIFReadL(fileSize,1,vsiFile)
+    gdal.Unlink("/vsimem//output"+conf["lenv"]["sid"])
+    return 3
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/Makefile	(revision 672)
@@ -0,0 +1,15 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/profile_service.zo: service.c
+	g++  -DZOO_SERVICE ${CFLAGS} -shared -fpic -o cgi-env/profile_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/gdal/profile
+	install cgi-env/* ${CGI_DIR}/gdal/profile
+
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/cgi-env/GdalExtractProfile.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/cgi-env/GdalExtractProfile.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/cgi-env/GdalExtractProfile.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[GdalExtractProfile]
+ Title = Extract elevation values along a line. 
+ Abstract = Fetch the x,y,z values of a DEM raster file along a linestring
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = profile_service.zo
+ <MetaData>
+   title = My Demo
+ </MetaData>
+ <DataInputs>
+  [RasterFile]
+   Title = The name of the MNT file
+   Abstract = The file containing elevation model relative to the dataPath defined in the ZOO-Project main configuration file.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value = topofr.tif
+    </Default>
+   </LiteralData>
+  [Geometry]
+   Title = The path to calaculate profile
+   Abstract = The input data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+     asReference = true	
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Profile]
+   Title = The resulting profile
+   Abstract = GeoJSON string containing the X Y Z values where (X,Y) is corresponding to the original coordinates and the elevation value. 
+   <ComplexData>
+    <Default>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/makefile.vc	(revision 672)
@@ -0,0 +1,23 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/profile_service.zo: service.c
+	$(CPP)  /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/ $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/profile_service.zo  $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\gdal_service.*
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/profile/service.c	(revision 672)
@@ -0,0 +1,194 @@
+/* ****************************************************************************
+ * $Id$
+ *
+ * Project:  GdalExtractProfile
+ * Purpose:  Extract Profile from a Raster file for an Input Geometry (LINE)
+ * Author:   Gérald Fenoy, gerald.fenoy@geolabs.fr
+ *
+ * ****************************************************************************
+ * Copyright (c) 2010-2011, GeoLabs SARL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifdef ZOO_SERVICE
+#include "service.h"
+#include "service_internal.h"
+#endif
+#include "gdal.h"
+#include "cpl_conv.h"
+#include "ogr_api.h"
+
+#ifdef ZOO_SERVICE
+extern "C" {
+#endif
+
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+#ifdef ZOO_SERVICE
+int GdalExtractProfile(maps*& conf,maps*& inputs,maps*& outputs)
+#else
+int main(int argc,char** argv)
+#endif
+{
+  char *pszFilename;
+#ifdef ZOO_SERVICE
+  map* tmp=NULL;
+  map* tmp1=NULL;
+  tmp=getMapFromMaps(conf,"main","dataPath");
+  tmp1=getMapFromMaps(inputs,"RasterFile","value");
+  pszFilename=(char *)malloc((2+strlen(tmp->value)+strlen(tmp1->value))*sizeof(char));
+  sprintf(pszFilename,"%s/%s",tmp->value,tmp1->value);
+#else
+  pszFilename=argv[1];
+#endif
+  GDALDatasetH  hDataset;  
+  GDALAllRegister();
+  OGRRegisterAll();
+ 
+  hDataset = GDALOpen( pszFilename, GA_ReadOnly );
+  free(pszFilename);
+  if( hDataset != NULL )
+    {
+      GDALDriverH   hDriver;
+      double        adfGeoTransform[6];
+
+      if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
+	{
+
+
+        GDALRasterBandH hBand;
+        int             nBlockXSize, nBlockYSize;
+        int             bGotMin, bGotMax;
+        double          adfMinMax[2];
+        
+        hBand = GDALGetRasterBand( hDataset, 1 );
+
+        adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin );
+        adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax );
+        if( ! (bGotMin && bGotMax) )
+	  GDALComputeRasterMinMax( hBand, TRUE, adfMinMax );
+#ifdef ZOO_SERVICE
+	  tmp1=getMapFromMaps(inputs,"Geometry","value");
+	  OGRGeometryH geometry=OGR_G_CreateGeometryFromJson(tmp1->value);
+#else
+	  OGRGeometryH geometry=OGR_G_CreateGeometryFromJson(argv[2]);
+#endif
+
+	  OGR_G_Segmentize(geometry, adfGeoTransform[1]);
+	  int nbGeom=OGR_G_GetPointCount(geometry);
+	  int k=0;
+	  double ppx=0,ppy=0;
+	  double value;
+	  char *buffer=NULL;
+	  int length=0;
+	  buffer=(char*)malloc(37*sizeof(char));
+	  sprintf(buffer,"{\"type\":\"LineString\",\"coordinates\":[");
+	  length+=strlen(buffer);
+	  for(k=0;k<nbGeom;k++){
+	    //OGRGeometryH point;
+	    double prx,pry,prz;
+	    OGR_G_GetPoint(geometry,k,&prx,&pry,&prz);
+	    float *pafScanline;
+	    pafScanline = (float *) CPLMalloc(sizeof(float));
+	    int px=(int)floor((prx-adfGeoTransform[0])/adfGeoTransform[1]);
+	    int py=(int)floor((pry-adfGeoTransform[3])/adfGeoTransform[5]);
+	    if(px!=ppx || py!=ppy){
+	      if(GDALRasterIO( hBand, GF_Read, px, py, 1, 1, 
+			    pafScanline, 1, 1, GDT_Float32, 
+			       0, 0 ) != CE_None){
+		char *tmp;
+		tmp=(char*) malloc(300*sizeof(char));
+		sprintf(tmp,"GDALRasterIO failed for point (%d,%d)",px,py);
+		setMapInMaps(conf,"lenv","message",_ss(tmp));
+		CPLFree(pafScanline);
+		free(tmp);
+		return SERVICE_FAILED;
+	      }
+	      if(buffer!=NULL){
+		int len=strlen(buffer);
+		buffer=(char*)realloc(buffer,(len+50+1)*sizeof(char));
+	      }
+	      else
+		buffer=(char*)malloc((51)*sizeof(char));
+	      char *tmpValue=(char *)malloc(50*sizeof(char));
+	      sprintf(tmpValue,"[%.6f,%.6f,%.6f]%c",prx,pry,pafScanline[0],(k+1==nbGeom?' ':','));
+	      strncpy(buffer+length,tmpValue,strlen(tmpValue));
+	      length+=strlen(tmpValue);
+	      buffer[length]=0;
+	      value=pafScanline[0];
+	      free(tmpValue);
+	      //Usefull if we can export 3D JSON string at the end
+	      //OGR_G_SetPoint(geometry,k,prx,pry,pafScanline[0]);	      
+	    }
+	    else{
+	      if(buffer!=NULL)
+		buffer=(char*)realloc(buffer,(strlen(buffer)+50+1)*sizeof(char));
+	      else
+		buffer=(char*)malloc((51)*sizeof(char));
+	      char *tmpValue=(char *)malloc(50*sizeof(char));
+	      sprintf(tmpValue,"[%.6f,%.6f,%.6f]%c",prx,pry,value,(k+1==nbGeom?' ':','));
+	      strncpy(buffer+length,tmpValue,strlen(tmpValue));
+	      length+=strlen(tmpValue);
+	      buffer[length]=0;
+	      free(tmpValue);
+	      value=value;
+	    }
+	    CPLFree(pafScanline);
+	    ppx=px;
+	    ppy=py;
+	  }
+	  buffer=(char*)realloc(buffer,(strlen(buffer)+3)*sizeof(char));
+	  char *tmpValue=(char *)malloc(3*sizeof(char));
+	  sprintf(tmpValue,"]}");
+	  tmpValue[2]=0;
+	  strncpy(buffer+length,tmpValue,strlen(tmpValue));
+	  length+=strlen(tmpValue);
+	  buffer[length]=0;
+#ifdef ZOO_SERVICE
+	  setMapInMaps(outputs,"Profile","value",buffer);
+	  setMapInMaps(outputs,"Profile","mimeType","text/plain");
+#else
+	  fprintf(stderr,"%s\n",buffer);
+#endif
+	  free(buffer);
+	  free(tmpValue);
+	  OGR_G_DestroyGeometry(geometry);
+	}
+    }
+  else{
+#ifdef ZOO_SERVICE
+    setMapInMaps(conf,"lenv","message",_ss("Unable to load your raster file !"));
+    return SERVICE_FAILED;
+#else
+    printf("Unable to load your raster file %s !\n",argv[1]);
+#endif
+  }
+  OGRCleanupAll();
+  GDALClose(hDataset);
+  GDALDestroyDriverManager();
+#ifdef ZOO_SERVICE
+  return SERVICE_SUCCEEDED;
+#endif
+}
+
+#ifdef ZOO_SERVICE
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/Makefile	(revision 672)
@@ -0,0 +1,16 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/translate_service.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/translate_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/gdal/translate
+	install cgi-env/* ${CGI_DIR}/gdal/translate
+
+
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/cgi-env/Gdal_Translate.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/cgi-env/Gdal_Translate.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/cgi-env/Gdal_Translate.zcfg	(revision 672)
@@ -0,0 +1,61 @@
+[Gdal_Translate]
+ Title = Convert raster data from one format to another. 
+ Abstract = http://www.gdal.org/gdal_translate.html
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = translate_service.zo
+ <MetaData>
+   title = My Demo
+ </MetaData>
+ <DataInputs>
+  [Format]
+   Title = Format of the output data
+   Abstract = Select the output format by usig short name of the format (use gda-config --formats for list of available formats on your platform).
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value = GTiff
+    </Default>
+   </LiteralData>
+  [GCP]
+   Title = Ground Point Control
+   Abstract = Ground Point Control in the form : pixel,line,eating,northing(,elev).
+   minOccurs = 0
+   maxOccurs = unbounded
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/makefile.vc	(revision 672)
@@ -0,0 +1,23 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/translate_service.zo: service.c
+	$(CPP)  /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/vrt $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/translate_service.zo  $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\translate_service.*
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/translate/service.c	(revision 672)
@@ -0,0 +1,925 @@
+/******************************************************************************
+ * $Id$
+ *
+ * Project:  GDAL Utilities
+ * Purpose:  GDAL Image Translator Program
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1998, 2002, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "cpl_vsi.h"
+#include "cpl_conv.h"
+#include "cpl_string.h"
+#include "gdal_priv.h"
+#include "ogr_spatialref.h"
+#include "vrtdataset.h"
+
+#include "service.h"
+
+CPL_CVSID("$Id$");
+
+extern "C" {
+
+  static void AttachMetadata( GDALDatasetH, char ** );
+  static int bSubCall = FALSE;
+
+  /************************************************************************/
+  /*                          Gdal_Translate()                            */
+  /************************************************************************/
+
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+  int Gdal_Translate(maps*& conf,maps*& inputs,maps*& outputs)
+  {
+
+
+    GDALDatasetH	hDataset, hOutDS;
+    int			i;
+    int			nRasterXSize, nRasterYSize;
+    const char		*pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
+    GDALDriverH		hDriver;
+    int			*panBandList = NULL, nBandCount = 0, bDefBands = TRUE;
+    double		adfGeoTransform[6];
+    GDALDataType	eOutputType = GDT_Unknown;
+    int			nOXSize = 0, nOYSize = 0;
+    char		*pszOXSize=NULL, *pszOYSize=NULL;
+    char                **papszCreateOptions = NULL;
+    int                 anSrcWin[4], bStrict = FALSE;
+    const char          *pszProjection;
+    int                 bScale = FALSE, bHaveScaleSrc = FALSE;
+    double	        dfScaleSrcMin=0.0, dfScaleSrcMax=255.0;
+    double              dfScaleDstMin=0.0, dfScaleDstMax=255.0;
+    double              dfULX, dfULY, dfLRX, dfLRY;
+    char                **papszMetadataOptions = NULL;
+    char                *pszOutputSRS = NULL;
+    int                 bQuiet = TRUE, bGotBounds = FALSE;
+    GDALProgressFunc    pfnProgress = GDALDummyProgress;
+    int                 nGCPCount = 0;
+    GDAL_GCP            *pasGCPs = NULL;
+    int                 iSrcFileArg = -1, iDstFileArg = -1;
+    int                 bCopySubDatasets = FALSE;
+    double              adfULLR[4] = { 0,0,0,0 };
+    int                 bSetNoData = FALSE;
+    double		dfNoDataReal = 0.0;
+    int                 nRGBExpand = 0;
+
+    anSrcWin[0] = 0;
+    anSrcWin[1] = 0;
+    anSrcWin[2] = 0;
+    anSrcWin[3] = 0;
+
+    dfULX = dfULY = dfLRX = dfLRY = 0.0;
+
+    /* ----------------------------------------------------------------- */
+    /*      Register standard GDAL drivers, and process generic GDAL     */
+    /* ----------------------------------------------------------------- */
+    GDALAllRegister();
+    /* ----------------------------------------------------------------- */
+    /* Extract Format, InputDSN, OutputDSN parameters                    */
+    /* ----------------------------------------------------------------- */
+
+    map* tmpMap=NULL;
+
+    char dataPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","dataPath");
+    if(tmpMap!=NULL)
+      sprintf(dataPath,"%s",tmpMap->value);
+    tmpMap=NULL;
+
+    char tempPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","tmpPath");
+    if(tmpMap!=NULL){
+      sprintf(tempPath,"%s",tmpMap->value);
+    }
+    tmpMap=NULL;
+
+    tmpMap=getMapFromMaps(inputs,"Format","value");
+    if(tmpMap!=NULL){
+      pszFormat=tmpMap->value;
+    }
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL){
+      pszSource=(char*)CPLMalloc(sizeof(char)*(strlen(dataPath)+strlen(tmpMap->value)+4));
+      sprintf((char*)pszSource,"%s/%s",dataPath,tmpMap->value);
+    }
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL){
+      pszDest=(char*)CPLMalloc(sizeof(char)*(strlen(tempPath)+strlen(tmpMap->value)+4));
+      char *ext=new char[4];
+      ext="tif";
+      if(strncasecmp(pszFormat,"AAIGRID",7)==0)
+	ext="csv";
+      else 
+	if(strncasecmp(pszFormat,"PNG",3)==0)
+	  ext="png";
+	else
+	  if(strncasecmp(pszFormat,"GIF",3)==0)
+	    ext="gif";
+	  else
+	    if(strncasecmp(pszFormat,"JPEG",4)==0)
+	      ext="jpg";
+      sprintf((char*)pszDest,"%s/%s.%s",tempPath,tmpMap->value,ext);
+      fprintf(stderr,"DEBUG pszDest : %s\n",pszDest);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"SrcWin","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      while(t!=NULL){
+	anSrcWin[cnt] = atoi(t);
+	t=strtok(NULL,",");
+	cnt++;
+      }
+    }   
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"ProjWin","value");
+    if(tmpMap!=NULL){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      while(t!=NULL){
+	switch(cnt){
+	case 0:
+	  dfULX = atof(t);
+	  break;
+	case 1:
+	  dfULY = atof(t);
+	  break;
+	case 2:
+	  dfLRX = atof(t);
+	  break;
+	case 3:
+	  dfLRY = atof(t);
+	  break;
+	}
+	t=strtok(NULL,",");
+	cnt++;
+      }
+    }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"GCP","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      map* length=getMapFromMaps(inputs,"GCP","length");
+      int len=0;
+      if(length){
+	len=atoi(length->value);
+	int i;
+	maps* currentMaps=getMaps(inputs,"GCP");
+	for(i=0;i<len;i++){
+	  char* endptr = NULL;
+	  /* -gcp pixel line easting northing [elev] */
+	  
+	  nGCPCount++;
+	  pasGCPs = (GDAL_GCP *) 
+	    realloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
+	  GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
+
+	  map* currentMap=getMapArray(currentMaps->content,"value",i);
+
+	  char* tmpV=strdup(currentMap->value);
+	  char *res=strtok(tmpV,",");
+	  int j=0;
+	  while(res!=NULL){
+	    switch(j){
+	    case 0:
+	      pasGCPs[nGCPCount-1].dfGCPPixel = CPLAtofM(res);
+	      break;
+	    case 1:
+	      pasGCPs[nGCPCount-1].dfGCPLine = CPLAtofM(res);
+	      break;
+	    case 2:
+	      pasGCPs[nGCPCount-1].dfGCPX = CPLAtofM(res);
+	      break;
+	    case 3:
+	      pasGCPs[nGCPCount-1].dfGCPY = CPLAtofM(res);
+	      break;
+	    case 4:
+	      if(res!=NULL && (strtod(res, &endptr) != 0.0 || res[0] == '0'))
+		if (endptr && *endptr == 0)
+		  pasGCPs[nGCPCount-1].dfGCPZ = CPLAtofM(res);
+	      break;
+	    }
+	    res=strtok(NULL,",");
+	    j++;
+	  }
+	}
+      }else{
+	char* endptr = NULL;
+	/* -gcp pixel line easting northing [elev] */
+	
+	nGCPCount++;
+	pasGCPs = (GDAL_GCP *) 
+	  realloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
+	GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
+	
+	char* tmpV=strdup(tmpMap->value);
+	char *res=strtok(tmpV,",");
+	int j=0;
+	while(res!=NULL){
+	  switch(j){
+	  case 0:
+	    pasGCPs[nGCPCount-1].dfGCPPixel = CPLAtofM(res);
+	    break;
+	  case 1:
+	    pasGCPs[nGCPCount-1].dfGCPLine = CPLAtofM(res);
+	    break;
+	  case 2:
+	    pasGCPs[nGCPCount-1].dfGCPX = CPLAtofM(res);
+	    break;
+	  case 3:
+	    pasGCPs[nGCPCount-1].dfGCPY = CPLAtofM(res);
+	    break;
+	  case 4:
+	    if(res!=NULL && (CPLStrtod(res, &endptr) != 0.0 || res[0] == '0'))
+	      if (endptr && *endptr == 0)
+		pasGCPs[nGCPCount-1].dfGCPZ = CPLAtofM(res);
+	    break;
+	  }	    
+	  res=strtok(NULL,",");
+	  j++;
+	}
+      }
+    }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"SRS","value");
+    if(tmpMap!=NULL){
+      OGRSpatialReference oOutputSRS;
+      if( oOutputSRS.SetFromUserInput( tmpMap->value ) != OGRERR_NONE )
+	{
+	  char *msg=(char*)CPLMalloc(100*sizeof(char));
+	  sprintf( msg, "Failed to process SRS definition: %s\n", 
+		   tmpMap->value );
+	  setMapInMaps(conf,"lenv","message",msg);
+	  /**
+	   * Avoiding GDALDestroyDriverManager() call
+	   */
+	  return SERVICE_FAILED;
+	}
+      oOutputSRS.exportToWkt( &pszOutputSRS );
+    }
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"Type","value");
+    if(tmpMap!=NULL){
+      int	iType;
+      
+      for( iType = 1; iType < GDT_TypeCount; iType++ )
+	{
+	  if( GDALGetDataTypeName((GDALDataType)iType) != NULL
+	      && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
+		       tmpMap->value) )
+	    {
+	      eOutputType = (GDALDataType) iType;
+	    }
+	}
+      
+      if( eOutputType == GDT_Unknown )
+	{
+	  printf( "Unknown output pixel type: %s\n", tmpMap->value );
+	  /**
+	   * Avoiding GDALDestroyDriverManager() call
+	   */
+	  exit( 2 );
+	}
+    }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    if( pszDest == NULL ){
+	fprintf(stderr,"exit line 416");
+	fflush(stderr);
+	/**
+	 * Avoiding GDALDestroyDriverManager() call
+	 */
+        exit( 10 );
+      }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    if ( strcmp(pszSource, pszDest) == 0)
+      {
+        fprintf(stderr, "Source and destination datasets must be different.\n");
+	fflush(stderr);
+	/**
+	 * Avoiding GDALDestroyDriverManager() call
+	 */
+        exit( 1 );
+      }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    /* ----------------------------------------------------------------- */
+    /*      Attempt to open source file.                                 */
+    /* ----------------------------------------------------------------- */
+
+    hDataset = GDALOpenShared( pszSource, GA_ReadOnly );
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    
+    if( hDataset == NULL ){
+      char *msg=(char*) CPLMalloc(1024*sizeof(char));
+      sprintf( msg,
+	       "GDALOpen failed - %d\n%s\n",
+	       CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
+      setMapInMaps(conf,"lenv","message",msg);
+      return SERVICE_FAILED;
+    }
+
+    fprintf(stderr,"DEBUG pszDest : %s %d\n",pszDest,__LINE__);
+    /* ----------------------------------------------------------------- */
+    /*      Handle subdatasets.                                          */
+    /* ----------------------------------------------------------------- */
+    if( !bCopySubDatasets 
+        && CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 
+        && GDALGetRasterCount(hDataset) == 0 )
+      {
+	char *msg=(char*) CPLMalloc(1024*sizeof(char));
+        sprintf( msg,
+                 "Input file contains subdatasets. Please, select one of them for reading.\n" );
+	setMapInMaps(conf,"lenv","message",msg);
+        GDALClose( hDataset );
+	/**
+	 * Avoiding GDALDestroyDriverManager() call
+	 */
+        exit( 1 );
+      }
+
+    if( CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 
+        && bCopySubDatasets )
+      {
+        char **papszSubdatasets = GDALGetMetadata(hDataset,"SUBDATASETS");
+        char *pszSubDest = (char *) CPLMalloc(strlen(pszDest)+32);
+        int i;
+        int bOldSubCall = bSubCall;
+        
+        //argv[iDstFileArg] = pszSubDest;
+        bSubCall = TRUE;
+        for( i = 0; papszSubdatasets[i] != NULL; i += 2 )
+	  {
+            //argv[iSrcFileArg] = strstr(papszSubdatasets[i],"=")+1;
+            sprintf( pszSubDest, "%s%d", pszDest, i/2 + 1 );
+            /*if( ProxyMain( argc, argv ) != 0 )
+	      break;*/
+	  }
+        
+        bSubCall = bOldSubCall;
+        free( pszSubDest );
+
+        GDALClose( hDataset );
+
+        if( !bSubCall )
+	  {
+            GDALDumpOpenDatasets( stderr );
+	    fflush(stderr);
+	    /**
+	     * Avoiding GDALDestroyDriverManager() call
+	     */
+	  }
+        return 1;
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Collect some information from the source file.               */
+    /* ----------------------------------------------------------------- */
+    nRasterXSize = GDALGetRasterXSize( hDataset );
+    nRasterYSize = GDALGetRasterYSize( hDataset );
+
+    if( !bQuiet )
+      fprintf( stderr, "Input file size is %d, %d\n", nRasterXSize, nRasterYSize );
+
+    if( anSrcWin[2] == 0 && anSrcWin[3] == 0 ){
+        anSrcWin[2] = nRasterXSize;
+        anSrcWin[3] = nRasterYSize;
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*	Build band list to translate	                                 */
+    /* ----------------------------------------------------------------- */
+    if( nBandCount == 0 ){
+        nBandCount = GDALGetRasterCount( hDataset );
+        if( nBandCount == 0 ){
+            fprintf( stderr, "Input file has no bands, and so cannot be translated.\n" );
+	    fflush(stderr);
+	    /**
+	     * Avoiding GDALDestroyDriverManager() call
+	     */
+            exit(1 );
+	  }
+
+        panBandList = (int *) CPLMalloc(sizeof(int)*nBandCount);
+        for( i = 0; i < nBandCount; i++ )
+	  panBandList[i] = i+1;
+      }
+    else
+      {
+        for( i = 0; i < nBandCount; i++ )
+	  {
+            if( panBandList[i] < 1 || panBandList[i] > GDALGetRasterCount(hDataset) )
+	      {
+                fprintf( stderr, 
+                         "Band %d requested, but only bands 1 to %d available.\n",
+                         panBandList[i], GDALGetRasterCount(hDataset) );
+		fflush(stderr);
+		/**
+		 * Avoiding GDALDestroyDriverManager() call
+		 */
+                exit( 2 );
+	      }
+	  }
+
+        if( nBandCount != GDALGetRasterCount( hDataset ) )
+	  bDefBands = FALSE;
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*   Compute the source window from the projected source window      */
+    /*   if the projected coordinates were provided.  Note that the      */
+    /*   projected coordinates are in ulx, uly, lrx, lry format,         */
+    /*   while the anSrcWin is xoff, yoff, xsize, ysize with the         */
+    /*   xoff,yoff being the ulx, uly in pixel/line.                     */
+    /* ----------------------------------------------------------------- */
+    if( dfULX != 0.0 || dfULY != 0.0 
+        || dfLRX != 0.0 || dfLRY != 0.0 )
+      {
+        double	adfGeoTransform[6];
+
+        GDALGetGeoTransform( hDataset, adfGeoTransform );
+
+        if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ){
+            fprintf( stderr, 
+                     "The -projwin option was used, but the geotransform is\n"
+                     "rotated.  This configuration is not supported.\n" );
+            GDALClose( hDataset );
+            free( panBandList );
+	    fflush(stderr);
+	    /**
+	     * Avoiding GDALDestroyDriverManager() call
+	     */
+            exit( 1 );
+	  }
+
+        anSrcWin[0] = (int) 
+	  ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
+        anSrcWin[1] = (int) 
+	  ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);
+
+        anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5);
+        anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5);
+
+        if( !bQuiet )
+	  fprintf( stdout, 
+		   "Computed -srcwin %d %d %d %d from projected window.\n",
+		   anSrcWin[0], 
+		   anSrcWin[1], 
+		   anSrcWin[2], 
+		   anSrcWin[3] );
+        
+        if( anSrcWin[0] < 0 || anSrcWin[1] < 0 
+            || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) 
+            || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset) )
+	  {
+            fprintf( stderr, 
+                     "Computed -srcwin falls outside raster size of %dx%d.\n",
+                     GDALGetRasterXSize(hDataset), 
+                     GDALGetRasterYSize(hDataset) );
+            exit( 1 );
+	  }
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Verify source window.                                        */
+    /* ----------------------------------------------------------------- */
+    if( anSrcWin[0] < 0 || anSrcWin[1] < 0 
+        || anSrcWin[2] <= 0 || anSrcWin[3] <= 0
+        || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) 
+        || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset) )
+      {
+        fprintf( stderr, 
+                 "-srcwin %d %d %d %d falls outside raster size of %dx%d\n"
+                 "or is otherwise illegal.\n",
+                 anSrcWin[0],
+                 anSrcWin[1],
+                 anSrcWin[2],
+                 anSrcWin[3],
+                 GDALGetRasterXSize(hDataset), 
+                 GDALGetRasterYSize(hDataset) );
+        exit( 1 );
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Find the output driver.                                      */
+    /* ----------------------------------------------------------------- */
+    hDriver = GDALGetDriverByName( pszFormat );
+    if( hDriver == NULL )
+      {
+        int	iDr;
+        
+	char* msg=(char*) CPLMalloc(4096*sizeof(char));
+	sprintf(msg,"Output driver `%s' not recognised.\nThe following format drivers are configured and support output:\n",pszFormat);
+        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
+	  {
+            GDALDriverH hDriver = GDALGetDriver(iDr);
+
+            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
+                || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
+                                        NULL ) != NULL )
+	      {
+		fprintf(stderr,msg);
+		char *tmp=strdup(msg);
+                sprintf( msg,"%s  %s: %s\n",tmp,
+                        GDALGetDriverShortName( hDriver  ),
+                        GDALGetDriverLongName( hDriver ) );
+		free(tmp);
+	      }
+	  }
+	setMapInMaps(conf,"lenv","message",msg);
+        GDALClose( hDataset );
+        free( panBandList );
+	fflush(stderr);
+	/**
+	 * Avoiding GDALDestroyDriverManager() call
+	 */
+        CSLDestroy( papszCreateOptions );
+        return 4;
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*   The short form is to CreateCopy().  We use this if the input    */
+    /*   matches the whole dataset.  Eventually we should rewrite        */
+    /*   this entire program to use virtual datasets to construct a      */
+    /*   virtual input source to copy from.                              */
+    /* ----------------------------------------------------------------- */
+    int bSpatialArrangementPreserved = (
+           anSrcWin[0] == 0 && anSrcWin[1] == 0
+        && anSrcWin[2] == GDALGetRasterXSize(hDataset)
+        && anSrcWin[3] == GDALGetRasterYSize(hDataset)
+        && pszOXSize == NULL && pszOYSize == NULL );
+
+    if( eOutputType == GDT_Unknown 
+        && !bScale && CSLCount(papszMetadataOptions) == 0 && bDefBands 
+        && bSpatialArrangementPreserved
+        && nGCPCount == 0 && !bGotBounds
+        && pszOutputSRS == NULL && !bSetNoData
+        && nRGBExpand == 0)
+      {
+        
+        hOutDS = GDALCreateCopy( hDriver, pszDest, hDataset, 
+                                 FALSE, (char**)0, 
+                                 pfnProgress, NULL );
+
+        if( hOutDS != NULL )
+	  GDALClose( hOutDS );
+        
+        GDALClose( hDataset );
+
+        free( panBandList );
+
+        if( !bSubCall )
+	  {
+            GDALDumpOpenDatasets( stderr );
+	    /**
+	     * Avoiding GDALDestroyDriverManager() call
+	     */
+	  }
+	fprintf(stderr,"==%s %s %s %d==\n",pszFormat,pszSource,pszDest,__LINE__);
+	fflush(stderr);
+
+        CSLDestroy( papszCreateOptions );
+	fprintf(stderr,"==%s %s %s %d==\n",pszFormat,pszSource,pszDest,__LINE__);
+	fflush(stderr);
+	//outputs=(maps*)CPLMalloc(sizeof(maps*));
+	//outputs->name="OutputedPolygon";
+	//outputs->content=createMap("value",(char*)pszDest);
+	//outputs->next=NULL;
+	dumpMaps(outputs);
+	setMapInMaps(outputs,"Result","value",(char*)pszDest);
+	return SERVICE_SUCCEEDED;
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Establish some parameters.                                   */
+    /* ----------------------------------------------------------------- */
+    if( pszOXSize == NULL )
+      {
+        nOXSize = anSrcWin[2];
+        nOYSize = anSrcWin[3];
+      }
+    else
+      {
+        nOXSize = (int) ((pszOXSize[strlen(pszOXSize)-1]=='%' 
+                          ? atof(pszOXSize)/100*anSrcWin[2] : atoi(pszOXSize)));
+        nOYSize = (int) ((pszOYSize[strlen(pszOYSize)-1]=='%' 
+                          ? atof(pszOYSize)/100*anSrcWin[3] : atoi(pszOYSize)));
+      }
+
+    /* ================================================================= */
+    /*      Create a virtual dataset.                                    */
+    /* ================================================================= */
+    VRTDataset *poVDS;
+        
+    /* ----------------------------------------------------------------- */
+    /*      Make a virtual clone.                                        */
+    /* ----------------------------------------------------------------- */
+    poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize );
+
+    if( nGCPCount == 0 )
+      {
+        if( pszOutputSRS != NULL )
+	  {
+            poVDS->SetProjection( pszOutputSRS );
+	  }
+        else
+	  {
+            pszProjection = GDALGetProjectionRef( hDataset );
+            if( pszProjection != NULL && strlen(pszProjection) > 0 )
+	      poVDS->SetProjection( pszProjection );
+	  }
+      }
+
+    if( bGotBounds )
+      {
+        adfGeoTransform[0] = adfULLR[0];
+        adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize;
+        adfGeoTransform[2] = 0.0;
+        adfGeoTransform[3] = adfULLR[1];
+        adfGeoTransform[4] = 0.0;
+        adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize;
+
+        poVDS->SetGeoTransform( adfGeoTransform );
+      }
+
+    else if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None 
+	     && nGCPCount == 0 )
+      {
+        adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1]
+	  + anSrcWin[1] * adfGeoTransform[2];
+        adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4]
+	  + anSrcWin[1] * adfGeoTransform[5];
+        
+        adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
+        adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
+        adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
+        adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;
+        
+        poVDS->SetGeoTransform( adfGeoTransform );
+      }
+
+    if( nGCPCount != 0 )
+      {
+        const char *pszGCPProjection = pszOutputSRS;
+
+        if( pszGCPProjection == NULL )
+	  pszGCPProjection = GDALGetGCPProjection( hDataset );
+        if( pszGCPProjection == NULL )
+	  pszGCPProjection = "";
+
+        poVDS->SetGCPs( nGCPCount, pasGCPs, pszGCPProjection );
+
+        GDALDeinitGCPs( nGCPCount, pasGCPs );
+        free( pasGCPs );
+      }
+
+    else if( GDALGetGCPCount( hDataset ) > 0 )
+      {
+        GDAL_GCP *pasGCPs;
+        int       nGCPs = GDALGetGCPCount( hDataset );
+
+        pasGCPs = GDALDuplicateGCPs( nGCPs, GDALGetGCPs( hDataset ) );
+
+        for( i = 0; i < nGCPs; i++ )
+	  {
+            pasGCPs[i].dfGCPPixel -= anSrcWin[0];
+            pasGCPs[i].dfGCPLine  -= anSrcWin[1];
+            pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] );
+            pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3] );
+	  }
+            
+        poVDS->SetGCPs( nGCPs, pasGCPs,
+                        GDALGetGCPProjection( hDataset ) );
+
+        GDALDeinitGCPs( nGCPs, pasGCPs );
+        free( pasGCPs );
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Transfer generally applicable metadata.                      */
+    /* ----------------------------------------------------------------- */
+    poVDS->SetMetadata( ((GDALDataset*)hDataset)->GetMetadata() );
+    AttachMetadata( (GDALDatasetH) poVDS, papszMetadataOptions );
+
+    /* ----------------------------------------------------------------- */
+    /*      Transfer metadata that remains valid if the spatial          */
+    /*      arrangement of the data is unaltered.                        */
+    /* ----------------------------------------------------------------- */
+    if( anSrcWin[0] == 0 && anSrcWin[1] == 0 
+        && anSrcWin[2] == GDALGetRasterXSize(hDataset)
+        && anSrcWin[3] == GDALGetRasterYSize(hDataset) 
+        && pszOXSize == NULL && pszOYSize == NULL )
+      {
+        char **papszMD;
+
+        papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC");
+        if( papszMD != NULL )
+	  poVDS->SetMetadata( papszMD, "RPC" );
+      }
+
+    if (nRGBExpand != 0)
+      nBandCount += nRGBExpand - 1;
+
+    /* ================================================================= */
+    /*      Process all bands.                                           */
+    /* ================================================================= */
+    for( i = 0; i < nBandCount; i++ )
+      {
+        VRTSourcedRasterBand   *poVRTBand;
+        GDALRasterBand  *poSrcBand;
+        GDALDataType    eBandType;
+
+        if (nRGBExpand != 0 && i < nRGBExpand)
+	  {
+            poSrcBand = ((GDALDataset *) 
+			 hDataset)->GetRasterBand(panBandList[0]);
+            if (poSrcBand->GetColorTable() == NULL)
+	      {
+                fprintf(stderr, "Error : band %d has no color table\n", panBandList[0]);
+                GDALClose( hDataset );
+                free( panBandList );
+		fflush(stderr);
+		/**
+		 * Avoiding GDALDestroyDriverManager() call
+		 */
+                CSLDestroy( papszCreateOptions );
+                exit( 1 );
+	      }
+	  }
+        else
+	  poSrcBand = ((GDALDataset *) 
+		       hDataset)->GetRasterBand(panBandList[i]);
+
+	/* ------------------------------------------------------------ */
+	/*      Select output data type to match source.                */
+	/* ------------------------------------------------------------ */
+        if( eOutputType == GDT_Unknown )
+	  eBandType = poSrcBand->GetRasterDataType();
+        else
+	  eBandType = eOutputType;
+
+	/* ------------------------------------------------------------ */
+	/*      Create this band.                                       */
+	/* ------------------------------------------------------------ */
+        poVDS->AddBand( eBandType, NULL );
+        poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i+1 );
+            
+	/* ------------------------------------------------------------ */
+	/*      Do we need to collect scaling information?              */
+	/* ------------------------------------------------------------ */
+        double dfScale=1.0, dfOffset=0.0;
+
+        if( bScale && !bHaveScaleSrc )
+	  {
+            double	adfCMinMax[2];
+            GDALComputeRasterMinMax( poSrcBand, TRUE, adfCMinMax );
+            dfScaleSrcMin = adfCMinMax[0];
+            dfScaleSrcMax = adfCMinMax[1];
+	  }
+
+        if( bScale )
+	  {
+            if( dfScaleSrcMax == dfScaleSrcMin )
+	      dfScaleSrcMax += 0.1;
+            if( dfScaleDstMax == dfScaleDstMin )
+	      dfScaleDstMax += 0.1;
+
+            dfScale = (dfScaleDstMax - dfScaleDstMin) 
+	      / (dfScaleSrcMax - dfScaleSrcMin);
+            dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin;
+	  }
+
+	/* ------------------------------------------------------------ */
+	/*      Create a simple or complex data source depending on the */
+	/*      translation type required.                              */
+	/* ------------------------------------------------------------ */
+        if( bScale || (nRGBExpand != 0 && i < nRGBExpand) )
+	  {
+            poVRTBand->AddComplexSource( poSrcBand,
+                                         anSrcWin[0], anSrcWin[1], 
+                                         anSrcWin[2], anSrcWin[3], 
+                                         0, 0, nOXSize, nOYSize,
+                                         dfOffset, dfScale,
+                                         VRT_NODATA_UNSET,
+                                         (nRGBExpand != 0 && i < nRGBExpand) ? i + 1 : 0 );
+	  }
+        else
+	  poVRTBand->AddSimpleSource( poSrcBand,
+				      anSrcWin[0], anSrcWin[1], 
+				      anSrcWin[2], anSrcWin[3], 
+				      0, 0, nOXSize, nOYSize );
+
+        /* In case of color table translate, we only set the color interpretation */
+        /* other info copied by CopyCommonInfoFrom are not relevant in RGB expansion */
+        if (nRGBExpand != 0 && i < nRGBExpand)
+	  {
+            poVRTBand->SetColorInterpretation( (GDALColorInterp) (GCI_RedBand + i) );
+	  }
+        else
+	  {
+	    /* --------------------------------------------------------- */
+	    /*      copy over some other information of interest.        */
+	    /* --------------------------------------------------------- */
+            poVRTBand->CopyCommonInfoFrom( poSrcBand );
+	  }
+
+	/* ------------------------------------------------------------- */
+	/*      Set a forcable nodata value?                             */
+	/* ------------------------------------------------------------- */
+        if( bSetNoData )
+	  poVRTBand->SetNoDataValue( dfNoDataReal );
+      }
+
+    /* ----------------------------------------------------------------- */
+    /*      Write to the output file using CopyCreate().                 */
+    /* ----------------------------------------------------------------- */
+    hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS,
+                             bStrict, papszCreateOptions, 
+                             pfnProgress, NULL );
+
+    if( hOutDS != NULL )
+      {
+        GDALClose( hOutDS );
+      }
+    
+    GDALClose( (GDALDatasetH) poVDS );
+         
+    GDALClose( hDataset );
+   
+    free( panBandList );
+    
+    free( pszOutputSRS );
+
+    if( !bSubCall )
+      {
+        GDALDumpOpenDatasets( stderr );
+	fflush(stderr);
+	/**
+	 * Avoiding GDALDestroyDriverManager() call
+	 */
+      }
+
+    CSLDestroy( papszCreateOptions );
+    
+    setMapInMaps(outputs,"Result","value",(char*)pszDest);
+
+    return SERVICE_SUCCEEDED;
+  }
+
+
+  /************************************************************************/
+  /*                           AttachMetadata()                           */
+  /************************************************************************/
+
+  static void AttachMetadata( GDALDatasetH hDS, char **papszMetadataOptions )
+
+  {
+    int nCount = CSLCount(papszMetadataOptions);
+    int i;
+
+    for( i = 0; i < nCount; i++ )
+      {
+        char    *pszKey = NULL;
+        const char *pszValue;
+        
+        pszValue = CPLParseNameValue( papszMetadataOptions[i], &pszKey );
+        GDALSetMetadataItem(hDS,pszKey,pszValue,NULL);
+        free( pszKey );
+      }
+
+    CSLDestroy( papszMetadataOptions );
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/Makefile	(revision 672)
@@ -0,0 +1,15 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/warp_service.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/warp_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/gdal/warp
+	install cgi-env/* ${CGI_DIR}/gdal/warp
+
+
+clean:
+	rm -f cgi-env/warp_service.*
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/cgi-env/Gdal_Warp.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/cgi-env/Gdal_Warp.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/cgi-env/Gdal_Warp.zcfg	(revision 672)
@@ -0,0 +1,129 @@
+[Gdal_Warp]
+ Title = GDAL Warp Tool
+ Abstract = The gdalwarp utility is an image mosaicing, reprojection and warping utility. The program can reproject to any supported projection, and can also apply GCPs stored with the image if the image is "raw" with control information.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = warp_service.zo
+ <DataInputs>
+  [Format]
+   Title = Format of the output data
+   Abstract = Select the output format by usig short name of the format (use gda-config --formats for list of available formats on your platform).
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value = GTiff
+    </Default>
+   </LiteralData>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [s_srs]
+   Title = The source Spatial reference Set
+   Abstract = The coordinate systems that can be passed are anything supported by the OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes (ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file containing well known text.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [t_srs]
+   Title = The target Spatial reference Set
+   Abstract = The coordinate systems that can be passed are anything supported by the OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes (ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file containing well known text.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+  [tps]
+   Title = Thin Plate Spline
+   Abstract = Force use of thin plate spline transformer based on available GCPs
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = boolean
+    <Default />
+   </LiteralData>
+  [geoloc]
+   Title = Geolocation
+   Abstract = Force use of Geolocation Arrays
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = boolean
+    <Default />
+   </LiteralData>
+  [rpc]
+   Title = RPCs
+   Abstract =  Force use of RPCs
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = boolean
+    <Default />
+   </LiteralData>
+  [r]
+   Title = Resampling method to use
+   Abstract = Available methods are: near (nearest neighbour resampling - default, fastest algorithm, worst interpolation quality), bilinear, cubic, cubicspline, lanczos (Lanczos windowed sinc resampling)
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = boolean
+    <Default />
+   </LiteralData>
+  [order]
+   Title = The order of polynomial used for warping (1 to 3)
+   Abstract = The default is to select a polynomial order based on the number of GCPs.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value=1
+    </Default>
+    <Supported>
+     value=2
+    </Supported>
+    <Supported>
+     value=3
+    </Supported>
+   </LiteralData>
+  [te]
+   Title = xmin,ymin,xmax,ymax
+   Abstract = set georeferenced extents of output file to be created (in target SRS).
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default />
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/makefile.vc	(revision 672)
@@ -0,0 +1,23 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/warp_service.zo: service.c
+	$(CPP)  /DOGR_ENABLED /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/ -I$(GDAL_DIR)/alg/ $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/warp_service.zo  $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\warp_service.*
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/gdal/warp/service.c	(revision 672)
@@ -0,0 +1,2150 @@
+/******************************************************************************
+ * $Id: gdalwarp.cpp 24214 2012-04-08 20:17:17Z etourigny $
+ *
+ * Project:  High Performance Image Reprojector
+ * Purpose:  Test program for high performance warper API.
+ * Author:   Frank Warmerdam <warmerdam@pobox.com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2002, i3 - information integration and imaging 
+ *                          Fort Collin, CO
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "gdalwarper.h"
+#include "cpl_string.h"
+#include "ogr_spatialref.h"
+#include "ogr_api.h"
+#include <vector>
+#include "service.h"
+
+CPL_CVSID("$Id: gdalwarp.cpp 24214 2012-04-08 20:17:17Z etourigny $");
+
+extern "C"{
+static void
+LoadCutline( const char *pszCutlineDSName, const char *pszCLayer, 
+             const char *pszCWHERE, const char *pszCSQL, 
+             void **phCutlineRet );
+static void
+TransformCutlineToSource( GDALDatasetH hSrcDS, void *hCutline,
+                          char ***ppapszWarpOptions, char **papszTO );
+
+static GDALDatasetH 
+GDALWarpCreateOutput( maps*& conf,char **papszSrcFiles, const char *pszFilename, 
+                      const char *pszFormat, char **papszTO,
+                      char ***ppapszCreateOptions, GDALDataType eDT,
+                      void ** phTransformArg,
+                      GDALDatasetH* phSrcDS );
+
+static double	       dfMinX=0.0, dfMinY=0.0, dfMaxX=0.0, dfMaxY=0.0;
+static double	       dfXRes=0.0, dfYRes=0.0;
+static int             bTargetAlignedPixels = FALSE;
+static int             nForcePixels=0, nForceLines=0, bQuiet = FALSE;
+static int             bEnableDstAlpha = FALSE, bEnableSrcAlpha = FALSE;
+
+static int             bVRT = FALSE;
+
+/******************************************************************************/
+/*! \page gdalwarp gdalwarp
+
+image reprojection and warping utility
+
+\section gdalwarp_synopsis SYNOPSIS
+
+\htmlonly
+Usage: 
+\endhtmlonly
+
+\verbatim
+gdalwarp [--help-general] [--formats]
+    [-s_srs srs_def] [-t_srs srs_def] [-to "NAME=VALUE"]
+    [-order n | -tps | -rpc | -geoloc] [-et err_threshold]
+    [-refine_gcps tolerance [minimum_gcps]]
+    [-te xmin ymin xmax ymax] [-tr xres yres] [-tap] [-ts width height]
+    [-wo "NAME=VALUE"] [-ot Byte/Int16/...] [-wt Byte/Int16]
+    [-srcnodata "value [value...]"] [-dstnodata "value [value...]"] -dstalpha
+    [-r resampling_method] [-wm memory_in_mb] [-multi] [-q]
+    [-cutline datasource] [-cl layer] [-cwhere expression]
+    [-csql statement] [-cblend dist_in_pixels] [-crop_to_cutline]
+    [-of format] [-co "NAME=VALUE"]* [-overwrite]
+    srcfile* dstfile
+\endverbatim
+
+\section gdalwarp_description DESCRIPTION
+
+<p>
+The gdalwarp utility is an image mosaicing, reprojection and warping
+utility. The program can reproject to any supported projection,
+and can also apply GCPs stored with the image if the image is "raw"
+with control information.
+
+<p>
+<dl>
+<dt> <b>-s_srs</b> <em>srs def</em>:</dt><dd> source spatial reference set.
+The coordinate systems that can be passed are anything supported by the
+OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes
+(ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file
+containing well known text.</dd>
+<dt> <b>-t_srs</b> <em>srs_def</em>:</dt><dd> target spatial reference set.
+The coordinate systems that can be passed are anything supported by the
+OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes
+(ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file
+containing well known text.</dd>
+<dt> <b>-to</b> <em>NAME=VALUE</em>:</dt><dd> set a transformer option suitable
+to pass to GDALCreateGenImgProjTransformer2(). </dd>
+<dt> <b>-order</b> <em>n</em>:</dt><dd> order of polynomial used for warping
+(1 to 3). The default is to select a polynomial order based on the number of
+GCPs.</dd>
+<dt> <b>-tps</b>:</dt><dd>Force use of thin plate spline transformer based on
+available GCPs.</dd>
+<dt> <b>-rpc</b>:</dt> <dd>Force use of RPCs.</dd>
+<dt> <b>-geoloc</b>:</dt><dd>Force use of Geolocation Arrays.</dd>
+<dt> <b>-et</b> <em>err_threshold</em>:</dt><dd> error threshold for
+transformation approximation (in pixel units - defaults to 0.125).</dd>
+<dt> <b>-refine_gcps</b> <em>tolerance minimum_gcps</em>:</dt><dd>  (GDAL >= 1.9.0) refines the GCPs by automatically eliminating outliers.
+Outliers will be eliminated until minimum_gcps are left or when no outliers can be detected.
+The tolerance is passed to adjust when a GCP will be eliminated.
+Not that GCP refinement only works with polynomial interpolation.
+The tolerance is in pixel units if no projection is available, otherwise it is in SRS units.
+If minimum_gcps is not provided, the minimum GCPs according to the polynomial model is used.</dd>
+<dt> <b>-te</b> <em>xmin ymin xmax ymax</em>:</dt><dd> set georeferenced
+extents of output file to be created (in target SRS).</dd>
+<dt> <b>-tr</b> <em>xres yres</em>:</dt><dd> set output file resolution (in
+target georeferenced units)</dd>
+<dt> <b>-tap</b>:</dt><dd> (GDAL >= 1.8.0) (target aligned pixels) align
+the coordinates of the extent of the output file to the values of the -tr,
+such that the aligned extent includes the minimum extent.</dd>
+<dt> <b>-ts</b> <em>width height</em>:</dt><dd> set output file size in
+pixels and lines. If width or height is set to 0, the other dimension will be
+guessed from the computed resolution. Note that -ts cannot be used with -tr</dd>
+<dt> <b>-wo</b> <em>"NAME=VALUE"</em>:</dt><dd> Set a warp options.  The 
+GDALWarpOptions::papszWarpOptions docs show all options.  Multiple
+ <b>-wo</b> options may be listed.</dd>
+<dt> <b>-ot</b> <em>type</em>:</dt><dd> For the output bands to be of the
+indicated data type.</dd>
+<dt> <b>-wt</b> <em>type</em>:</dt><dd> Working pixel data type. The data type
+of pixels in the source image and destination image buffers.</dd>
+<dt> <b>-srcnodata</b> <em>value [value...]</em>:</dt><dd> Set nodata masking
+values for input bands (different values can be supplied for each band).  If 
+more than one value is supplied all values should be quoted to keep them 
+together as a single operating system argument.  Masked values will not be 
+used in interpolation.  Use a value of <tt>None</tt> to ignore intrinsic nodata settings on the source dataset.</dd>
+<dt> <b>-dstnodata</b> <em>value [value...]</em>:</dt><dd> Set nodata values
+for output bands (different values can be supplied for each band).  If more
+than one value is supplied all values should be quoted to keep them together
+as a single operating system argument.  New files will be initialized to this
+value and if possible the nodata value will be recorded in the output
+file.</dd>
+<dt> <b>-dstalpha</b>:</dt><dd> Create an output alpha band to identify 
+nodata (unset/transparent) pixels. </dd>
+<dt> <b>-wm</b> <em>memory_in_mb</em>:</dt><dd> Set the amount of memory (in
+megabytes) that the warp API is allowed to use for caching.</dd>
+<dt> <b>-multi</b>:</dt><dd> Use multithreaded warping implementation.
+Multiple threads will be used to process chunks of image and perform
+input/output operation simultaneously.</dd>
+<dt> <b>-q</b>:</dt><dd> Be quiet.</dd>
+<dt> <b>-of</b> <em>format</em>:</dt><dd> Select the output format. The default is GeoTIFF (GTiff). Use the short format name. </dd>
+<dt> <b>-co</b> <em>"NAME=VALUE"</em>:</dt><dd> passes a creation option to
+the output format driver. Multiple <b>-co</b> options may be listed. See
+format specific documentation for legal creation options for each format.
+</dd>
+
+<dt> <b>-cutline</b> <em>datasource</em>:</dt><dd>Enable use of a blend cutline from the name OGR support datasource.</dd>
+<dt> <b>-cl</b> <em>layername</em>:</dt><dd>Select the named layer from the 
+cutline datasource.</dd>
+<dt> <b>-cwhere</b> <em>expression</em>:</dt><dd>Restrict desired cutline features based on attribute query.</dd>
+<dt> <b>-csql</b> <em>query</em>:</dt><dd>Select cutline features using an SQL query instead of from a layer with -cl.</dd>
+<dt> <b>-cblend</b> <em>distance</em>:</dt><dd>Set a blend distance to use to blend over cutlines (in pixels).</dd>
+<dt> <b>-crop_to_cutline</b>:</dt><dd>(GDAL >= 1.8.0) Crop the extent of the target dataset to the extent of the cutline.</dd>
+<dt> <b>-overwrite</b>:</dt><dd>(GDAL >= 1.8.0) Overwrite the target dataset if it already exists.</dd>
+
+<dt> <em>srcfile</em>:</dt><dd> The source file name(s). </dd>
+<dt> <em>dstfile</em>:</dt><dd> The destination file name. </dd>
+</dl>
+
+Mosaicing into an existing output file is supported if the output file 
+already exists. The spatial extent of the existing file will not
+be modified to accomodate new data, so you may have to remove it in that case, or
+use the -overwrite option.
+
+Polygon cutlines may be used as a mask to restrict the area of the destination file
+that may be updated, including blending.  If the OGR layer containing the cutline
+features has no explicit SRS, the cutline features must be in the georeferenced
+units of the destination file. When outputing to a not yet existing target dataset,
+its extent will be the one of the original raster unless -te or -crop_to_cutline are
+specified.
+
+<p>
+\section gdalwarp_example EXAMPLE
+
+For instance, an eight bit spot scene stored in GeoTIFF with
+control points mapping the corners to lat/long could be warped to a UTM
+projection with a command like this:<p>
+
+\verbatim
+gdalwarp -t_srs '+proj=utm +zone=11 +datum=WGS84' raw_spot.tif utm11.tif
+\endverbatim
+
+For instance, the second channel of an ASTER image stored in HDF with
+control points mapping the corners to lat/long could be warped to a UTM
+projection with a command like this:<p>
+
+\verbatim
+gdalwarp HDF4_SDS:ASTER_L1B:"pg-PR1B0000-2002031402_100_001":2 pg-PR1B0000-2002031402_100_001_2.tif
+\endverbatim
+
+\if man
+\section gdalwarp_author AUTHORS
+Frank Warmerdam <warmerdam@pobox.com>, Silke Reimer <silke@intevation.de>
+\endif
+*/
+
+/************************************************************************/
+/*                               GDALExit()                             */
+/*  This function exits and cleans up GDAL and OGR resources            */
+/*  Perhaps it should be added to C api and used in all apps?           */
+/************************************************************************/
+
+static int GDALExit( int nCode )
+{
+  const char  *pszDebug = CPLGetConfigOption("CPL_DEBUG",NULL);
+  if( pszDebug && (EQUAL(pszDebug,"ON") || EQUAL(pszDebug,"") ) )
+  {  
+    GDALDumpOpenDatasets( stderr );
+    CPLDumpSharedList( NULL );
+  }
+
+  GDALDestroyDriverManager();
+
+#ifdef OGR_ENABLED
+  OGRCleanupAll();
+#endif
+
+  return SERVICE_FAILED;
+}
+
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage()
+
+{
+    printf( 
+        "Usage: gdalwarp [--help-general] [--formats]\n"
+        "    [-s_srs srs_def] [-t_srs srs_def] [-to \"NAME=VALUE\"]\n"
+        "    [-order n | -tps | -rpc | -geoloc] [-et err_threshold]\n"
+        "    [-refine_gcps tolerance [minimum_gcps]]\n"
+        "    [-te xmin ymin xmax ymax] [-tr xres yres] [-tap] [-ts width height]\n"
+        "    [-wo \"NAME=VALUE\"] [-ot Byte/Int16/...] [-wt Byte/Int16]\n"
+        "    [-srcnodata \"value [value...]\"] [-dstnodata \"value [value...]\"] -dstalpha\n" 
+        "    [-r resampling_method] [-wm memory_in_mb] [-multi] [-q]\n"
+        "    [-cutline datasource] [-cl layer] [-cwhere expression]\n"
+        "    [-csql statement] [-cblend dist_in_pixels] [-crop_to_cutline]\n"
+        "    [-of format] [-co \"NAME=VALUE\"]* [-overwrite]\n"
+        "    srcfile* dstfile\n"
+        "\n"
+        "Available resampling methods:\n"
+        "    near (default), bilinear, cubic, cubicspline, lanczos.\n" );
+    GDALExit( 1 );
+}
+
+/************************************************************************/
+/*                             SanitizeSRS                              */
+/************************************************************************/
+
+char *SanitizeSRS( const char *pszUserInput )
+
+{
+    OGRSpatialReferenceH hSRS;
+    char *pszResult = NULL;
+
+    CPLErrorReset();
+    
+    hSRS = OSRNewSpatialReference( NULL );
+    if( OSRSetFromUserInput( hSRS, pszUserInput ) == OGRERR_NONE )
+        OSRExportToWkt( hSRS, &pszResult );
+    else
+    {
+        CPLError( CE_Failure, CPLE_AppDefined,
+                  "Translating source or target SRS failed:\n%s",
+                  pszUserInput );
+        GDALExit( 1 );
+    }
+    
+    OSRDestroySpatialReference( hSRS );
+
+    return pszResult;
+}
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+int Gdal_Warp( maps*& conf,maps*& inputs,maps*& outputs )
+
+{
+    GDALDatasetH	hDstDS;
+    const char         *pszFormat = "GTiff";
+    int bFormatExplicitelySet = FALSE;
+    char              **papszSrcFiles = NULL;
+    char               *pszDstFilename = NULL;
+    int                 bCreateOutput = FALSE, i;
+    void               *hTransformArg, *hGenImgProjArg=NULL, *hApproxArg=NULL;
+    char               **papszWarpOptions = NULL;
+    double             dfErrorThreshold = 0.125;
+    double             dfWarpMemoryLimit = 0.0;
+    GDALTransformerFunc pfnTransformer = NULL;
+    char                **papszCreateOptions = NULL;
+    GDALDataType        eOutputType = GDT_Unknown, eWorkingType = GDT_Unknown; 
+    GDALResampleAlg     eResampleAlg = GRA_NearestNeighbour;
+    const char          *pszSrcNodata = NULL;
+    const char          *pszDstNodata = NULL;
+    int                 bMulti = FALSE;
+    char                **papszTO = NULL;
+    char                *pszCutlineDSName = NULL;
+    char                *pszCLayer = NULL, *pszCWHERE = NULL, *pszCSQL = NULL;
+    void                *hCutline = NULL;
+    int                  bHasGotErr = FALSE;
+    int                  bCropToCutline = FALSE;
+    int                  bOverwrite = FALSE;
+
+
+    /* Check that we are running against at least GDAL 1.6 */
+    /* Note to developers : if we use newer API, please change the requirement */
+    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1600)
+    {
+        fprintf(stderr, "At least, GDAL >= 1.6.0 is required for this version of warp_service.zo, "
+                "which was compiled against GDAL %s\n", GDAL_RELEASE_NAME);
+        GDALExit(1);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Register standard GDAL drivers, and process generic GDAL        */
+/*      command options.                                                */
+/* -------------------------------------------------------------------- */
+    GDALAllRegister();
+
+/* -------------------------------------------------------------------- */
+/*      Parse arguments.                                                */
+/* -------------------------------------------------------------------- */
+    char *dataPath;
+    map* tmpMap=getMapFromMaps(conf,"main","dataPath");
+    if(tmpMap!=NULL)
+      dataPath=strdup(tmpMap->value);
+    tmpMap=NULL;
+
+    char *tempPath;
+    tmpMap=getMapFromMaps(conf,"main","tmpPath");
+    if(tmpMap!=NULL){
+      tempPath=strdup(tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL){
+      map* length=getMapFromMaps(inputs,"InputDSN","length");
+      if(length!=NULL){
+	int i=0;
+	int len=atoi(length->value);
+	maps* currentMaps=getMaps(inputs,"InputDSN");
+	for(i=0;i<len;i++){
+	  tmpMap=getMapArray(currentMaps->content,"value",i);
+	  papszSrcFiles[i]=(char*)CPLMalloc(sizeof(char)*(strlen(dataPath)+strlen(tmpMap->value)+4));
+	  sprintf((char*)papszSrcFiles[i],"%s/%s",dataPath,tmpMap->value);
+	}
+      }else{
+	char *tmp=(char*)CPLMalloc(sizeof(char)*(strlen(dataPath)+strlen(tmpMap->value)+4));
+	sprintf(tmp,"%s/%s",dataPath,tmpMap->value);
+	papszSrcFiles=CSLAddString( papszSrcFiles, tmp );
+	free(tmp);
+      }
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL){
+      pszDstFilename=(char*)CPLMalloc(sizeof(char)*(strlen(tempPath)+strlen(tmpMap->value)+4));
+      char *ext=new char[4];
+      ext="tif";
+      if(strncasecmp(pszFormat,"AAIGRID",7)==0)
+	ext="csv";
+      else 
+	if(strncasecmp(pszFormat,"PNG",3)==0)
+	  ext="png";
+	else
+	  if(strncasecmp(pszFormat,"GIF",3)==0)
+	    ext="gif";
+	  else
+	    if(strncasecmp(pszFormat,"JPEG",4)==0)
+	      ext="jpg";
+      sprintf(pszDstFilename,"%s/%s.%s",tempPath,tmpMap->value,ext);
+    }
+
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"r","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      if ( EQUAL(tmpMap->value, "near") )
+	eResampleAlg = GRA_NearestNeighbour;
+      else if ( EQUAL(tmpMap->value, "bilinear") )
+	eResampleAlg = GRA_Bilinear;
+      else if ( EQUAL(tmpMap->value, "cubic") )
+	eResampleAlg = GRA_Cubic;
+      else if ( EQUAL(tmpMap->value, "cubicspline") )
+	eResampleAlg = GRA_CubicSpline;
+      else if ( EQUAL(tmpMap->value, "lanczos") )
+	eResampleAlg = GRA_Lanczos;
+      else
+	{
+	  char tmp[1024];
+	  sprintf(tmp,"Unknown resampling method: \"%s\".", tmpMap->value );
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return SERVICE_FAILED;
+	}
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"t_srs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *pszSRS = SanitizeSRS(tmpMap->value);
+      papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSRS );
+      CPLFree( pszSRS );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"s_srs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *pszSRS = SanitizeSRS(tmpMap->value);
+      papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSRS );
+      CPLFree( pszSRS );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"order","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      const char* pszMethod = CSLFetchNameValue(papszTO, "METHOD");
+      if (pszMethod)
+	fprintf(stderr, "Warning: only one METHOD can be used. Method %s is already defined\n",
+		pszMethod);
+      papszTO = CSLSetNameValue( papszTO, "MAX_GCP_ORDER", tmpMap->value );
+    }
+    
+    tmpMap=getMapFromMaps(inputs,"co","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      papszCreateOptions = CSLAddString( papszCreateOptions, tmpMap->value );
+      bCreateOutput = TRUE;
+    }   
+
+    tmpMap=getMapFromMaps(inputs,"wo","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      papszWarpOptions = CSLAddString( papszWarpOptions, tmpMap->value );
+    }   
+
+    tmpMap=getMapFromMaps(inputs,"multi","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      bMulti = TRUE;
+    }   
+
+    tmpMap=getMapFromMaps(inputs,"dstalpha","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      bEnableDstAlpha = TRUE;
+    }
+
+    tmpMap=getMapFromMaps(inputs,"srcalpha","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      bEnableSrcAlpha = TRUE;
+    }
+
+    tmpMap=getMapFromMaps(inputs,"tap","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      bTargetAlignedPixels = TRUE;
+    }
+
+
+    tmpMap=getMapFromMaps(inputs,"crop_to_cutline","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      bCropToCutline = TRUE;
+      bCreateOutput = TRUE;
+    }
+
+
+    tmpMap=getMapFromMaps(inputs,"tps","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"rpc","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      papszTO = CSLSetNameValue( papszTO, "METHOD", "RPC" );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"geoloc","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0 ){
+      papszTO = CSLSetNameValue( papszTO, "METHOD", "GEOLOC_ARRAY" );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"wt","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      int	iType;
+      
+      for( iType = 1; iType < GDT_TypeCount; iType++ )
+	{
+	  if( GDALGetDataTypeName((GDALDataType)iType) != NULL
+	      && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
+		       tmpMap->value) )
+	    {
+	      eWorkingType = (GDALDataType) iType;
+	    }
+	}
+      
+      if( eWorkingType == GDT_Unknown )
+	{
+	  char tmp[1024];
+	  sprintf(tmp,"Unknown output pixel type: %s\n", tmpMap->value );
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return SERVICE_FAILED;
+	}
+    }
+
+    tmpMap=getMapFromMaps(inputs,"srcnodata","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszSrcNodata = strdup(tmpMap->value);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"dstnodata","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszDstNodata = strdup(tmpMap->value);
+    }
+
+
+    tmpMap=getMapFromMaps(inputs,"tr","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *tmpV=strdup(tmpMap->value);
+      char *res=strtok(tmpV,",");
+      int i=0;
+      while(res!=NULL){
+	if(i==0)
+	  dfXRes = CPLAtofM(res);
+	else
+	  dfYRes = fabs(CPLAtofM(res));
+	res=strtok(NULL,",");
+	i++;
+      }
+      if( dfXRes == 0 || dfYRes == 0 )
+	{
+	  setMapInMaps(conf,"lenv","message","Wrong value for TR parameters");
+	}
+      bCreateOutput = TRUE;
+    }
+
+    tmpMap=getMapFromMaps(inputs,"cblend","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      papszWarpOptions = 
+	CSLSetNameValue( papszWarpOptions, 
+			 "CUTLINE_BLEND_DIST", tmpMap->value );
+    }
+    
+    tmpMap=getMapFromMaps(inputs,"ot","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      int	iType;
+      
+      for( iType = 1; iType < GDT_TypeCount; iType++ )
+	{
+	  if( GDALGetDataTypeName((GDALDataType)iType) != NULL
+	      && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
+		       tmpMap->value) )
+	    {
+	      eOutputType = (GDALDataType) iType;
+	    }
+	}
+
+      if( eOutputType == GDT_Unknown )
+	{
+	  char tmp[128];
+	  sprintf( tmp,"Unknown output pixel type: %s\n", tmpMap->value );
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return SERVICE_FAILED;
+	}
+      bCreateOutput = TRUE;      
+    }
+
+
+    tmpMap=getMapFromMaps(inputs,"ts","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *tmpV=strdup(tmpMap->value);
+      char *res=strtok(tmpV,",");
+      int i=0;
+      while(res!=NULL){
+	if(i==0)
+	  nForcePixels = atoi(res);	  
+	else
+	  nForceLines = atoi(res);	  
+	res=strtok(NULL,",");
+	i++;
+      }
+      free(tmpV);
+      bCreateOutput = TRUE;      
+    }
+
+    tmpMap=getMapFromMaps(inputs,"te","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *tmpV=strdup(tmpMap->value);
+      char *res=strtok(tmpV,",");
+      int i=0;
+      while(res!=NULL){
+	switch(i){
+	case 0:
+	  dfMinX = CPLAtofM(res);
+	  break;
+	case 1:
+	  dfMinY = CPLAtofM(res);
+	  break;
+	case 2:
+	  dfMaxX = CPLAtofM(res);
+	  break;
+	case 3:
+	  dfMaxY = CPLAtofM(res);
+	  break;
+	}
+	if(i==0)
+	  nForcePixels = atoi(res);	  
+	else
+	  nForceLines = atoi(res);	  
+	res=strtok(NULL,",");
+	i++;
+      }
+      free(tmpV);
+      bCreateOutput = TRUE;
+    }
+
+    tmpMap=getMapFromMaps(inputs,"te","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszCutlineDSName = strdup(tmpMap->value);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"cwhere","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszCWHERE = strdup(tmpMap->value);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"cl","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszCLayer = strdup(tmpMap->value);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"csql","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszCSQL = strdup(tmpMap->value);
+    }
+    
+    tmpMap=getMapFromMaps(inputs,"of","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      pszFormat = strdup(tmpMap->value);
+      bFormatExplicitelySet = TRUE;
+      bCreateOutput = TRUE;
+      if( EQUAL(pszFormat,"VRT") )
+	bVRT = TRUE;
+    }
+
+    tmpMap=getMapFromMaps(inputs,"to","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      papszTO = CSLAddString( papszTO, tmpMap->value );
+    }
+
+    tmpMap=getMapFromMaps(inputs,"et","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      dfErrorThreshold = CPLAtofM(tmpMap->value);
+    }
+    
+
+    tmpMap=getMapFromMaps(inputs,"refine_gpcs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0 ){
+      char *tmpV=strdup(tmpMap->value);
+      char *res=strtok(tmpV,",");
+      int i=0;
+      while(res!=NULL){
+	if(i==0){
+	  papszTO = CSLSetNameValue( papszTO, "REFINE_TOLERANCE", res );
+	  if(atof(res) < 0){
+	    setMapInMaps(conf,"lenv","message","The tolerance for -refine_gcps may not be negative\n");
+	    return SERVICE_FAILED;
+	  }
+	}else if(i==1){
+	  if(atoi(res) >= 0 && isdigit(res[0]))
+	    papszTO = CSLSetNameValue( papszTO, "REFINE_MINIMUM_GCPS", res );
+	  else
+	    papszTO = CSLSetNameValue( papszTO, "REFINE_MINIMUM_GCPS", "-1" );
+	}
+	res=strtok(NULL,",");
+	i++;
+      }
+    }
+
+    bQuiet = TRUE;
+    
+/* -------------------------------------------------------------------- */
+/*      Check that incompatible options are not used                    */
+/* -------------------------------------------------------------------- */
+
+    if ((nForcePixels != 0 || nForceLines != 0) && 
+        (dfXRes != 0 && dfYRes != 0))
+    {
+      setMapInMaps(conf,"lenv","message","tr and ts options cannot be used at the same time\n");
+      return SERVICE_FAILED;
+    }
+    
+    if (bTargetAlignedPixels && dfXRes == 0 && dfYRes == 0)
+    {
+      setMapInMaps(conf,"lenv","message","tap option cannot be used without using tr");
+      return SERVICE_FAILED;
+    }
+
+
+/* -------------------------------------------------------------------- */
+/*      Does the output dataset already exist?                          */
+/* -------------------------------------------------------------------- */
+
+    /* FIXME ? source filename=target filename and -overwrite is definitely */
+    /* an error. But I can't imagine of a valid case (without -overwrite), */
+    /* where it would make sense. In doubt, let's keep that dubious possibility... */
+    if ( CSLCount(papszSrcFiles) == 1 &&
+         strcmp(papszSrcFiles[0], pszDstFilename) == 0 && bOverwrite)
+    {
+      setMapInMaps(conf,"lenv","message","Source and destination datasets must be different.");
+      return GDALExit(1);
+    }
+
+    CPLPushErrorHandler( CPLQuietErrorHandler );
+    hDstDS = GDALOpen( pszDstFilename, GA_Update );
+    CPLPopErrorHandler();
+
+    if( hDstDS != NULL && bOverwrite )
+    {
+        GDALClose(hDstDS);
+        hDstDS = NULL;
+    }
+
+    if( hDstDS != NULL && bCreateOutput )
+    {
+      char tmp[024];
+      sprintf( tmp, 
+	       "Output dataset %s exists,\n"
+	       "but some commandline options were provided indicating a new dataset\n"
+	       "should be created.  Please delete existing dataset and run again.\n",
+	       pszDstFilename );
+      setMapInMaps(conf,"lenv","message",tmp);
+      return GDALExit(1);
+    }
+
+    /* Avoid overwriting an existing destination file that cannot be opened in */
+    /* update mode with a new GTiff file */
+    if ( hDstDS == NULL && !bOverwrite )
+    {
+        CPLPushErrorHandler( CPLQuietErrorHandler );
+        hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly );
+        CPLPopErrorHandler();
+        
+        if (hDstDS)
+        {
+	  char tmp[1024];
+	  sprintf( tmp, 
+		   "Output dataset %s exists, but cannot be opened in update mode\n",
+		   pszDstFilename );
+	  GDALClose(hDstDS);
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return GDALExit( 1 );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a cutline datasource read it and attach it in the    */
+/*      warp options.                                                   */
+/* -------------------------------------------------------------------- */
+    if( pszCutlineDSName != NULL )
+    {
+        LoadCutline( pszCutlineDSName, pszCLayer, pszCWHERE, pszCSQL,
+                     &hCutline );
+    }
+
+#ifdef OGR_ENABLED
+    if ( bCropToCutline && hCutline != NULL )
+    {
+      
+      
+        OGRGeometryH hCutlineGeom = OGR_G_Clone( (OGRGeometryH) hCutline );
+        OGRSpatialReferenceH hCutlineSRS = OGR_G_GetSpatialReference( hCutlineGeom );
+        const char *pszThisTargetSRS = CSLFetchNameValue( papszTO, "DST_SRS" );
+        OGRCoordinateTransformationH hCT = NULL;
+        if (hCutlineSRS == NULL)
+        {
+            /* We suppose it is in target coordinates */
+        }
+        else if (pszThisTargetSRS != NULL)
+        {
+            OGRSpatialReferenceH hTargetSRS = OSRNewSpatialReference(NULL);
+            if( OSRImportFromWkt( hTargetSRS, (char **)&pszThisTargetSRS ) != CE_None )
+            {
+	      setMapInMaps(conf,"lenv","message","Cannot compute bounding box of cutline.\n");
+                return GDALExit(1);
+            }
+
+            hCT = OCTNewCoordinateTransformation(hCutlineSRS, hTargetSRS);
+
+            OSRDestroySpatialReference(hTargetSRS);
+        }
+        else if (pszThisTargetSRS == NULL)
+        {
+            if (papszSrcFiles[0] != NULL)
+            {
+                GDALDatasetH hSrcDS = GDALOpen(papszSrcFiles[0], GA_ReadOnly);
+                if (hSrcDS == NULL)
+                {
+		  setMapInMaps(conf,"lenv","message","Cannot compute bounding box of cutline.");
+		  return GDALExit(1);
+                }
+
+                OGRSpatialReferenceH  hRasterSRS = NULL;
+                const char *pszProjection = NULL;
+
+                if( GDALGetProjectionRef( hSrcDS ) != NULL
+                    && strlen(GDALGetProjectionRef( hSrcDS )) > 0 )
+                    pszProjection = GDALGetProjectionRef( hSrcDS );
+                else if( GDALGetGCPProjection( hSrcDS ) != NULL )
+                    pszProjection = GDALGetGCPProjection( hSrcDS );
+
+                if( pszProjection == NULL )
+                {
+		  setMapInMaps(conf,"lenv","message","Cannot compute bounding box of cutline.");
+		  return GDALExit(1);
+                }
+
+                hRasterSRS = OSRNewSpatialReference(NULL);
+                if( OSRImportFromWkt( hRasterSRS, (char **)&pszProjection ) != CE_None )
+                {
+		  setMapInMaps(conf,"lenv","message","Cannot compute bounding box of cutline.");
+		  return GDALExit(1);
+                }
+
+                hCT = OCTNewCoordinateTransformation(hCutlineSRS, hRasterSRS);
+
+                OSRDestroySpatialReference(hRasterSRS);
+
+                GDALClose(hSrcDS);
+            }
+            else
+            {
+	      setMapInMaps(conf,"levn","message", "Cannot compute bounding box of cutline.\n");
+	      return GDALExit(1);
+            }
+        }
+
+        if (hCT)
+        {
+            OGR_G_Transform( hCutlineGeom, hCT );
+
+            OCTDestroyCoordinateTransformation(hCT);
+        }
+
+        OGREnvelope sEnvelope;
+        OGR_G_GetEnvelope(hCutlineGeom, &sEnvelope);
+
+        dfMinX = sEnvelope.MinX;
+        dfMinY = sEnvelope.MinY;
+        dfMaxX = sEnvelope.MaxX;
+        dfMaxY = sEnvelope.MaxY;
+        
+        OGR_G_DestroyGeometry(hCutlineGeom);
+    }
+#endif
+    
+/* -------------------------------------------------------------------- */
+/*      If not, we need to create it.                                   */
+/* -------------------------------------------------------------------- */
+    int   bInitDestSetForFirst = FALSE;
+
+    void* hUniqueTransformArg = NULL;
+    GDALDatasetH hUniqueSrcDS = NULL;
+
+    if( hDstDS == NULL )
+    {
+
+      hDstDS = GDALWarpCreateOutput( conf,papszSrcFiles, pszDstFilename,pszFormat,
+                                       papszTO, &papszCreateOptions, 
+                                       eOutputType, &hUniqueTransformArg,
+                                       &hUniqueSrcDS);
+        bCreateOutput = TRUE;
+
+
+        if( CSLFetchNameValue( papszWarpOptions, "INIT_DEST" ) == NULL 
+            && pszDstNodata == NULL )
+        {
+            papszWarpOptions = CSLSetNameValue(papszWarpOptions,
+                                               "INIT_DEST", "0");
+            bInitDestSetForFirst = TRUE;
+        }
+        else if( CSLFetchNameValue( papszWarpOptions, "INIT_DEST" ) == NULL )
+        {
+            papszWarpOptions = CSLSetNameValue(papszWarpOptions,
+                                               "INIT_DEST", "NO_DATA" );
+            bInitDestSetForFirst = TRUE;
+        }
+
+        CSLDestroy( papszCreateOptions );
+        papszCreateOptions = NULL;
+    }
+
+ 
+    if( hDstDS == NULL )
+        GDALExit( 1 );
+
+/* -------------------------------------------------------------------- */
+/*      Loop over all source files, processing each in turn.            */
+/* -------------------------------------------------------------------- */
+    int iSrc;
+
+    for( iSrc = 0; papszSrcFiles[iSrc] != NULL; iSrc++ )
+    {
+        GDALDatasetH hSrcDS;
+       
+/* -------------------------------------------------------------------- */
+/*      Open this file.                                                 */
+/* -------------------------------------------------------------------- */
+        if (hUniqueSrcDS)
+            hSrcDS = hUniqueSrcDS;
+        else
+            hSrcDS = GDALOpen( papszSrcFiles[iSrc], GA_ReadOnly );
+    
+        if( hSrcDS == NULL ){
+	  setMapInMaps(conf,"lenv","message",CPLGetLastErrorMsg());
+	  return GDALExit( 2 );
+	}
+
+/* -------------------------------------------------------------------- */
+/*      Check that there's at least one raster band                     */
+/* -------------------------------------------------------------------- */
+        if ( GDALGetRasterCount(hSrcDS) == 0 )
+        {    
+	  char tmp[1024];
+	  sprintf(tmp, "Input file %s has no raster bands.\n", papszSrcFiles[iSrc] );
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return GDALExit( 1 );
+        }
+	
+        if( !bQuiet )
+            printf( "Processing input file %s.\n", papszSrcFiles[iSrc] );
+
+/* -------------------------------------------------------------------- */
+/*      Warns if the file has a color table and something more          */
+/*      complicated than nearest neighbour resampling is asked          */
+/* -------------------------------------------------------------------- */
+ 
+	if ( eResampleAlg != GRA_NearestNeighbour &&
+             GDALGetRasterColorTable(GDALGetRasterBand(hSrcDS, 1)) != NULL)
+        {
+                fprintf( stderr, "Warning: Input file %s has a color table, which will likely lead to "
+                        "bad results when using a resampling method other than "
+                        "nearest neighbour. Converting the dataset prior to 24/32 bit "
+                        "is advised.\n", papszSrcFiles[iSrc] );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Do we have a source alpha band?                                 */
+/* -------------------------------------------------------------------- */
+        if( GDALGetRasterColorInterpretation( 
+                GDALGetRasterBand(hSrcDS,GDALGetRasterCount(hSrcDS)) ) 
+            == GCI_AlphaBand 
+            && !bEnableSrcAlpha )
+        {
+            bEnableSrcAlpha = TRUE;
+            if( !bQuiet )
+                printf( "Using band %d of source image as alpha.\n", 
+                        GDALGetRasterCount(hSrcDS) );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Create a transformation object from the source to               */
+/*      destination coordinate system.                                  */
+/* -------------------------------------------------------------------- */
+        if (hUniqueTransformArg)
+            hTransformArg = hGenImgProjArg = hUniqueTransformArg;
+        else
+            hTransformArg = hGenImgProjArg =
+                GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO );
+
+        if( hTransformArg == NULL ){
+	  setMapInMaps(conf,"lenv","message",CPLGetLastErrorMsg());
+	  return GDALExit( 1 );
+	}
+        
+        pfnTransformer = GDALGenImgProjTransform;
+
+/* -------------------------------------------------------------------- */
+/*      Warp the transformer with a linear approximator unless the      */
+/*      acceptable error is zero.                                       */
+/* -------------------------------------------------------------------- */
+        if( dfErrorThreshold != 0.0 )
+        {
+            hTransformArg = hApproxArg = 
+                GDALCreateApproxTransformer( GDALGenImgProjTransform, 
+                                             hGenImgProjArg, dfErrorThreshold);
+            pfnTransformer = GDALApproxTransform;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Clear temporary INIT_DEST settings after the first image.       */
+/* -------------------------------------------------------------------- */
+        if( bInitDestSetForFirst && iSrc == 1 )
+            papszWarpOptions = CSLSetNameValue( papszWarpOptions, 
+                                                "INIT_DEST", NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Setup warp options.                                             */
+/* -------------------------------------------------------------------- */
+        GDALWarpOptions *psWO = GDALCreateWarpOptions();
+
+        psWO->papszWarpOptions = CSLDuplicate(papszWarpOptions);
+        psWO->eWorkingDataType = eWorkingType;
+        psWO->eResampleAlg = eResampleAlg;
+
+        psWO->hSrcDS = hSrcDS;
+        psWO->hDstDS = hDstDS;
+
+        psWO->pfnTransformer = pfnTransformer;
+        psWO->pTransformerArg = hTransformArg;
+
+        if( !bQuiet )
+            psWO->pfnProgress = GDALTermProgress;
+
+        if( dfWarpMemoryLimit != 0.0 )
+            psWO->dfWarpMemoryLimit = dfWarpMemoryLimit;
+
+/* -------------------------------------------------------------------- */
+/*      Setup band mapping.                                             */
+/* -------------------------------------------------------------------- */
+        if( bEnableSrcAlpha )
+            psWO->nBandCount = GDALGetRasterCount(hSrcDS) - 1;
+        else
+            psWO->nBandCount = GDALGetRasterCount(hSrcDS);
+
+        psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
+        psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
+
+        for( i = 0; i < psWO->nBandCount; i++ )
+        {
+            psWO->panSrcBands[i] = i+1;
+            psWO->panDstBands[i] = i+1;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Setup alpha bands used if any.                                  */
+/* -------------------------------------------------------------------- */
+        if( bEnableSrcAlpha )
+            psWO->nSrcAlphaBand = GDALGetRasterCount(hSrcDS);
+
+        if( !bEnableDstAlpha 
+            && GDALGetRasterCount(hDstDS) == psWO->nBandCount+1 
+            && GDALGetRasterColorInterpretation( 
+                GDALGetRasterBand(hDstDS,GDALGetRasterCount(hDstDS))) 
+            == GCI_AlphaBand )
+        {
+            if( !bQuiet )
+                printf( "Using band %d of destination image as alpha.\n", 
+                        GDALGetRasterCount(hDstDS) );
+                
+            bEnableDstAlpha = TRUE;
+        }
+
+        if( bEnableDstAlpha )
+            psWO->nDstAlphaBand = GDALGetRasterCount(hDstDS);
+
+/* -------------------------------------------------------------------- */
+/*      Setup NODATA options.                                           */
+/* -------------------------------------------------------------------- */
+        if( pszSrcNodata != NULL && !EQUALN(pszSrcNodata,"n",1) )
+        {
+            char **papszTokens = CSLTokenizeString( pszSrcNodata );
+            int  nTokenCount = CSLCount(papszTokens);
+
+            psWO->padfSrcNoDataReal = (double *) 
+                CPLMalloc(psWO->nBandCount*sizeof(double));
+            psWO->padfSrcNoDataImag = (double *) 
+                CPLMalloc(psWO->nBandCount*sizeof(double));
+
+            for( i = 0; i < psWO->nBandCount; i++ )
+            {
+                if( i < nTokenCount )
+                {
+                    CPLStringToComplex( papszTokens[i], 
+                                        psWO->padfSrcNoDataReal + i,
+                                        psWO->padfSrcNoDataImag + i );
+                }
+                else
+                {
+                    psWO->padfSrcNoDataReal[i] = psWO->padfSrcNoDataReal[i-1];
+                    psWO->padfSrcNoDataImag[i] = psWO->padfSrcNoDataImag[i-1];
+                }
+            }
+
+            CSLDestroy( papszTokens );
+
+            psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions,
+                                               "UNIFIED_SRC_NODATA", "YES" );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If -srcnodata was not specified, but the data has nodata        */
+/*      values, use them.                                               */
+/* -------------------------------------------------------------------- */
+        if( pszSrcNodata == NULL )
+        {
+            int bHaveNodata = FALSE;
+            double dfReal = 0.0;
+
+            for( i = 0; !bHaveNodata && i < psWO->nBandCount; i++ )
+            {
+                GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, i+1 );
+                dfReal = GDALGetRasterNoDataValue( hBand, &bHaveNodata );
+            }
+
+            if( bHaveNodata )
+            {
+                if( !bQuiet )
+                {
+                    if (CPLIsNan(dfReal))
+                        printf( "Using internal nodata values (eg. nan) for image %s.\n",
+                                papszSrcFiles[iSrc] );
+                    else
+                        printf( "Using internal nodata values (eg. %g) for image %s.\n",
+                                dfReal, papszSrcFiles[iSrc] );
+                }
+                psWO->padfSrcNoDataReal = (double *) 
+                    CPLMalloc(psWO->nBandCount*sizeof(double));
+                psWO->padfSrcNoDataImag = (double *) 
+                    CPLMalloc(psWO->nBandCount*sizeof(double));
+                
+                for( i = 0; i < psWO->nBandCount; i++ )
+                {
+                    GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, i+1 );
+
+                    dfReal = GDALGetRasterNoDataValue( hBand, &bHaveNodata );
+
+                    if( bHaveNodata )
+                    {
+                        psWO->padfSrcNoDataReal[i] = dfReal;
+                        psWO->padfSrcNoDataImag[i] = 0.0;
+                    }
+                    else
+                    {
+                        psWO->padfSrcNoDataReal[i] = -123456.789;
+                        psWO->padfSrcNoDataImag[i] = 0.0;
+                    }
+                }
+            }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If the output dataset was created, and we have a destination    */
+/*      nodata value, go through marking the bands with the information.*/
+/* -------------------------------------------------------------------- */
+        if( pszDstNodata != NULL )
+        {
+            char **papszTokens = CSLTokenizeString( pszDstNodata );
+            int  nTokenCount = CSLCount(papszTokens);
+
+            psWO->padfDstNoDataReal = (double *) 
+                CPLMalloc(psWO->nBandCount*sizeof(double));
+            psWO->padfDstNoDataImag = (double *) 
+                CPLMalloc(psWO->nBandCount*sizeof(double));
+
+            for( i = 0; i < psWO->nBandCount; i++ )
+            {
+                if( i < nTokenCount )
+                {
+                    CPLStringToComplex( papszTokens[i], 
+                                        psWO->padfDstNoDataReal + i,
+                                        psWO->padfDstNoDataImag + i );
+                }
+                else
+                {
+                    psWO->padfDstNoDataReal[i] = psWO->padfDstNoDataReal[i-1];
+                    psWO->padfDstNoDataImag[i] = psWO->padfDstNoDataImag[i-1];
+                }
+                
+                GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, i+1 );
+                int bClamped = FALSE, bRounded = FALSE;
+
+#define CLAMP(val,type,minval,maxval) \
+    do { if (val < minval) { bClamped = TRUE; val = minval; } \
+    else if (val > maxval) { bClamped = TRUE; val = maxval; } \
+    else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \
+    while(0)
+
+                switch(GDALGetRasterDataType(hBand))
+                {
+                    case GDT_Byte:
+                        CLAMP(psWO->padfDstNoDataReal[i], GByte,
+                              0.0, 255.0);
+                        break;
+                    case GDT_Int16:
+                        CLAMP(psWO->padfDstNoDataReal[i], GInt16,
+                              -32768.0, 32767.0);
+                        break;
+                    case GDT_UInt16:
+                        CLAMP(psWO->padfDstNoDataReal[i], GUInt16,
+                              0.0, 65535.0);
+                        break;
+                    case GDT_Int32:
+                        CLAMP(psWO->padfDstNoDataReal[i], GInt32,
+                              -2147483648.0, 2147483647.0);
+                        break;
+                    case GDT_UInt32:
+                        CLAMP(psWO->padfDstNoDataReal[i], GUInt32,
+                              0.0, 4294967295.0);
+                        break;
+                    default:
+                        break;
+                }
+                    
+                if (bClamped)
+                {
+                    printf( "for band %d, destination nodata value has been clamped "
+                           "to %.0f, the original value being out of range.\n",
+                           i + 1, psWO->padfDstNoDataReal[i]);
+                }
+                else if(bRounded)
+                {
+                    printf("for band %d, destination nodata value has been rounded "
+                           "to %.0f, %s being an integer datatype.\n",
+                           i + 1, psWO->padfDstNoDataReal[i],
+                           GDALGetDataTypeName(GDALGetRasterDataType(hBand)));
+                }
+
+                if( bCreateOutput )
+                {
+                    GDALSetRasterNoDataValue( 
+                        GDALGetRasterBand( hDstDS, psWO->panDstBands[i] ), 
+                        psWO->padfDstNoDataReal[i] );
+                }
+            }
+
+            CSLDestroy( papszTokens );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a cutline, transform it into the source              */
+/*      pixel/line coordinate system and insert into warp options.      */
+/* -------------------------------------------------------------------- */
+        if( hCutline != NULL )
+        {
+            TransformCutlineToSource( hSrcDS, hCutline, 
+                                      &(psWO->papszWarpOptions), 
+                                      papszTO );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we are producing VRT output, then just initialize it with    */
+/*      the warp options and write out now rather than proceeding       */
+/*      with the operations.                                            */
+/* -------------------------------------------------------------------- */
+        if( bVRT )
+        {
+            if( GDALInitializeWarpedVRT( hDstDS, psWO ) != CE_None )
+                GDALExit( 1 );
+
+            GDALClose( hDstDS );
+            GDALClose( hSrcDS );
+
+            /* The warped VRT will clean itself the transformer used */
+            /* So we have only to destroy the hGenImgProjArg if we */
+            /* have wrapped it inside the hApproxArg */
+            if (pfnTransformer == GDALApproxTransform)
+            {
+                if( hGenImgProjArg != NULL )
+                    GDALDestroyGenImgProjTransformer( hGenImgProjArg );
+            }
+
+            GDALDestroyWarpOptions( psWO );
+
+	    setMapInMaps(outputs,"Result","value",pszDstFilename);
+
+            CPLFree( pszDstFilename );
+            CSLDestroy( papszSrcFiles );
+            CSLDestroy( papszWarpOptions );
+            CSLDestroy( papszTO );
+    
+            GDALDumpOpenDatasets( stderr );
+        
+            GDALDestroyDriverManager();
+        
+            return SERVICE_SUCCEEDED;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Initialize and execute the warp.                                */
+/* -------------------------------------------------------------------- */
+        GDALWarpOperation oWO;
+
+        if( oWO.Initialize( psWO ) == CE_None )
+        {
+            CPLErr eErr;
+            if( bMulti )
+                eErr = oWO.ChunkAndWarpMulti( 0, 0, 
+                                       GDALGetRasterXSize( hDstDS ),
+                                       GDALGetRasterYSize( hDstDS ) );
+            else
+                eErr = oWO.ChunkAndWarpImage( 0, 0, 
+                                       GDALGetRasterXSize( hDstDS ),
+                                       GDALGetRasterYSize( hDstDS ) );
+            if (eErr != CE_None){
+                bHasGotErr = TRUE;
+	    }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Cleanup                                                         */
+/* -------------------------------------------------------------------- */
+        if( hApproxArg != NULL )
+            GDALDestroyApproxTransformer( hApproxArg );
+        
+        if( hGenImgProjArg != NULL )
+            GDALDestroyGenImgProjTransformer( hGenImgProjArg );
+        
+        GDALDestroyWarpOptions( psWO );
+
+        GDALClose( hSrcDS );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Final Cleanup.                                                  */
+/* -------------------------------------------------------------------- */
+    CPLErrorReset();
+    GDALFlushCache( hDstDS );
+    if( CPLGetLastErrorType() != CE_None )
+        bHasGotErr = TRUE;
+    GDALClose( hDstDS );
+
+    setMapInMaps(outputs,"Result","value",pszDstFilename);
+    
+    CPLFree( pszDstFilename );
+    CSLDestroy( papszSrcFiles );
+    CSLDestroy( papszWarpOptions );
+    CSLDestroy( papszTO );
+
+    GDALDumpOpenDatasets( stderr );
+
+    GDALDestroyDriverManager();
+    
+#ifdef OGR_ENABLED
+    if( hCutline != NULL )
+        OGR_G_DestroyGeometry( (OGRGeometryH) hCutline );
+    OGRCleanupAll();
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*      Clean allocated arguments.                                      */
+/* -------------------------------------------------------------------- */
+    free(dataPath);
+    free(tempPath);
+
+    tmpMap=getMapFromMaps(inputs,"te","value");
+    if(tmpMap!=NULL){
+      free(pszCutlineDSName);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"cwhere","value");
+    if(tmpMap!=NULL){
+      free(pszCWHERE);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"cl","value");
+    if(tmpMap!=NULL){
+      free(pszCLayer);
+    }
+
+    tmpMap=getMapFromMaps(inputs,"csql","value");
+    if(tmpMap!=NULL){
+      free(pszCSQL);
+    }
+
+    return (bHasGotErr) ? SERVICE_FAILED : SERVICE_SUCCEEDED;
+}
+
+/************************************************************************/
+/*                        GDALWarpCreateOutput()                        */
+/*                                                                      */
+/*      Create the output file based on various commandline options,    */
+/*      and the input file.                                             */
+/*      If there's just one source file, then *phTransformArg and       */
+/*      *phSrcDS will be set, in order them to be reused by main        */
+/*      function. This saves dataset re-opening, and above all transform*/
+/*      recomputation, which can be expensive in the -tps case          */
+/************************************************************************/
+
+static GDALDatasetH 
+GDALWarpCreateOutput( maps*& conf,char **papszSrcFiles, const char *pszFilename, 
+                      const char *pszFormat, char **papszTO, 
+                      char ***ppapszCreateOptions, GDALDataType eDT,
+                      void ** phTransformArg,
+                      GDALDatasetH* phSrcDS)
+
+
+{
+    GDALDriverH hDriver;
+    GDALDatasetH hDstDS;
+    void *hTransformArg;
+    GDALColorTableH hCT = NULL;
+    double dfWrkMinX=0, dfWrkMaxX=0, dfWrkMinY=0, dfWrkMaxY=0;
+    double dfWrkResX=0, dfWrkResY=0;
+    int nDstBandCount = 0;
+    std::vector<GDALColorInterp> apeColorInterpretations;
+
+    *phTransformArg = NULL;
+    *phSrcDS = NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Find the output driver.                                         */
+/* -------------------------------------------------------------------- */
+    hDriver = GDALGetDriverByName( pszFormat );
+    if( hDriver == NULL 
+        || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL )
+    {
+        int	iDr;
+        char tmp[2048];
+        sprintf( tmp, "Output driver `%s' not recognised or does not support\n"
+		 "direct output file creation.  The following format drivers are configured\n"
+		 "and support direct output:\n", 
+		 pszFormat );
+
+        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
+        {
+            GDALDriverH hDriver = GDALGetDriver(iDr);
+
+            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL) != NULL )
+            {
+	      char *_tmp=strdup(tmp);
+	      sprintf( tmp,"%s  %s: %s\n",
+		       _tmp,
+		       GDALGetDriverShortName( hDriver  ),
+		       GDALGetDriverLongName( hDriver ) );
+	      free(_tmp);
+            }
+        }
+	setMapInMaps(conf,"lenv","message",tmp);
+        GDALExit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      For virtual output files, we have to set a special subclass     */
+/*      of dataset to create.                                           */
+/* -------------------------------------------------------------------- */
+    if( bVRT )
+        *ppapszCreateOptions = 
+            CSLSetNameValue( *ppapszCreateOptions, "SUBCLASS", 
+                             "VRTWarpedDataset" );
+
+/* -------------------------------------------------------------------- */
+/*      Loop over all input files to collect extents.                   */
+/* -------------------------------------------------------------------- */
+    int     iSrc;
+    char    *pszThisTargetSRS = (char*)CSLFetchNameValue( papszTO, "DST_SRS" );
+    if( pszThisTargetSRS != NULL )
+        pszThisTargetSRS = CPLStrdup( pszThisTargetSRS );
+
+    for( iSrc = 0; papszSrcFiles[iSrc] != NULL; iSrc++ )
+    {
+        GDALDatasetH hSrcDS;
+        const char *pszThisSourceSRS = CSLFetchNameValue(papszTO,"SRC_SRS");
+
+        hSrcDS = GDALOpen( papszSrcFiles[iSrc], GA_ReadOnly );
+        if( hSrcDS == NULL )
+            GDALExit( 1 );
+
+/* -------------------------------------------------------------------- */
+/*      Check that there's at least one raster band                     */
+/* -------------------------------------------------------------------- */
+        if ( GDALGetRasterCount(hSrcDS) == 0 )
+        {
+            fprintf(stderr, "Input file %s has no raster bands.\n", papszSrcFiles[iSrc] );
+            GDALExit( 1 );
+        }
+
+        if( eDT == GDT_Unknown )
+            eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDS,1));
+
+/* -------------------------------------------------------------------- */
+/*      If we are processing the first file, and it has a color         */
+/*      table, then we will copy it to the destination file.            */
+/* -------------------------------------------------------------------- */
+        if( iSrc == 0 )
+        {
+            nDstBandCount = GDALGetRasterCount(hSrcDS);
+            hCT = GDALGetRasterColorTable( GDALGetRasterBand(hSrcDS,1) );
+            if( hCT != NULL )
+            {
+                hCT = GDALCloneColorTable( hCT );
+                if( !bQuiet )
+                    printf( "Copying color table from %s to new file.\n", 
+                            papszSrcFiles[iSrc] );
+            }
+
+            for(int iBand = 0; iBand < nDstBandCount; iBand++)
+            {
+                apeColorInterpretations.push_back(
+                    GDALGetRasterColorInterpretation(GDALGetRasterBand(hSrcDS,iBand+1)) );
+            }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Get the sourcesrs from the dataset, if not set already.         */
+/* -------------------------------------------------------------------- */
+        if( pszThisSourceSRS == NULL )
+        {
+            const char *pszMethod = CSLFetchNameValue( papszTO, "METHOD" );
+
+            if( GDALGetProjectionRef( hSrcDS ) != NULL 
+                && strlen(GDALGetProjectionRef( hSrcDS )) > 0
+                && (pszMethod == NULL || EQUAL(pszMethod,"GEOTRANSFORM")) )
+                pszThisSourceSRS = GDALGetProjectionRef( hSrcDS );
+            
+            else if( GDALGetGCPProjection( hSrcDS ) != NULL
+                     && strlen(GDALGetGCPProjection(hSrcDS)) > 0 
+                     && GDALGetGCPCount( hSrcDS ) > 1 
+                     && (pszMethod == NULL || EQUALN(pszMethod,"GCP_",4)) )
+                pszThisSourceSRS = GDALGetGCPProjection( hSrcDS );
+            else if( pszMethod != NULL && EQUAL(pszMethod,"RPC") )
+                pszThisSourceSRS = SRS_WKT_WGS84;
+            else
+                pszThisSourceSRS = "";
+        }
+
+        if( pszThisTargetSRS == NULL )
+            pszThisTargetSRS = CPLStrdup( pszThisSourceSRS );
+        
+/* -------------------------------------------------------------------- */
+/*      Create a transformation object from the source to               */
+/*      destination coordinate system.                                  */
+/* -------------------------------------------------------------------- */
+        hTransformArg = 
+            GDALCreateGenImgProjTransformer2( hSrcDS, NULL, papszTO );
+        
+        if( hTransformArg == NULL )
+        {
+            CPLFree( pszThisTargetSRS );
+            GDALClose( hSrcDS );
+            return NULL;
+        }
+        
+        GDALTransformerInfo* psInfo = (GDALTransformerInfo*)hTransformArg;
+
+/* -------------------------------------------------------------------- */
+/*      Get approximate output definition.                              */
+/* -------------------------------------------------------------------- */
+        double adfThisGeoTransform[6];
+        double adfExtent[4];
+        int    nThisPixels, nThisLines;
+
+        if( GDALSuggestedWarpOutput2( hSrcDS, 
+                                      psInfo->pfnTransform, hTransformArg, 
+                                      adfThisGeoTransform, 
+                                      &nThisPixels, &nThisLines, 
+                                      adfExtent, 0 ) != CE_None )
+        {
+            CPLFree( pszThisTargetSRS );
+            GDALClose( hSrcDS );
+            return NULL;
+        }
+        
+        if (CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", NULL ) == NULL)
+        {
+            double MinX = adfExtent[0];
+            double MaxX = adfExtent[2];
+            double MaxY = adfExtent[3];
+            double MinY = adfExtent[1];
+            int bSuccess = TRUE;
+            
+            /* Check that the the edges of the target image are in the validity area */
+            /* of the target projection */
+#define N_STEPS 20
+            int i,j;
+            for(i=0;i<=N_STEPS && bSuccess;i++)
+            {
+                for(j=0;j<=N_STEPS && bSuccess;j++)
+                {
+                    double dfRatioI = i * 1.0 / N_STEPS;
+                    double dfRatioJ = j * 1.0 / N_STEPS;
+                    double expected_x = (1 - dfRatioI) * MinX + dfRatioI * MaxX;
+                    double expected_y = (1 - dfRatioJ) * MinY + dfRatioJ * MaxY;
+                    double x = expected_x;
+                    double y = expected_y;
+                    double z = 0;
+                    /* Target SRS coordinates to source image pixel coordinates */
+                    if (!psInfo->pfnTransform(hTransformArg, TRUE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
+                        bSuccess = FALSE;
+                    /* Source image pixel coordinates to target SRS coordinates */
+                    if (!psInfo->pfnTransform(hTransformArg, FALSE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
+                        bSuccess = FALSE;
+                    if (fabs(x - expected_x) > (MaxX - MinX) / nThisPixels ||
+                        fabs(y - expected_y) > (MaxY - MinY) / nThisLines)
+                        bSuccess = FALSE;
+                }
+            }
+            
+            /* If not, retry with CHECK_WITH_INVERT_PROJ=TRUE that forces ogrct.cpp */
+            /* to check the consistency of each requested projection result with the */
+            /* invert projection */
+            if (!bSuccess)
+            {
+                CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" );
+                CPLDebug("WARP", "Recompute out extent with CHECK_WITH_INVERT_PROJ=TRUE");
+
+                if( GDALSuggestedWarpOutput2( hSrcDS, 
+                                      psInfo->pfnTransform, hTransformArg, 
+                                      adfThisGeoTransform, 
+                                      &nThisPixels, &nThisLines, 
+                                      adfExtent, 0 ) != CE_None )
+                {
+                    CPLFree( pszThisTargetSRS );
+                    GDALClose( hSrcDS );
+                    return NULL;
+                }
+            }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Expand the working bounds to include this region, ensure the    */
+/*      working resolution is no more than this resolution.             */
+/* -------------------------------------------------------------------- */
+        if( dfWrkMaxX == 0.0 && dfWrkMinX == 0.0 )
+        {
+            dfWrkMinX = adfExtent[0];
+            dfWrkMaxX = adfExtent[2];
+            dfWrkMaxY = adfExtent[3];
+            dfWrkMinY = adfExtent[1];
+            dfWrkResX = adfThisGeoTransform[1];
+            dfWrkResY = ABS(adfThisGeoTransform[5]);
+        }
+        else
+        {
+            dfWrkMinX = MIN(dfWrkMinX,adfExtent[0]);
+            dfWrkMaxX = MAX(dfWrkMaxX,adfExtent[2]);
+            dfWrkMaxY = MAX(dfWrkMaxY,adfExtent[3]);
+            dfWrkMinY = MIN(dfWrkMinY,adfExtent[1]);
+            dfWrkResX = MIN(dfWrkResX,adfThisGeoTransform[1]);
+            dfWrkResY = MIN(dfWrkResY,ABS(adfThisGeoTransform[5]));
+        }
+
+        if (iSrc == 0 && papszSrcFiles[1] == NULL)
+        {
+            *phTransformArg = hTransformArg;
+            *phSrcDS = hSrcDS;
+        }
+        else
+        {
+            GDALDestroyGenImgProjTransformer( hTransformArg );
+            GDALClose( hSrcDS );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Did we have any usable sources?                                 */
+/* -------------------------------------------------------------------- */
+    if( nDstBandCount == 0 )
+    {
+        CPLError( CE_Failure, CPLE_AppDefined,
+                  "No usable source images." );
+        CPLFree( pszThisTargetSRS );
+        return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Turn the suggested region into a geotransform and suggested     */
+/*      number of pixels and lines.                                     */
+/* -------------------------------------------------------------------- */
+    double adfDstGeoTransform[6];
+    int nPixels, nLines;
+
+    adfDstGeoTransform[0] = dfWrkMinX;
+    adfDstGeoTransform[1] = dfWrkResX;
+    adfDstGeoTransform[2] = 0.0;
+    adfDstGeoTransform[3] = dfWrkMaxY;
+    adfDstGeoTransform[4] = 0.0;
+    adfDstGeoTransform[5] = -1 * dfWrkResY;
+
+    nPixels = (int) ((dfWrkMaxX - dfWrkMinX) / dfWrkResX + 0.5);
+    nLines = (int) ((dfWrkMaxY - dfWrkMinY) / dfWrkResY + 0.5);
+
+/* -------------------------------------------------------------------- */
+/*      Did the user override some parameters?                          */
+/* -------------------------------------------------------------------- */
+    if( dfXRes != 0.0 && dfYRes != 0.0 )
+    {
+        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0 )
+        {
+            dfMinX = adfDstGeoTransform[0];
+            dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels;
+            dfMaxY = adfDstGeoTransform[3];
+            dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines;
+        }
+        
+        if ( bTargetAlignedPixels )
+        {
+            dfMinX = floor(dfMinX / dfXRes) * dfXRes;
+            dfMaxX = ceil(dfMaxX / dfXRes) * dfXRes;
+            dfMinY = floor(dfMinY / dfYRes) * dfYRes;
+            dfMaxY = ceil(dfMaxY / dfYRes) * dfYRes;
+        }
+
+        nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
+        nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
+        adfDstGeoTransform[0] = dfMinX;
+        adfDstGeoTransform[3] = dfMaxY;
+        adfDstGeoTransform[1] = dfXRes;
+        adfDstGeoTransform[5] = -dfYRes;
+    }
+
+    else if( nForcePixels != 0 && nForceLines != 0 )
+    {
+        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0 )
+        {
+            dfMinX = dfWrkMinX;
+            dfMaxX = dfWrkMaxX;
+            dfMaxY = dfWrkMaxY;
+            dfMinY = dfWrkMinY;
+        }
+
+        dfXRes = (dfMaxX - dfMinX) / nForcePixels;
+        dfYRes = (dfMaxY - dfMinY) / nForceLines;
+
+        adfDstGeoTransform[0] = dfMinX;
+        adfDstGeoTransform[3] = dfMaxY;
+        adfDstGeoTransform[1] = dfXRes;
+        adfDstGeoTransform[5] = -dfYRes;
+
+        nPixels = nForcePixels;
+        nLines = nForceLines;
+    }
+
+    else if( nForcePixels != 0 )
+    {
+        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0 )
+        {
+            dfMinX = dfWrkMinX;
+            dfMaxX = dfWrkMaxX;
+            dfMaxY = dfWrkMaxY;
+            dfMinY = dfWrkMinY;
+        }
+
+        dfXRes = (dfMaxX - dfMinX) / nForcePixels;
+        dfYRes = dfXRes;
+
+        adfDstGeoTransform[0] = dfMinX;
+        adfDstGeoTransform[3] = dfMaxY;
+        adfDstGeoTransform[1] = dfXRes;
+        adfDstGeoTransform[5] = -dfYRes;
+
+        nPixels = nForcePixels;
+        nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
+    }
+
+    else if( nForceLines != 0 )
+    {
+        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0 )
+        {
+            dfMinX = dfWrkMinX;
+            dfMaxX = dfWrkMaxX;
+            dfMaxY = dfWrkMaxY;
+            dfMinY = dfWrkMinY;
+        }
+
+        dfYRes = (dfMaxY - dfMinY) / nForceLines;
+        dfXRes = dfYRes;
+
+        adfDstGeoTransform[0] = dfMinX;
+        adfDstGeoTransform[3] = dfMaxY;
+        adfDstGeoTransform[1] = dfXRes;
+        adfDstGeoTransform[5] = -dfYRes;
+
+        nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
+        nLines = nForceLines;
+    }
+
+    else if( dfMinX != 0.0 || dfMinY != 0.0 || dfMaxX != 0.0 || dfMaxY != 0.0 )
+    {
+        dfXRes = adfDstGeoTransform[1];
+        dfYRes = fabs(adfDstGeoTransform[5]);
+
+        nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
+        nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
+
+        dfXRes = (dfMaxX - dfMinX) / nPixels;
+        dfYRes = (dfMaxY - dfMinY) / nLines;
+
+        adfDstGeoTransform[0] = dfMinX;
+        adfDstGeoTransform[3] = dfMaxY;
+        adfDstGeoTransform[1] = dfXRes;
+        adfDstGeoTransform[5] = -dfYRes;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Do we want to generate an alpha band in the output file?        */
+/* -------------------------------------------------------------------- */
+    if( bEnableSrcAlpha )
+        nDstBandCount--;
+
+    if( bEnableDstAlpha )
+        nDstBandCount++;
+
+/* -------------------------------------------------------------------- */
+/*      Create the output file.                                         */
+/* -------------------------------------------------------------------- */
+    if( !bQuiet )
+        printf( "Creating output file that is %dP x %dL.\n", nPixels, nLines );
+
+    hDstDS = GDALCreate( hDriver, pszFilename, nPixels, nLines, 
+                         nDstBandCount, eDT, *ppapszCreateOptions );
+    
+    if( hDstDS == NULL )
+    {
+        CPLFree( pszThisTargetSRS );
+        return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write out the projection definition.                            */
+/* -------------------------------------------------------------------- */
+    GDALSetProjection( hDstDS, pszThisTargetSRS );
+    GDALSetGeoTransform( hDstDS, adfDstGeoTransform );
+
+    if (*phTransformArg != NULL)
+        GDALSetGenImgProjTransformerDstGeoTransform( *phTransformArg, adfDstGeoTransform);
+
+/* -------------------------------------------------------------------- */
+/*      Try to set color interpretation of source bands to target       */
+/*      dataset.                                                        */
+/*      FIXME? We should likely do that for other drivers than VRT      */
+/*      but it might create spurious .aux.xml files (at least with HFA, */
+/*      and netCDF)                                                     */
+/* -------------------------------------------------------------------- */
+    if( bVRT )
+    {
+        int nBandsToCopy = (int)apeColorInterpretations.size();
+        if ( bEnableSrcAlpha )
+            nBandsToCopy --;
+        for(int iBand = 0; iBand < nBandsToCopy; iBand++)
+        {
+            GDALSetRasterColorInterpretation(
+                GDALGetRasterBand( hDstDS, iBand + 1 ),
+                apeColorInterpretations[iBand] );
+        }
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Try to set color interpretation of output file alpha band.      */
+/* -------------------------------------------------------------------- */
+    if( bEnableDstAlpha )
+    {
+        GDALSetRasterColorInterpretation( 
+            GDALGetRasterBand( hDstDS, nDstBandCount ), 
+            GCI_AlphaBand );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Copy the color table, if required.                              */
+/* -------------------------------------------------------------------- */
+    if( hCT != NULL )
+    {
+        GDALSetRasterColorTable( GDALGetRasterBand(hDstDS,1), hCT );
+        GDALDestroyColorTable( hCT );
+    }
+
+    CPLFree( pszThisTargetSRS );
+    return hDstDS;
+}
+
+/************************************************************************/
+/*                      GeoTransform_Transformer()                      */
+/*                                                                      */
+/*      Convert points from georef coordinates to pixel/line based      */
+/*      on a geotransform.                                              */
+/************************************************************************/
+
+class CutlineTransformer : public OGRCoordinateTransformation
+{
+public:
+
+    void         *hSrcImageTransformer;
+
+    virtual OGRSpatialReference *GetSourceCS() { return NULL; }
+    virtual OGRSpatialReference *GetTargetCS() { return NULL; }
+
+    virtual int Transform( int nCount, 
+                           double *x, double *y, double *z = NULL ) {
+        int nResult;
+
+        int *pabSuccess = (int *) CPLCalloc(sizeof(int),nCount);
+        nResult = TransformEx( nCount, x, y, z, pabSuccess );
+        CPLFree( pabSuccess );
+
+        return nResult;
+    }
+
+    virtual int TransformEx( int nCount, 
+                             double *x, double *y, double *z = NULL,
+                             int *pabSuccess = NULL ) {
+        return GDALGenImgProjTransform( hSrcImageTransformer, TRUE, 
+                                        nCount, x, y, z, pabSuccess );
+    }
+};
+
+
+/************************************************************************/
+/*                            LoadCutline()                             */
+/*                                                                      */
+/*      Load blend cutline from OGR datasource.                         */
+/************************************************************************/
+
+static void
+LoadCutline( const char *pszCutlineDSName, const char *pszCLayer, 
+             const char *pszCWHERE, const char *pszCSQL, 
+             void **phCutlineRet )
+
+{
+#ifndef OGR_ENABLED
+    CPLError( CE_Failure, CPLE_AppDefined, 
+              "Request to load a cutline failed, this build does not support OGR features.\n" );
+    GDALExit( 1 );
+#else // def OGR_ENABLED
+    OGRRegisterAll();
+
+/* -------------------------------------------------------------------- */
+/*      Open source vector dataset.                                     */
+/* -------------------------------------------------------------------- */
+    OGRDataSourceH hSrcDS;
+
+    hSrcDS = OGROpen( pszCutlineDSName, FALSE, NULL );
+    if( hSrcDS == NULL )
+        GDALExit( 1 );
+
+/* -------------------------------------------------------------------- */
+/*      Get the source layer                                            */
+/* -------------------------------------------------------------------- */
+    OGRLayerH hLayer = NULL;
+
+    if( pszCSQL != NULL )
+        hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszCSQL, NULL, NULL ); 
+    else if( pszCLayer != NULL )
+        hLayer = OGR_DS_GetLayerByName( hSrcDS, pszCLayer );
+    else
+        hLayer = OGR_DS_GetLayer( hSrcDS, 0 );
+
+    if( hLayer == NULL )
+    {
+        fprintf( stderr, "Failed to identify source layer from datasource.\n" );
+        GDALExit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Apply WHERE clause if there is one.                             */
+/* -------------------------------------------------------------------- */
+    if( pszCWHERE != NULL )
+        OGR_L_SetAttributeFilter( hLayer, pszCWHERE );
+
+/* -------------------------------------------------------------------- */
+/*      Collect the geometries from this layer, and build list of       */
+/*      burn values.                                                    */
+/* -------------------------------------------------------------------- */
+    OGRFeatureH hFeat;
+    OGRGeometryH hMultiPolygon = OGR_G_CreateGeometry( wkbMultiPolygon );
+
+    OGR_L_ResetReading( hLayer );
+    
+    while( (hFeat = OGR_L_GetNextFeature( hLayer )) != NULL )
+    {
+        OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat);
+
+        if( hGeom == NULL )
+        {
+            fprintf( stderr, "ERROR: Cutline feature without a geometry.\n" );
+            GDALExit( 1 );
+        }
+        
+        OGRwkbGeometryType eType = wkbFlatten(OGR_G_GetGeometryType( hGeom ));
+
+        if( eType == wkbPolygon )
+            OGR_G_AddGeometry( hMultiPolygon, hGeom );
+        else if( eType == wkbMultiPolygon )
+        {
+            int iGeom;
+
+            for( iGeom = 0; iGeom < OGR_G_GetGeometryCount( hGeom ); iGeom++ )
+            {
+                OGR_G_AddGeometry( hMultiPolygon, 
+                                   OGR_G_GetGeometryRef(hGeom,iGeom) );
+            }
+        }
+        else
+        {
+            fprintf( stderr, "ERROR: Cutline not of polygon type.\n" );
+            GDALExit( 1 );
+        }
+
+        OGR_F_Destroy( hFeat );
+    }
+
+    if( OGR_G_GetGeometryCount( hMultiPolygon ) == 0 )
+    {
+        fprintf( stderr, "ERROR: Did not get any cutline features.\n" );
+        GDALExit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Ensure the coordinate system gets set on the geometry.          */
+/* -------------------------------------------------------------------- */
+    OGR_G_AssignSpatialReference(
+        hMultiPolygon, OGR_L_GetSpatialRef(hLayer) );
+
+    *phCutlineRet = (void *) hMultiPolygon;
+
+/* -------------------------------------------------------------------- */
+/*      Cleanup                                                         */
+/* -------------------------------------------------------------------- */
+    if( pszCSQL != NULL )
+        OGR_DS_ReleaseResultSet( hSrcDS, hLayer );
+
+    OGR_DS_Destroy( hSrcDS );
+#endif
+}
+
+/************************************************************************/
+/*                      TransformCutlineToSource()                      */
+/*                                                                      */
+/*      Transform cutline from its SRS to source pixel/line coordinates.*/
+/************************************************************************/
+static void
+TransformCutlineToSource( GDALDatasetH hSrcDS, void *hCutline,
+                          char ***ppapszWarpOptions, char **papszTO_In )
+
+{
+#ifdef OGR_ENABLED
+    OGRGeometryH hMultiPolygon = OGR_G_Clone( (OGRGeometryH) hCutline );
+    char **papszTO = CSLDuplicate( papszTO_In );
+
+/* -------------------------------------------------------------------- */
+/*      Checkout that SRS are the same.                                 */
+/* -------------------------------------------------------------------- */
+    OGRSpatialReferenceH  hRasterSRS = NULL;
+    const char *pszProjection = NULL;
+
+    if( GDALGetProjectionRef( hSrcDS ) != NULL 
+        && strlen(GDALGetProjectionRef( hSrcDS )) > 0 )
+        pszProjection = GDALGetProjectionRef( hSrcDS );
+    else if( GDALGetGCPProjection( hSrcDS ) != NULL )
+        pszProjection = GDALGetGCPProjection( hSrcDS );
+
+    if( pszProjection != NULL )
+    {
+        hRasterSRS = OSRNewSpatialReference(NULL);
+        if( OSRImportFromWkt( hRasterSRS, (char **)&pszProjection ) != CE_None )
+        {
+            OSRDestroySpatialReference(hRasterSRS);
+            hRasterSRS = NULL;
+        }
+    }
+
+    OGRSpatialReferenceH hCutlineSRS = OGR_G_GetSpatialReference( hMultiPolygon );
+    if( hRasterSRS != NULL && hCutlineSRS != NULL )
+    {
+        /* ok, we will reproject */
+    }
+    else if( hRasterSRS != NULL && hCutlineSRS == NULL )
+    {
+        fprintf(stderr,
+                "Warning : the source raster dataset has a SRS, but the cutline features\n"
+                "not.  We assume that the cutline coordinates are expressed in the destination SRS.\n"
+                "If not, cutline results may be incorrect.\n");
+    }
+    else if( hRasterSRS == NULL && hCutlineSRS != NULL )
+    {
+        fprintf(stderr,
+                "Warning : the input vector layer has a SRS, but the source raster dataset does not.\n"
+                "Cutline results may be incorrect.\n");
+    }
+
+    if( hRasterSRS != NULL )
+        OSRDestroySpatialReference(hRasterSRS);
+
+/* -------------------------------------------------------------------- */
+/*      Extract the cutline SRS WKT.                                    */
+/* -------------------------------------------------------------------- */
+    if( hCutlineSRS != NULL )
+    {
+        char *pszCutlineSRS_WKT = NULL;
+
+        OSRExportToWkt( hCutlineSRS, &pszCutlineSRS_WKT );
+        papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszCutlineSRS_WKT );
+        CPLFree( pszCutlineSRS_WKT );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      It may be unwise to let the mask geometry be re-wrapped by      */
+/*      the CENTER_LONG machinery as this can easily screw up world     */
+/*      spanning masks and invert the mask topology.                    */
+/* -------------------------------------------------------------------- */
+    papszTO = CSLSetNameValue( papszTO, "INSERT_CENTER_LONG", "FALSE" );
+
+/* -------------------------------------------------------------------- */
+/*      Transform the geometry to pixel/line coordinates.               */
+/* -------------------------------------------------------------------- */
+    CutlineTransformer oTransformer;
+
+    /* The cutline transformer will *invert* the hSrcImageTransformer */
+    /* so it will convert from the cutline SRS to the source pixel/line */
+    /* coordinates */
+    oTransformer.hSrcImageTransformer = 
+        GDALCreateGenImgProjTransformer2( hSrcDS, NULL, papszTO );
+
+    CSLDestroy( papszTO );
+
+    if( oTransformer.hSrcImageTransformer == NULL )
+        GDALExit( 1 );
+
+    OGR_G_Transform( hMultiPolygon, 
+                     (OGRCoordinateTransformationH) &oTransformer );
+
+    GDALDestroyGenImgProjTransformer( oTransformer.hSrcImageTransformer );
+
+/* -------------------------------------------------------------------- */
+/*      Convert aggregate geometry into WKT.                            */
+/* -------------------------------------------------------------------- */
+    char *pszWKT = NULL;
+
+    OGR_G_ExportToWkt( hMultiPolygon, &pszWKT );
+    OGR_G_DestroyGeometry( hMultiPolygon );
+
+    *ppapszWarpOptions = CSLSetNameValue( *ppapszWarpOptions, 
+                                          "CUTLINE", pszWKT );
+    CPLFree( pszWKT );
+#endif
+}
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/LICENSE
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/LICENSE	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/LICENSE	(revision 672)
@@ -0,0 +1,21 @@
+ZOO-Kernel License
+
+Copyright (c) 2009-2013 GeoLabs SARL
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the “Software”), to deal
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies of this Software or works derived from this Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/Makefile	(revision 672)
@@ -0,0 +1,5 @@
+cgi-env/service.zo: servive.for
+	gfortran -shared -fpic -o cgi-env/fortran_hello.zo ./service.f
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/cgi-env/hellof.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/cgi-env/hellof.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/cgi-env/hellof.zcfg	(revision 672)
@@ -0,0 +1,40 @@
+[hellof]
+ Title = Hello string
+ Abstract = Create a welcome message.
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = driftx_service.zo
+ serviceType = C-FORTRAN
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = The string
+   Abstract = The name to display in the welcome message.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [result]
+   Title = The string
+   Abstract = The string created by service.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/service.f
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/service.f	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-fortran/service.f	(revision 672)
@@ -0,0 +1,44 @@
+ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+c     Simply create a welcome message
+ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+       Integer FUNCTION HELLOF(zoo_main_cfg,zoo_inputs,zoo_outputs)
+     & RESULT (R)
+       Integer R, ls, iLenStr
+       CHARACTER*(1024) zoo_main_cfg(10,30),zoo_inputs(10,30),
+     & zoo_outputs(10,30)
+        CHARACTER*(1024) TMP
+
+       write(0,*) 'Hello '//zoo_inputs(4,1)//' from the Fortran world !'
+
+       ls = iLenStr(zoo_inputs(4,1))
+       TMP = zoo_inputs(4,1)
+       zoo_outputs(1,1) = 'name'//CHAR(0)
+       zoo_outputs(2,1) = 'result'//CHAR(0)
+       zoo_outputs(3,1) = 'value'//CHAR(0)
+       zoo_outputs(4,1) = 'Hello '//TMP(1:ls)//
+     & ' from the Fortran world !'//CHAR(0)
+       zoo_outputs(5,1) = 'datatype'//CHAR(0)
+       zoo_outputs(6,1) = 'string'//CHAR(0)
+
+       R = 3
+       Return
+       END
+
+       Integer Function iLenStr(cString)
+ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+c     Compute String Length (thanks to Abdelatif Djerboua from RHEA™)
+ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+       Character*(*) cString
+       Integer       iLen,i
+
+      iLen = Len(cString)
+      Do i=iLen,1,-1
+         If(ichar(cString(i:i)).NE.0) Goto 10
+      EndDo
+      i = 1
+  10  Continue
+      iLenStr = i
+
+      Return
+      End Function iLenStr
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/HelloJava.java
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/HelloJava.java	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/HelloJava.java	(revision 672)
@@ -0,0 +1,53 @@
+/**
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2008-2009 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+import java.lang.*;
+import java.util.*;
+
+public class HelloJava {
+    public static int HelloWorldJava(HashMap conf,HashMap inputs, HashMap outputs) {
+        HashMap tmp=(HashMap)(inputs.get("S"));
+        String v=tmp.get("value").toString();
+        HashMap hm1 = (HashMap)(outputs.get("Result"));
+        hm1.put("value",ZOO._("Hello "+v+" from JAVA World !!"));
+        return ZOO.SERVICE_SUCCEEDED;
+    }
+    public static int JavaLongProcess(HashMap conf,HashMap inputs, HashMap outputs) {
+        HashMap tmp=(HashMap)(inputs.get("S"));
+        String v=tmp.get("value").toString();
+	Integer i;
+	for(i=0;i<100;i+=5){
+	    ZOO.updateStatus(conf,String.valueOf(i),"Currently executing tasks "+String.valueOf(i/5)+"..");
+	    try{
+		Thread.sleep(2000);
+	    }catch(java.lang.InterruptedException e){
+	    }finally{
+	    }
+	}
+        HashMap hm1 = (HashMap)(outputs.get("Result"));
+        hm1.put("value",ZOO._("Hello "+v+" from JAVA World !!"));
+        return ZOO.SERVICE_SUCCEEDED;
+    }
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/Makefile	(revision 672)
@@ -0,0 +1,5 @@
+cgi-env/HelloJava.class: HelloJava.java
+	javac -d cgi-env -cp ../../zoo-api/java/ HelloJava.java 
+
+clean:
+	rm cgi-env/*class
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/HelloWorldJava.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/HelloWorldJava.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/HelloWorldJava.zcfg	(revision 672)
@@ -0,0 +1,33 @@
+[HelloWorldJava]
+ Title = Display a string
+ Abstract = Display a string which contains an hello message
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = HelloJava
+ serviceType = Java
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = the string
+   Abstract = The string to add to the hellow one.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The hello string
+   Abstract = The Hello message string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/JavaLongProcess.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/JavaLongProcess.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-java/cgi-env/JavaLongProcess.zcfg	(revision 672)
@@ -0,0 +1,33 @@
+[JavaLongProcess]
+ Title = Display a string
+ Abstract = Display a string which contains an hello message after waiting many times to illustrate the way you can use updateStatus ZOO-API function from your Java service
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = HelloJava
+ serviceType = Java
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = the string
+   Abstract = The string to add to the hellow one.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The hello string
+   Abstract = The Hello message string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hello.js
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hello.js	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hello.js	(revision 672)
@@ -0,0 +1,36 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+function hellojs(conf,inputs,outputs){
+	outputs["result"]["value"]="Hello "+inputs["S"]["value"]+" from the JS World !";
+	//SERVICE_SUCEEDED
+	return Array(3,outputs);
+}
+
+function hellojs1(conf,inputs,outputs){
+	outputs["result"]["value"]="Hello "+inputs["S"]["value"]+" from the JS World !";
+	//SERVICE_SUCEEDED
+	return {"result":3,"outputs": outputs};
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs.zcfg	(revision 672)
@@ -0,0 +1,40 @@
+[hellojs]
+ Title = HelloWorld Service in JavaScript
+ Abstract = Output and Hello Wolrd string
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = hello.js
+ serviceType = JS
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = Name
+   Abstract = The name to display in the hello message
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [result]
+   Title = The resulting string
+   Abstract = The string created by service.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralOutput>
+     dataType = string
+     <Default>
+     </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs1.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs1.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-js/cgi-env/hellojs1.zcfg	(revision 672)
@@ -0,0 +1,40 @@
+[hellojs1]
+ Title = HelloWorld Service in JavaScript
+ Abstract = Output and Hello Wolrd string
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = hello.js
+ serviceType = JS
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = Name
+   Abstract = The name to display in the hello message
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [result]
+   Title = The resulting string
+   Abstract = The string created by service.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralOutput>
+     dataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/Hello.pl
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/Hello.pl	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/Hello.pl	(revision 672)
@@ -0,0 +1,32 @@
+#
+# Author : David Saggiorato
+#
+# Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including with
+# out limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+sub HelloPL {
+	my ($main_conf,$real_inputs,$real_outputs) = @_;
+	
+	$real_outputs->{"Result"}->{"value"}=$real_inputs->{"a"}->{"value"};
+	return 3;
+}
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/cgi-env/HelloPL.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/cgi-env/HelloPL.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-perl/cgi-env/HelloPL.zcfg	(revision 672)
@@ -0,0 +1,39 @@
+[HelloPL]
+ Title = Create a welcome message string.
+ Abstract = Create a welcome string.
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = Hello.pl
+ serviceType = Perl
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [a]
+   Title = Input string
+   Abstract = The name to display in the welcome message.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = My test
+   </MetaData>
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The welcome message
+   Abstract = The welcome message created by service.
+   <MetaData>
+    title = My test
+   </MetaData>
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataOutputs>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/HelloPHP.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/HelloPHP.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/HelloPHP.zcfg	(revision 672)
@@ -0,0 +1,33 @@
+[HelloPHP]
+ Title = Display a string
+ Abstract = Display a string which contains an hello message
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = hello.php
+ serviceType = PHP
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [S]
+   Title = the string
+   Abstract = The string to add to the hellow one.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The hello string
+   Abstract = The Hello message string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/hello.php
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/hello.php	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-php/cgi-env/hello.php	(revision 672)
@@ -0,0 +1,34 @@
+<?
+
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-20013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+function HelloPHP(&$main_conf,&$inputs,&$outputs){
+  $tmp="Hello ".$inputs["S"]["value"]." from the PHP world !!";
+  $outputs["Result"]["value"]=zoo_Translate($tmp);
+  zoo_UpdateStatus($main_conf,"Final step",99);
+  return zoo_SERVICE_SUCCEEDED();
+}
+
+?>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/HelloPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/HelloPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/HelloPy.zcfg	(revision 672)
@@ -0,0 +1,47 @@
+[HelloPy]
+ Title = Create a welcome message string.
+ Abstract = Create a welcome string.
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = test_service
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [a]
+   Title = Input string
+   Abstract = The name to display in the welcome message.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = My test
+   </MetaData>
+   <LiteralData>
+    DataType = string
+    <Default>
+     UOM = meter
+    </Default>
+    <Supported>
+     UOM = meter
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The welcome message
+   Abstract = The welcome message created by service.
+   <MetaData>
+    title = My test
+   </MetaData>
+   <LiteralData>
+    DataType = string
+    <Default>
+     UOM = meter
+    </Default>
+    <Supported>
+     UOM = meter
+    </Supported>
+   </LiteralData>
+ </DataOutputs>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/test_service.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/test_service.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/hello-py/cgi-env/test_service.py	(revision 672)
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+#
+# Author : Gérald FENOY
+#
+# Copyright 2008-2013 GeoLabs SARL. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including with
+# out limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+import zoo
+
+def HelloPy(conf,inputs,outputs):
+	outputs["Result"]["value"]="Hello "+inputs["a"]["value"]+" from Python World !"
+	return zoo.SERVICE_SUCCEEDED
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BoundaryPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BoundaryPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BoundaryPy.zcfg	(revision 672)
@@ -0,0 +1,56 @@
+[BoundaryPy]
+ Title = Computes boundary.
+ Abstract = A new geometry object is created and returned containing the boundary of the geometry on which the method is invoked. 
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to conpute boundary
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The geometry created
+   Abstract = The geometry containing the boundary of the geometry on which the method is invoked.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BufferPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BufferPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/BufferPy.zcfg	(revision 672)
@@ -0,0 +1,68 @@
+[BufferPy]
+ Title = Creates a buffer around a polygon. 
+ Abstract = Creates a buffer around a single polygon. Accepts the polygon as GML and provides GML output for the buffered feature. 
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to be buffered
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     asReference = true	
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+  [BufferDistance]
+   Title = Buffer Distance
+   Abstract = Distance to be used to calculate buffer.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = float
+    <Default>
+     uom = meters
+     value = 1
+    </Default>
+    <Supported>
+     uom = feet
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Buffered Polygon
+   Abstract = GML stream describing the buffered polygon feature.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg	(revision 672)
@@ -0,0 +1,43 @@
+[Clean]
+ Title = Computes the centroid of a polygon 
+ Abstract = Computes the centroid of a polygon that have a valid geometry field.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <DataInputs>
+  [InputData]
+   Title = Polygon to get the centroid
+   Abstract = The centroid which is not necessarily within the geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The Centroid
+   Abstract = JSON String / GML Entity of the centroid
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/point.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ConvexHullPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ConvexHullPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ConvexHullPy.zcfg	(revision 672)
@@ -0,0 +1,51 @@
+[ConvexHullPy]
+ Title = Computes convex hull.
+ Abstract = A new geometry object is created and returned containing the convex hull of the geometry on which the method is invoked.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to compute convexhull
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+   title = Mon test
+   </MetaData>
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The convex hull of the geometry
+   Abstract = The convex hull of the geometry
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataOutputs> 
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/DifferencePy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/DifferencePy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/DifferencePy.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[DifferencePy]
+ Title = Computes difference. 
+ Abstract = Generates a new geometry which is the region of this geometry with the region of the other geometry removed.
+ Profile = urn:ogc:wps:1.0.0:difference
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The difference between two geometries
+   Abstract = The difference between the two geometries.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/IntersectionPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/IntersectionPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/IntersectionPy.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[IntersectionPy]
+ Title = Computes intersection. 
+ Abstract = Generates a new geometry which is the region of intersection of the two geometries operated on.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Intersection of the two geometries
+   Abstract = A new geometry representing the intersection or NULL if there is no intersection or an error occurs.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/SymDifferencePy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/SymDifferencePy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/SymDifferencePy.zcfg	(revision 672)
@@ -0,0 +1,83 @@
+[SymDifferencePy]
+ Title = Computes symmetric difference. 
+ Abstract = Generates a new geometry which is the symmetric difference of this geometry and the other geometry.
+ Profile = urn:ogc:wps:1.0.0:symmetricdifference
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Supported>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The symmetric difference between two geometries
+   Abstract = The symmetric difference between the two geometries.
+   <MetaData>
+    title = Symmetric Difference  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/UnionPy.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/UnionPy.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/UnionPy.zcfg	(revision 672)
@@ -0,0 +1,73 @@
+[UnionPy]
+ Title = Computes union. 
+ Abstract = Generates a new geometry which is the region of union of the two geometries operated on.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_sp
+ serviceType = Python
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The union of two geometries
+   Abstract = The geometry representing the union of the two geometries.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://schemas.opengis.net/gml/3.1.0/base/feature.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 672)
@@ -0,0 +1,394 @@
+# -*- coding: utf-8 -*-
+#
+# Author : Gérald FENOY
+#
+# Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including with
+# out limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+from osgeo import *
+import osgeo.ogr
+import osgeo.gdal
+import libxml2
+import os
+import sys
+import zoo
+
+def readFileFromBuffer(data,ext):
+    try:
+        geometry=[]
+        print >> sys.stderr,'/vsimem//temp1'+ext
+        #print >> sys.stderr,data
+        osgeo.gdal.FileFromMemBuffer('/vsimem//temp1'+ext,data)
+        ds = osgeo.ogr.Open('/vsimem//temp1'+ext)
+        lyr = ds.GetLayer(0)
+        feat = lyr.GetNextFeature()
+        while feat is not None:
+            geometry+=[feat.Clone()]
+            feat.Destroy()
+            feat = lyr.GetNextFeature()
+        ds.Destroy()
+        osgeo.gdal.Unlink('/vsimem//temp1'+ext)
+        return geometry
+    except Exception,e:
+        print >> sys.stderr,e
+        return []
+    
+def buildFeatureFromGeomtry(conf,geom,driverName,ext):
+    drv = osgeo.ogr.GetDriverByName( driverName )
+    ds = drv.CreateDataSource( "/vsimem//store"+conf["lenv"]["sid"]+"0."+ext )
+    lyr = ds.CreateLayer( "Result", None, osgeo.ogr.wkbUnknown )
+    field_defn = osgeo.ogr.FieldDefn( "Name", osgeo.ogr.OFTString )
+    field_defn.SetWidth( len("Result10000") )
+    lyr.CreateField ( field_defn )
+    feat = osgeo.ogr.Feature(lyr.GetLayerDefn())
+    feat.SetField( "Name", "Input0" )
+    feat.SetGeometry(geom)
+    lyr.CreateFeature(feat)
+    ds.Destroy()
+    return [feat]
+
+def createGeometryFromWFS(conf,my_wfs_response):
+    try:
+        geom=osgeo.ogr.CreateGeometryFromGML(my_wfs_response.replace('<?xml version="1.0" encoding="utf-8"?>\n','').replace('<?xml version=\'1.0\' encoding="utf-8"?>\n',''))
+    except Exception,e:
+        print >> sys.stderr,"**"
+        print >> sys.stderr,e
+        geom=None
+    try:
+        print >> sys.stderr,geom is None
+        if geom is None:
+            if not(conf["lenv"].has_key("cnt")):
+                conf["lenv"]["cnt"]=0
+            else:
+                conf["lenv"]["cnt"]+=1
+            return readFileFromBuffer(my_wfs_response,str(conf["lenv"]["cnt"]))
+        else:
+            return buildFeatureFromGeomtry(conf,geom,"GML","xml")
+    except:
+        print >> sys.stderr,"Unable to load file input data !!!\n\n\n"
+
+def createLayerFromJson(conf,obj):
+    geom=osgeo.ogr.CreateGeometryFromJson(obj)
+    if geom is None:
+        return readFileFromBuffer(obj,".json")
+    else:
+        return buildFeatureFromGeomtry(conf,geom,"GeoJSON","json")
+
+def extractInputs(conf,obj):
+    if obj["mimeType"]=="application/json":
+        return createLayerFromJson(conf,obj["value"])
+    else:
+        return createGeometryFromWFS(conf,obj["value"])
+    
+def outputResult(conf,obj,geom):
+    if obj["mimeType"].count("text/xml")>0:
+        driverName = "GML"
+        extension = [ ".xml" , ".xsd" ]
+        format_list = { "2.": 'GML2', "3.1.1": 'GML3', "3.1": 'GML3Deegree', "3.2": 'GML3.2' }
+        opts=['FORMAT=%s,GML3_LONGSRS=YES',format_list["3.2"]]
+        for i in format_list:
+            if obj["mimeType"].count(i)>0:
+                opts=['FORMAT=%s,GML3_LONGSRS=YES',format_list[i]]
+    if obj["mimeType"]=="application/json":
+        driverName = "GeoJSON"
+        extension = [ ".js" ]
+        opts=None
+    if obj.keys().count("schema")>0 and \
+            obj["schema"]=="http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd":
+        driverName = "KML"
+        extension = [ ".kml" ]
+        opts=None
+    drv = osgeo.ogr.GetDriverByName( driverName )
+    print >> sys.stderr,drv
+    # Create virtual file
+    ds = drv.CreateDataSource( "/vsimem/store"+conf["lenv"]["sid"]+extension[0],options = opts)
+    print >> sys.stderr,ds
+    lyr = ds.CreateLayer( "Result", None, osgeo.ogr.wkbUnknown )
+    print >> sys.stderr,lyr
+    i=0
+    print >> sys.stderr,driverName
+    print >> sys.stderr,extension
+    while i < len(geom):
+        if i==0 and driverName!="GeoJSON":
+            poDstFDefn=geom[i].GetDefnRef()
+            if poDstFDefn is not None:
+                nDstFieldCount = poDstFDefn.GetFieldCount()
+                for iField in range(nDstFieldCount):
+                    poSrcFieldDefn = poDstFDefn.GetFieldDefn(iField)
+                    oFieldDefn = osgeo.ogr.FieldDefn(poSrcFieldDefn.GetNameRef(),poSrcFieldDefn.GetType())
+                    oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() )
+                    oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
+                    lyr.CreateField( oFieldDefn )
+        try:
+            lyr.CreateFeature(geom[i])
+        except:
+            pass
+        geom[i].Destroy()
+        i+=1
+    ds.Destroy()
+    vsiFile=osgeo.gdal.VSIFOpenL("/vsimem/store"+conf["lenv"]["sid"]+extension[0],"r")
+    i=0
+    while osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_END)>0:
+        i+=1
+    fileSize=osgeo.gdal.VSIFTellL(vsiFile)
+    osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_SET)
+    obj["value"]=osgeo.gdal.VSIFReadL(fileSize,1,vsiFile)
+    osgeo.gdal.Unlink("/vsimem/store"+conf["lenv"]["sid"]+extension[0])
+
+def BufferPy(conf,inputs,outputs):
+    print >> sys.stderr, "Starting service ..."
+    try:
+        bdist=float(inputs["BufferDistance"]["value"])
+    except:
+        bdist=1
+    print >> sys.stderr, bdist
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef().Buffer(bdist)
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        resg.thisown=False 
+        tmp.thisown=False
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    i=0
+    return zoo.SERVICE_SUCCEEDED
+
+def Clean(conf,inputs,outputs):
+    from shapely.wkb import loads
+    print >> sys.stderr, "Starting service ..."
+    features=extractInputs(conf,inputs["InputData"])
+    i=0
+    rgeometries=[]
+    while i < len(features):
+        tmp=features[i].Clone()
+        resg=features[i].GetGeometryRef()
+        if resg is not None:
+            geom = loads(resg.ExportToWkb())
+            if geom.is_valid:
+                tmp.SetGeometryDirectly(resg)
+                rgeometries+=[tmp]
+                print >> sys.stderr,"valid !"
+            else:
+                print >> sys.stderr,"invalid !"
+                print >> sys.stderr,geom.wkt[0:50]
+        features[i].Destroy()
+        resg.thisown=False 
+        tmp.thisown=False
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    i=0
+    print >> sys.stderr,"Return"
+    return zoo.SERVICE_SUCCEEDED
+
+def TransformService(conf,inputs,outputs):
+    from osgeo import osr
+    geometry=extractInputs(conf,inputs["InputData"])
+    sourceRef = osr.SpatialReference()
+    tmp=inputs["SourceCRS"]["value"].split(":")
+    sourceRef.ImportFromEPSG(int(tmp[len(tmp)-1]))
+    targetRef = osr.SpatialReference()    
+    tmp=inputs["TargetCRS"]["value"].split(":")
+    targetRef.ImportFromEPSG(int(tmp[len(tmp)-1]))
+    transform = osr.CoordinateTransformation(sourceRef, targetRef)
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        resg.Transform(transform)
+        tmp.SetGeometryDirectly(resg.Clone())
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["TransformedData"],rgeometries)
+    return zoo.SERVICE_SUCCEEDED
+
+def BoundaryPy(conf,inputs,outputs):
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        resg=resg.GetBoundary()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return zoo.SERVICE_SUCCEEDED
+
+def CentroidPy(conf,inputs,outputs):
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        if resg.GetGeometryType()!=3:
+            resg=resg.ConvexHull()
+        resg=resg.Centroid()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return zoo.SERVICE_SUCCEEDED
+
+def ConvexHullPy(conf,inputs,outputs):
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef().ConvexHull()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return zoo.SERVICE_SUCCEEDED
+
+
+
+def EnvelopePy(conf,inputs,outputs):
+    print >> sys.stderr, inputs
+    try:
+        bdist=float(inputs["BufferDistance"]["value"])
+    except:
+        bdist=10
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    tmp=geometry[0].GetGeometryRef().GetEnvelope()
+    outputs["Result"]["value"]=str(tmp[0])+','+str(tmp[2])+','+str(tmp[1])+','+str(tmp[3])+','+'urn:ogc:def:crs:OGC:1.3:CRS84'
+    print >> sys.stderr,outputs["Result"]
+    return 3
+
+def UnionPy(conf,inputs,outputs):
+    geometry1=extractInputs(conf,inputs["InputEntity1"])
+    geometry2=extractInputs(conf,inputs["InputEntity2"])
+    rgeometries=[]
+    i=0
+    while i < len(geometry1):
+        j=0
+        while j < len(geometry2):
+            tmp=geometry1[i].Clone()
+            resg=geometry2[j].GetGeometryRef()
+            resg=resg.Union(geometry1[i].GetGeometryRef())
+            tmp.SetGeometryDirectly(resg)
+            if not(resg.IsEmpty()):
+                rgeometries+=[tmp]
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return 3
+
+def IntersectionPy(conf,inputs,outputs):
+
+    geometry1=extractInputs(conf,inputs["InputEntity1"])
+    geometry2=extractInputs(conf,inputs["InputEntity2"])
+
+    print >> sys.stderr,str(len(geometry1))+" "+str(len(geometry2))
+
+    rgeometries=[]
+    fids=[]
+    i=0
+    while i < len(geometry1):
+        j=0
+        while j < len(geometry2):
+            tmp=geometry2[j].Clone()
+            resg=geometry2[j].GetGeometryRef()
+            #resg=resg.Intersection(geometry1[i].GetGeometryRef())
+            resg=geometry1[i].GetGeometryRef().Intersection(resg)
+            tmp.SetGeometryDirectly(resg)
+            if resg is not None and not(resg.IsEmpty()) and fids.count(tmp.GetFID())==0:
+                rgeometries+=[tmp]
+                fids+=[tmp.GetFID()]
+            else:
+                tmp.Destroy()
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    print >> sys.stderr,"/outputResult"
+    return 3
+
+def DifferencePy(conf,inputs,outputs):
+    geometry1=extractInputs(conf,inputs["InputEntity1"])
+    geometry2=extractInputs(conf,inputs["InputEntity2"])
+    rgeometries=[]
+    i=0
+    while i < len(geometry1):
+        j=0
+        while j < len(geometry2):
+            tmp=geometry2[j].Clone()
+            resg=geometry1[i].GetGeometryRef()
+            resg=resg.Difference(geometry2[i].GetGeometryRef())
+            tmp.SetGeometryDirectly(resg)
+            if not(resg.IsEmpty()):
+                rgeometries+=[tmp]
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return 3
+
+def SymDifferencePy(conf,inputs,outputs):
+    geometry1=extractInputs(conf,inputs["InputEntity1"])
+    geometry2=extractInputs(conf,inputs["InputEntity2"])
+    rgeometries=[]
+    i=0
+    while i < len(geometry1):
+        j=0
+        while j < len(geometry2):
+            tmp=geometry2[j].Clone()
+            resg=geometry1[i].GetGeometryRef()
+            resg=resg.SymmetricDifference(geometry2[i].GetGeometryRef())
+            tmp.SetGeometryDirectly(resg)
+            rgeometries+=[tmp]
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return 3
+
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/Makefile	(revision 672)
@@ -0,0 +1,19 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${JSCFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${GEOS_CFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+
+ifneq ($(MS_FILE),)
+	MS_FILES=${ZRPATH}/zoo-kernel/${MS_FILE} -lmapserver
+else
+	MS_FILES=
+endif
+
+cgi-env/ogr_service.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/ogr_service.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${GEOS_LDFLAGS} -lfcgi  -lpthread -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/ogr/base-vect-ops
+	install cgi-env/* ${CGI_DIR}/ogr/base-vect-ops
+
+clean:
+	rm -f cgi-env/ogr_service.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Boundary.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Boundary.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Boundary.zcfg	(revision 672)
@@ -0,0 +1,60 @@
+[Boundary]
+ Title = Computes boundary.
+ Abstract = This service shall return a feature callection representing the combinatorial boundary of each geometry in the InputPolygon feature collection.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to compute boundary
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The geometry created
+   Abstract = The geometry containing the boundary of the geometry on which the method is invoked.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     extension = xml
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Supported>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     extension = xml
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Buffer.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Buffer.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Buffer.zcfg	(revision 672)
@@ -0,0 +1,70 @@
+[Buffer]
+ Title = Create a buffer around a polygon. 
+ Abstract = This service shall return a feature collection representing the buffer of geometry InputPolygon at distance BufferDistance. The buffer of a geometry at distance d is the Polygon or MultiPolygon which contains all points within a distance d of the geometry.
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to be buffered
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     asReference = true	
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+  [BufferDistance]
+   Title = Buffer Distance
+   Abstract = Distance to be used to calculate buffer.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = float
+    <Default>
+     uom = meters
+     value = 10
+    </Default>
+    <Supported>
+     uom = feet
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Buffered Polygon
+   Abstract = GML stream describing the buffered polygon feature.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     extension = xml
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Centroid.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Centroid.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Centroid.zcfg	(revision 672)
@@ -0,0 +1,55 @@
+[Centroid]
+ Title = Computes the centroid of a polygon. 
+ Abstract = This service shall return the point that is the geometric centre of gravity of the geometry InputPolygon.
+ Profile = urn:ogc:wps:1.0.0:centroid
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to get the centroid
+   Abstract = The centroid which is not necessarily within the geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The Centroid
+   Abstract = JSON String / GML Entity of the centroid
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/point.xsd
+     extension = xml
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Contains.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Contains.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Contains.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Contains]
+ Title = Contains
+ Abstract = This service shall return a true value if and only if the geometry g2 lies in the closure (boundary union interior) of geometry g1 - the inverse of Within(g1: Geometry, g2: Geometry).
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Contains result
+   Abstract = A value true or false if the geometry1 contains the geometry2.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/ConvexHull.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/ConvexHull.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/ConvexHull.zcfg	(revision 672)
@@ -0,0 +1,54 @@
+[ConvexHull]
+ Title = Compute convex hull.
+ Abstract = This service shall return a feature collection that represents the convex hull of geometry InputPolygon. The convex hull is the smallest convex polygon that contains all points of the geometry. The convex Hull for a geometry of encoding data type Point is the point itself
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to compute convexhull
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+   title = Mon test
+   </MetaData>
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The convex hull of the geometry
+   Abstract = The convex hull of the geometry
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     extension = xml
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Supported>
+   </ComplexData>
+ </DataOutputs> 
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Crosses.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Crosses.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Crosses.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Crosses]
+ Title = Crosses test
+ Abstract = This service shall return a true value if and only if the geometries g1 and g2 share some but neither is containe in the other, and the dimension of the intersection is less than that of both of the geometries.
+ processVersion = 2
+ profile = urn:ogc:wps:1.0.0:union
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Disjoint result
+   Abstract = true if disjoint.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Difference.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Difference.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Difference.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[Difference]
+ Title = Compute difference. 
+ Abstract = This function shall return a bag of geometry values representing the closure of the set difference between the two geometries InputEntity1 and InputEntity2. The difference is the set of all points which lie on InputEntity1 but not on InputEntity2.
+ Profile = urn:ogc:wps:1.0.0:difference
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The difference between two geometries
+   Abstract = The difference between the two geometries.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      encoding = UTF-8
+      schema = http://fooa/gml/3.1.0/polygon.xsd
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Disjoint.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Disjoint.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Disjoint.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Disjoint]
+ Title = Disjoint 
+ Abstract = This servuce shall return a true value if and only if the geometries g1 and g2 have no point in common.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Disjoint result
+   Abstract = true if disjoint.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Distance.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Distance.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Distance.zcfg	(revision 672)
@@ -0,0 +1,71 @@
+[Distance]
+ Title = Compute the distance between two geometries
+ Abstract = Compute the distance between two geometries
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Distance]
+   Title = The distance between two geometries
+   Abstract = The shortest distance between the two geometries.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+     DataType = float
+     <Default>
+      uom = meters
+     </Default>
+     <Supported>
+      uom = feet
+     </Supported>
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Equals.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Equals.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Equals.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Equals]
+ Title = Equals 
+ Abstract = This service shall return a true value if and only if the geometries g1 and g2 are equal
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Equals result
+   Abstract = Should be true if two geometries are equivalent..
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/GetArea.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/GetArea.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/GetArea.zcfg	(revision 672)
@@ -0,0 +1,50 @@
+[GetArea]
+ Title = Compute geometry area.
+ Abstract = Computes the area of a geometry
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to compute are
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+   title = Mon test
+   </MetaData>
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Area]
+   Title = Computed Area
+   Abstract = The Computed Area Value
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <LiteralData>
+    DataType = float
+    <Default>
+     uom = degree
+    </Default>
+    <Supported>
+     uom = meter
+    </Supported>
+   </LiteralData>
+ </DataOutputs> 
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersection.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersection.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersection.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[Intersection]
+ Title = Compute intersection. 
+ Abstract = This function SHALL return a bag of geometry values representing the Point set intersection of geometry InputEntity1 and geometry InputEntity2.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Intersection of geometries
+   Abstract = A new geometry representing the intersection or NULL if there is no intersection or an error occurs.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      encoding = UTF-8
+      schema = http://fooa/gml/3.1.0/polygon.xsd
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersects.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersects.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Intersects.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Intersects]
+ Title = Intersects test
+ Abstract = This service shall return a true value if and only if the geometries g1 and g2 have at least one boundary point in common, but no interior points.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Contains result
+   Abstract = A value true or false if the geometry1 contains the geometry2.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsSimple.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsSimple.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsSimple.zcfg	(revision 672)
@@ -0,0 +1,37 @@
+[IsSimple]
+ Title = IsSimple test 
+ Abstract = This service shall return a true value if and only if geometry g has no anomalous geometric points, such as self intersection or self tangency. Simple curves intersect themselves only at their endpoints (only if they are also closed, see next function).
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputPolygon]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = IsSimple result
+   Abstract = The boolean result
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsValid.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsValid.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/IsValid.zcfg	(revision 672)
@@ -0,0 +1,37 @@
+[IsValid]
+ Title = IsValid test 
+ Abstract = This service shall return a TRUE value if and only if the geometry g is valid
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputPolygon]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Equals result
+   Abstract = Should be true if two geometries are equivalent..
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Simplify.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Simplify.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Simplify.zcfg	(revision 672)
@@ -0,0 +1,61 @@
+[Simplify]
+ Title = Simplifies polygons geometries. 
+ Abstract = This service shall return a feature collection representing all simplified geometries with all their vertices within the distance of the original geometry defined by the given tolerance.
+ Profile = urn:ogc:wps:1.0.0:buffer
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputPolygon]
+   Title = Polygon to be simplified
+   Abstract = URI to a set of GML that describes the polygon.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     asReference = true	
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+  [Tolerance]
+   Title = Buffer Distance
+   Abstract = Distance tolerance for the simplification.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = float
+    <Default>
+     uom = meters
+     value = 2
+    </Default>
+    <Supported>
+     uom = feet
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Simplified features
+   Abstract = GML stream describing the simplified features.
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     extension = xml
+    </Default>
+    <Supported>
+     mimeType = application/json
+     encoding = UTF-8
+     extension = js
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/SymDifference.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/SymDifference.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/SymDifference.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[SymDifference]
+ Title = Compute symmetric difference. 
+ Abstract = This service shall return a feature collection representing the closure of the symmetric difference of two Geometries. The symmetric difference is the set of points which lie on either InputEntity1 or InputEntity2 but not in both.
+ Profile = urn:ogc:wps:1.0.0:symmetricdifference
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting geometry
+   Abstract = The symmetric difference of two geometries
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://fooa/gml/3.1.0/polygon.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Touches.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Touches.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Touches.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Touches]
+ Title = Compute intersection. 
+ Abstract = Generates a new geometry which is the region of intersection of the two geometries operated on.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Intersects result
+   Abstract = A value true or false if the geometry1 and geometry2 touches.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Union.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Union.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Union.zcfg	(revision 672)
@@ -0,0 +1,75 @@
+[Union]
+ Title = Compute union. 
+ Abstract = This service shall return a bag of geometry values representing a Point set union of geometry InputEntity1 with geometry InputEntity2.
+ profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <MetaData>
+   title = Demo
+ </MetaData>
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry to compare against.
+   minOccurs = 1
+   maxOccurs = 1
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The union of two geometries
+   Abstract = The geometry representing the union of the two geometries.
+   <MetaData>
+    title = Mon test  
+   </MetaData>
+    <ComplexData>
+     <Default>
+      mimeType = text/xml
+      schema = http://fooa/gml/3.1.0/polygon.xsd
+      encoding = UTF-8
+      extension = xml
+     </Default>
+     <Supported>
+      mimeType = application/json
+      encoding = UTF-8
+      extension = js
+     </Supported>
+    </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Within.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Within.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/cgi-env/Within.zcfg	(revision 672)
@@ -0,0 +1,57 @@
+[Within]
+ Title = Within test
+ Abstract = This service shall return a true value if and only if the geometry InputEntity1 is spatially within geometry InputEntity2; that is if every point on InputEntity1 is also on InputEntity2.
+ Profile = urn:ogc:wps:1.0.0:union
+ processVersion = 2
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = ogr_service.zo
+ serviceType = C
+ <DataInputs>
+  [InputEntity1]
+   Title = the first geometry 
+   Abstract = the first geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+  [InputEntity2]
+   Title = the other geometry
+   Abstract = the other geometry.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+     encoding = UTF-8
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = base64
+     schema = http://fooa/gml/3.1.0/polygon.xsd
+    </Supported>
+   </ComplexData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = Within result
+   Abstract = A value true or false if the geometry1 contains the geometry2.
+   <MetaData>
+    title = Mon test  
+   </MetaData>   
+    <LiteralData>
+      dataType=boolean
+      <Default />
+    </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/fr_FR.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/fr_FR.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/fr_FR.utf8.po	(revision 672)
@@ -0,0 +1,320 @@
+# French translations for PACKAGE package.
+# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# root <gerald.fenoy@geolabs.fr>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: zoo-services\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 12:52+0200\n"
+"PO-Revision-Date: 2010-09-28 12:55+0200\n"
+"Last-Translator: root <gerald.fenoy@geolabs.fr>\n"
+"Language-Team: French\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: locale/.cache/my_service_string_to_translate.c:1
+msgid "Compute boundary."
+msgstr "Calcul le contour."
+
+#: locale/.cache/my_service_string_to_translate.c:2
+msgid "Polygon to compute boundary"
+msgstr "Le polygon à utiliser pour calculer le contour"
+
+#: locale/.cache/my_service_string_to_translate.c:3
+msgid "The geometry created"
+msgstr "La géométrie créée"
+
+#: locale/.cache/my_service_string_to_translate.c:4
+msgid ""
+"A new geometry object is created and returned containing the boundary of the "
+"geometry on which the method is invoked. "
+msgstr ""
+"Un nouvel objet géographique contenant le contour de la géométrie passée en "
+"paramètre est créé et retourné. "
+
+#: locale/.cache/my_service_string_to_translate.c:5
+#: locale/.cache/my_service_string_to_translate.c:12
+#: locale/.cache/my_service_string_to_translate.c:25
+#: locale/.cache/my_service_string_to_translate.c:47
+#: locale/.cache/my_service_string_to_translate.c:62
+msgid "URI to a set of GML that describes the polygon."
+msgstr "Le lien vers un fichier GML décrivant un polygone."
+
+#: locale/.cache/my_service_string_to_translate.c:6
+msgid ""
+"The geometry containing the boundary of the geometry on which the method is "
+"invoked."
+msgstr ""
+"La géométrie contenant le contour de la géométrie passée en paramètre."
+
+#: locale/.cache/my_service_string_to_translate.c:7
+msgid "Create a buffer around a polygon. "
+msgstr "Crée une zone tampon atour du polygone."
+
+#: locale/.cache/my_service_string_to_translate.c:8
+msgid "Polygon to be buffered"
+msgstr "Le Polygone à utiliser"
+
+#: locale/.cache/my_service_string_to_translate.c:9
+msgid "Buffer Distance"
+msgstr "La distance pour créer la zone tampon"
+
+#: locale/.cache/my_service_string_to_translate.c:10
+msgid "Buffered Polygon"
+msgstr "La zone tampon correspondant au polygone "
+
+#: locale/.cache/my_service_string_to_translate.c:11
+msgid ""
+"Create a buffer around a single polygon. Accepts the polygon as GML and "
+"provides GML output for the buffered feature. "
+msgstr ""
+"Crée une zone tampon autour d'un polygone. Prend en entrée un GML et fournit une "
+"chaîne GeoJSON de la zone tampon. "
+
+#: locale/.cache/my_service_string_to_translate.c:13
+msgid "Distance to be used to calculate buffer."
+msgstr "La distance à utiliser pour créer la zone tampon."
+
+#: locale/.cache/my_service_string_to_translate.c:14
+msgid "GML stream describing the buffered polygon feature."
+msgstr "Une chaîne GeoJSON contenant la zone tampon."
+
+#: locale/.cache/my_service_string_to_translate.c:15
+msgid "Get the centroid of a polygon. "
+msgstr "Renvoit le centroid d'un polygone"
+
+#: locale/.cache/my_service_string_to_translate.c:16
+msgid "Polygon to get the centroid"
+msgstr "Le polygone à utiliser pour calculer le centroid"
+
+#: locale/.cache/my_service_string_to_translate.c:17
+msgid "The Centroid"
+msgstr "Le centroid"
+
+#: locale/.cache/my_service_string_to_translate.c:18
+msgid "Compute the geometry centroid."
+msgstr "Calcul le centroid d'une géométrie"
+
+#: locale/.cache/my_service_string_to_translate.c:19
+msgid "The centroid which is not necessarily within the geometry."
+msgstr "Le centroid qui n'est pas nécessairement dans la géométrie."
+
+#: locale/.cache/my_service_string_to_translate.c:20
+msgid "JSON String / GML Entity of the centroid"
+msgstr "La chaîne GeoJSON ou l'entité GML du centroid"
+
+#: locale/.cache/my_service_string_to_translate.c:21
+msgid "Compute convex hull."
+msgstr "Calcul de la partie convexe"
+
+#: locale/.cache/my_service_string_to_translate.c:22
+msgid "Polygon to compute convexhull"
+msgstr "Polygone pour calculer la partie convexe"
+
+#: locale/.cache/my_service_string_to_translate.c:23
+#: locale/.cache/my_service_string_to_translate.c:26
+msgid "The convex hull of the geometry"
+msgstr "La partie convexe de la géométrie"
+
+#: locale/.cache/my_service_string_to_translate.c:24
+msgid ""
+"A new geometry object is created and returned containing the convex hull of "
+"the geometry on which the method is invoked."
+msgstr ""
+"Un nouvel objet géographique est créé et retourné. Il contient la partie convexe de la "
+"géométrie sur laquelle on a appliqué la méthode."
+
+#: locale/.cache/my_service_string_to_translate.c:27
+msgid "Compute difference. . "
+msgstr "Calcul de la différence."
+
+#: locale/.cache/my_service_string_to_translate.c:28
+#: locale/.cache/my_service_string_to_translate.c:36
+#: locale/.cache/my_service_string_to_translate.c:50
+#: locale/.cache/my_service_string_to_translate.c:66
+#: locale/.cache/my_service_string_to_translate.c:74
+msgid "the first geometry "
+msgstr "La première géométrie"
+
+#: locale/.cache/my_service_string_to_translate.c:29
+#: locale/.cache/my_service_string_to_translate.c:37
+#: locale/.cache/my_service_string_to_translate.c:51
+#: locale/.cache/my_service_string_to_translate.c:67
+#: locale/.cache/my_service_string_to_translate.c:75
+msgid "the other geometry"
+msgstr "L'autre géométrie"
+
+#: locale/.cache/my_service_string_to_translate.c:30
+msgid "The difference between two geometries"
+msgstr "La différence entre les deux géométries"
+
+#: locale/.cache/my_service_string_to_translate.c:31
+msgid ""
+"Generates a new geometry which is the region of this geometry with the "
+"region of the other geometry removed."
+msgstr ""
+"Génère une nouvelle géométrie qui contient la région de la géométrie dont on a "
+"supprimé l'autre géométrie."
+
+
+#: locale/.cache/my_service_string_to_translate.c:32
+#: locale/.cache/my_service_string_to_translate.c:40
+#: locale/.cache/my_service_string_to_translate.c:54
+#: locale/.cache/my_service_string_to_translate.c:70
+#: locale/.cache/my_service_string_to_translate.c:78
+msgid "the first geometry to compare against."
+msgstr "La première géométrie utilisée pour la comparaison"
+
+#: locale/.cache/my_service_string_to_translate.c:33
+#: locale/.cache/my_service_string_to_translate.c:41
+#: locale/.cache/my_service_string_to_translate.c:55
+#: locale/.cache/my_service_string_to_translate.c:71
+#: locale/.cache/my_service_string_to_translate.c:79
+msgid "the other geometry to compare against."
+msgstr "L'autre géométrie à comparer."
+
+#: locale/.cache/my_service_string_to_translate.c:34
+msgid "The difference between the two geometries."
+msgstr "La différence entre les deux géométries."
+
+#: locale/.cache/my_service_string_to_translate.c:35
+msgid "Calcul la distance entre deux entites geographique. "
+msgstr "Calcul de la distance entre deux objets géographiques."
+
+#: locale/.cache/my_service_string_to_translate.c:38
+msgid "The distance between two geometries"
+msgstr "La distance entre deux géométries"
+
+#: locale/.cache/my_service_string_to_translate.c:39
+msgid "Calcul de la distance entre deux entites geographique. "
+msgstr "Calcul de la distance entre deux entités géographiques."
+
+#: locale/.cache/my_service_string_to_translate.c:42
+msgid "The shortest distance between the two geometries."
+msgstr "La plus courte distance entre de géométries."
+
+#: locale/.cache/my_service_string_to_translate.c:43
+msgid "Compute geometry area."
+msgstr "Calcul l'aire de la géométrie."
+
+#: locale/.cache/my_service_string_to_translate.c:44
+msgid "Polygon to compute are"
+msgstr "Le polygone à utiliser"
+
+#: locale/.cache/my_service_string_to_translate.c:45
+msgid "Computed Area"
+msgstr "L'aire calculée"
+
+#: locale/.cache/my_service_string_to_translate.c:46
+msgid "Computes the area for a geometry"
+msgstr "Calcul de l'aire d'une géométrie"
+
+#: locale/.cache/my_service_string_to_translate.c:48
+msgid "The Computed Area Value"
+msgstr "La valeur de l'aire calculée"
+
+#: locale/.cache/my_service_string_to_translate.c:49
+msgid "Compute intersection. "
+msgstr "Calcul de l'intersection."
+
+#: locale/.cache/my_service_string_to_translate.c:52
+msgid "Intersection of geometries"
+msgstr "L'intersection des géométries."
+
+#: locale/.cache/my_service_string_to_translate.c:53
+msgid ""
+"Generates a new geometry which is the region of intersection of the two "
+"geometries operated on."
+msgstr ""
+"Crée une nouvelle géométrie qui représente l'intersection des deux géométries avec "
+"lesquelles le service est utilisé."
+
+#: locale/.cache/my_service_string_to_translate.c:56
+msgid ""
+"A new geometry representing the intersection or NULL if there is no "
+"intersection or an error occurs."
+msgstr ""
+"Une nouvelle géométrie représentant l'intersection ou NULL si l'intersection est vide "
+"si une erreur s'est produite."
+
+#: locale/.cache/my_service_string_to_translate.c:57
+msgid "Douglas-Peucker like algorithm"
+msgstr "Algorythme de simplification de type Douglas-Peucker"
+
+#: locale/.cache/my_service_string_to_translate.c:58
+msgid "Polygon to simplify"
+msgstr "Le polygone à simplifier"
+
+#: locale/.cache/my_service_string_to_translate.c:59
+msgid "Tolerance to use."
+msgstr "La tolérance à utliser."
+
+#: locale/.cache/my_service_string_to_translate.c:60
+msgid "The simplified geometry"
+msgstr "La géométrie simplifiée"
+
+#: locale/.cache/my_service_string_to_translate.c:61
+msgid ""
+"Simplifies a geometry, ensuring that the result is a valid geometry having "
+"the same dimension and number of components as the input. The simplification "
+"uses a maximum distance difference algorithm similar to the one used in the "
+"Douglas-Peucker algorithm."
+msgstr ""
+"Simplifie une géométrie, en s'assurant que le résultat soit une géométrie valide "
+"ayant la même dimension et le même nombre de composants que la donnée d'entrée. "
+"La simplification utilise un algorythme similaire à l'algorythme Douglas-Peucker."
+
+#: locale/.cache/my_service_string_to_translate.c:63
+msgid "The approximation tolerance to use."
+msgstr "La valeur approximative de la tolérance à utiliser."
+
+#: locale/.cache/my_service_string_to_translate.c:64
+msgid ""
+"The result has the same number of shells and holes (rings) as the input, in "
+"the same order. The result rings touch at no more than the number of "
+"touching point in the input (although they may touch at fewer points)."
+msgstr ""
+"Le résultat a le même nombre composant que l'entrée, dans le même ordre. "
+
+#: locale/.cache/my_service_string_to_translate.c:65
+msgid "Compute symmetric difference. "
+msgstr "Calcul de la différence symétrique."
+
+#: locale/.cache/my_service_string_to_translate.c:68
+msgid "The resulting geometry"
+msgstr "La géométrie résultat"
+
+#: locale/.cache/my_service_string_to_translate.c:69
+msgid ""
+"Generates a new geometry which is the symmetric difference of this geometry "
+"and the other geometry."
+msgstr ""
+"Crée une nouvelle géométrie qui est la difference symétrique des géométries."
+
+#: locale/.cache/my_service_string_to_translate.c:72
+msgid "The symmetric difference of two geometries"
+msgstr "La différence symmétrique de deux géométries"
+
+#: locale/.cache/my_service_string_to_translate.c:73
+msgid "Compute union. "
+msgstr "Cacul l'union."
+
+#: locale/.cache/my_service_string_to_translate.c:76
+msgid "The union of two geometries"
+msgstr "L'union de deux géométries"
+
+#: locale/.cache/my_service_string_to_translate.c:77
+msgid ""
+"Generates a new geometry which is the region of union of the two geometries "
+"operated on."
+msgstr ""
+"Génère une nouvelle géométrie qui est l'union des deux géométrie passées en "
+"paramètre."
+
+#: locale/.cache/my_service_string_to_translate.c:80
+msgid "The geometry representing the union of the two geometries."
+msgstr "La géométrie représentant l'union des deux géométries."
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/ja_JP.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/ja_JP.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/ja_JP.utf8.po	(revision 672)
@@ -0,0 +1,308 @@
+# Japanese translations for PACKAGE package.
+# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ZOO Services package.
+# Daisuke YOSHIDA <yoshida@la.tezuka-gu.ac.jp>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: zoo-services\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 12:52+0200\n"
+"PO-Revision-Date: 2010-09-28 12:55+0200\n"
+"Last-Translator: Daisuke YOSHIDA <yoshida@la.tezuka-gu.ac.jp>\n"
+"Language-Team: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: locale/.cache/my_service_string_to_translate.c:1
+msgid "Compute boundary."
+msgstr "境界線を計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:2
+msgid "Polygon to compute boundary"
+msgstr "境界線を計算するためのポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:3
+msgid "The geometry created"
+msgstr "ジオメトリが作成される．"
+
+#: locale/.cache/my_service_string_to_translate.c:4
+msgid ""
+"A new geometry object is created and returned containing the boundary of the "
+"geometry on which the method is invoked. "
+msgstr "新しいジオメトリオブジェクトは作成され，メソッド上に返答された境界面を含むジオメトリが，呼び出される．"
+
+
+#: locale/.cache/my_service_string_to_translate.c:5
+#: locale/.cache/my_service_string_to_translate.c:12
+#: locale/.cache/my_service_string_to_translate.c:25
+#: locale/.cache/my_service_string_to_translate.c:47
+#: locale/.cache/my_service_string_to_translate.c:62
+msgid "URI to a set of GML that describes the polygon."
+msgstr "ポリゴンが記述されているGMLセットへのURI．"
+
+#: locale/.cache/my_service_string_to_translate.c:6
+msgid ""
+"The geometry containing the boundary of the geometry on which the method is "
+"invoked."
+msgstr "メソッド上の地質境界面を含んでいるジオメトリを起動．"
+
+
+#: locale/.cache/my_service_string_to_translate.c:7
+msgid "Create a buffer around a polygon. "
+msgstr "ポリゴン周辺のバッファを作成．"
+
+#: locale/.cache/my_service_string_to_translate.c:8
+msgid "Polygon to be buffered"
+msgstr "バッファリングするポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:9
+msgid "Buffer Distance"
+msgstr "バッファ距離．"
+
+#: locale/.cache/my_service_string_to_translate.c:10
+msgid "Buffered Polygon"
+msgstr "バッファリングされたポリゴン． "
+
+#: locale/.cache/my_service_string_to_translate.c:11
+msgid ""
+"Create a buffer around a single polygon. Accepts the polygon as GML and "
+"provides GML output for the buffered feature. "
+msgstr "シングルポリゴン周辺のバッファの作成．GMLとしてポリゴンを許可し，バッファリングされたフィーチャーのためのGMLを提供．"
+
+#: locale/.cache/my_service_string_to_translate.c:13
+msgid "Distance to be used to calculate buffer."
+msgstr "バッファを計算するために使われる距離．"
+
+#: locale/.cache/my_service_string_to_translate.c:14
+msgid "GML stream describing the buffered polygon feature."
+msgstr "バッファリングされたポリゴンフィーチャーを記述するGML．"
+
+#: locale/.cache/my_service_string_to_translate.c:15
+msgid "Get the centroid of a polygon. "
+msgstr "ポリゴンの中心点を取得．"
+
+#: locale/.cache/my_service_string_to_translate.c:16
+msgid "Polygon to get the centroid"
+msgstr "中心点を取得するためのポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:17
+msgid "The Centroid"
+msgstr "中心点．"
+
+#: locale/.cache/my_service_string_to_translate.c:18
+msgid "Compute the geometry centroid."
+msgstr "ジオメトリの中心点を計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:19
+msgid "The centroid which is not necessarily within the geometry."
+msgstr "ジオメトリに含まれる重要ではない中心点．"
+
+#: locale/.cache/my_service_string_to_translate.c:20
+msgid "JSON String / GML Entity of the centroid"
+msgstr "中心点のJSON文字列／GMLエンティティ．"
+
+#: locale/.cache/my_service_string_to_translate.c:21
+msgid "Compute convex hull."
+msgstr "凸包を計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:22
+msgid "Polygon to compute convex hull"
+msgstr "凸包を計算するポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:23
+#: locale/.cache/my_service_string_to_translate.c:26
+msgid "The convex hull of the geometry"
+msgstr "ジオメトリの凸包．"
+
+#: locale/.cache/my_service_string_to_translate.c:24
+msgid ""
+"A new geometry object is created and returned containing the convex hull of "
+"the geometry on which the method is invoked."
+msgstr "新しいジオメトリオブジェクトは作成されメッソド上に返答され，凸包を含むジオメトリが呼び出される．"
+
+
+#: locale/.cache/my_service_string_to_translate.c:27
+msgid "Compute difference. . "
+msgstr "差分の計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:28
+#: locale/.cache/my_service_string_to_translate.c:36
+#: locale/.cache/my_service_string_to_translate.c:50
+#: locale/.cache/my_service_string_to_translate.c:66
+#: locale/.cache/my_service_string_to_translate.c:74
+msgid "the first geometry "
+msgstr "最初のジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:29
+#: locale/.cache/my_service_string_to_translate.c:37
+#: locale/.cache/my_service_string_to_translate.c:51
+#: locale/.cache/my_service_string_to_translate.c:67
+#: locale/.cache/my_service_string_to_translate.c:75
+msgid "the other geometry"
+msgstr "その他のジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:30
+msgid "The difference between two geometries"
+msgstr "２つのジオメトリの差。"
+
+#: locale/.cache/my_service_string_to_translate.c:31
+msgid ""
+"Generates a new geometry which is the region of this geometry with the "
+"region of the other geometry removed."
+msgstr "他のジオメトリを削除した領域に，このジオメトリの領域の新しいジオメトリ"
+"を作成"
+
+
+#: locale/.cache/my_service_string_to_translate.c:32
+#: locale/.cache/my_service_string_to_translate.c:40
+#: locale/.cache/my_service_string_to_translate.c:54
+#: locale/.cache/my_service_string_to_translate.c:70
+#: locale/.cache/my_service_string_to_translate.c:78
+msgid "the first geometry to compare against."
+msgstr "対比比較する最初のジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:33
+#: locale/.cache/my_service_string_to_translate.c:41
+#: locale/.cache/my_service_string_to_translate.c:55
+#: locale/.cache/my_service_string_to_translate.c:71
+#: locale/.cache/my_service_string_to_translate.c:79
+msgid "the other geometry to compare against."
+msgstr "対比比較するその他のジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:34
+msgid "The difference between the two geometries."
+msgstr "2つのジオメトリの差分．"
+
+#: locale/.cache/my_service_string_to_translate.c:35
+msgid "Calcul la distance entre deux entites geographique. "
+msgstr "Calcul de la distance entre deux objets géographiques."
+
+#: locale/.cache/my_service_string_to_translate.c:38
+msgid "The distance between two geometries"
+msgstr "２つのジオメトリの距離．"
+
+#: locale/.cache/my_service_string_to_translate.c:39
+msgid "Calcul de la distance entre deux entites geographique. "
+msgstr "Calcul de la distance entre deux entités géographiques."
+
+#: locale/.cache/my_service_string_to_translate.c:42
+msgid "The shortest distance between the two geometries."
+msgstr "二つのジオメトリの最短距離."
+
+#: locale/.cache/my_service_string_to_translate.c:43
+msgid "Compute geometry area."
+msgstr "ジオメトリ面積の計算."
+
+#: locale/.cache/my_service_string_to_translate.c:44
+msgid "Polygon to compute area"
+msgstr "面積計算するためのポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:45
+msgid "Computed Area"
+msgstr "面積計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:46
+msgid "Computes the area for a geometry"
+msgstr "ジオメトリの面積を計算する．"
+
+#: locale/.cache/my_service_string_to_translate.c:48
+msgid "The Computed Area Value"
+msgstr "計算された面積の値．"
+
+#: locale/.cache/my_service_string_to_translate.c:49
+msgid "Compute intersection. "
+msgstr "交点を計算する．"
+
+#: locale/.cache/my_service_string_to_translate.c:52
+msgid "Intersection of geometries"
+msgstr "ジオメトリの交点．"
+
+#: locale/.cache/my_service_string_to_translate.c:53
+msgid ""
+"Generates a new geometry which is the region of intersection of the two "
+"geometries operated on."
+msgstr "操作された２つのジオメトリの交点の領域の新しいジオメトリを作成．"
+
+
+#: locale/.cache/my_service_string_to_translate.c:56
+msgid ""
+"A new geometry representing the intersection or NULL if there is no "
+"intersection or an error occurs."
+msgstr "もし交点、またはエラーが起こっていない場合、交点またはNULLを表す新しいジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:57
+msgid "Douglas-Peucker like algorithm"
+msgstr "Douglas-Peucker的アルゴリズム．"
+
+#: locale/.cache/my_service_string_to_translate.c:58
+msgid "Polygon to simplify"
+msgstr "単純化するためのポリゴン．"
+
+#: locale/.cache/my_service_string_to_translate.c:59
+msgid "Tolerance to use."
+msgstr "使用する許容値．"
+
+#: locale/.cache/my_service_string_to_translate.c:60
+msgid "The simplified geometry"
+msgstr "単純化されたジオメトリ．"
+
+#: locale/.cache/my_service_string_to_translate.c:61
+msgid ""
+"Simplifies a geometry, ensuring that the result is a valid geometry having "
+"the same dimension and number of components as the input. The simplification "
+"uses a maximum distance difference algorithm similar to the one used in the "
+"Douglas-Peucker algorithm."
+msgstr ""
+"ジオメトリを単純化"
+"結果がインプットとして同じ次元とコンポーネント数が等しい有効なジオメトリか確認．"
+"単純化では，Douglas-Peuckerアルゴリズムと類似した最大距離を使うアルゴリズムを使用．"
+
+#: locale/.cache/my_service_string_to_translate.c:63
+msgid "The approximation tolerance to use."
+msgstr "使用する許容値の概要．"
+
+#: locale/.cache/my_service_string_to_translate.c:64
+msgid ""
+"The result has the same number of shells and holes (rings) as the input, in "
+"the same order. The result rings touch at no more than the number of "
+"touching point in the input (although they may touch at fewer points)."
+msgstr "結果はインプットとしてshells とholes (rings）が共に等しい数，順序になる．"
+"結果のリングはインプットの中のタッチングポイントの数まで達しない．（しかし，より少ないポイントをタッチするかもしれない．"
+#: locale/.cache/my_service_string_to_translate.c:65
+msgid "Compute symmetric difference. "
+msgstr "対照的な差を計算．"
+
+#: locale/.cache/my_service_string_to_translate.c:68
+msgid "The resulting geometry"
+msgstr "ジオメトリの結果．"
+
+#: locale/.cache/my_service_string_to_translate.c:69
+msgid ""
+"Generates a new geometry which is the symmetric difference of this geometry "
+"and the other geometry."
+msgstr "このジオメトリと他のジオメトリで，対照的に異なった新しいジオメトリの作成"
+
+#: locale/.cache/my_service_string_to_translate.c:72
+msgid "The symmetric difference of two geometries"
+msgstr "2つのジオメトリの対照的違い．"
+
+#: locale/.cache/my_service_string_to_translate.c:73
+msgid "Compute union. "
+msgstr "結合の計算."
+
+#: locale/.cache/my_service_string_to_translate.c:76
+msgid "The union of two geometries"
+msgstr "2つのジオメトリの結合"
+
+#: locale/.cache/my_service_string_to_translate.c:77
+msgid ""
+"Generates a new geometry which is the region of union of the two geometries "
+"operated on."
+msgstr "操作された２つのジオメトリを結合した領域の新しいジオメトリの作成"
+
+#: locale/.cache/my_service_string_to_translate.c:80
+msgid "The geometry representing the union of the two geometries."
+msgstr "２つのジオメトリの結合を表すジオメトリ"
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/messages.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/messages.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/locale/po/messages.po	(revision 672)
@@ -0,0 +1,299 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: zoo-services\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-28 12:52+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: GÃ©rald Fenoy <gerald.fenoy@geolabs.fr>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: locale/.cache/my_service_string_to_translate.c:1
+msgid "Compute boundary."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:2
+msgid "Polygon to compute boundary"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:3
+msgid "The geometry created"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:4
+msgid ""
+"A new geometry object is created and returned containing the boundary of the "
+"geometry on which the method is invoked. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:5
+#: locale/.cache/my_service_string_to_translate.c:12
+#: locale/.cache/my_service_string_to_translate.c:25
+#: locale/.cache/my_service_string_to_translate.c:47
+#: locale/.cache/my_service_string_to_translate.c:62
+msgid "URI to a set of GML that describes the polygon."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:6
+msgid ""
+"The geometry containing the boundary of the geometry on which the method is "
+"invoked."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:7
+msgid "Create a buffer around a polygon. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:8
+msgid "Polygon to be buffered"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:9
+msgid "Buffer Distance"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:10
+msgid "Buffered Polygon"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:11
+msgid ""
+"Create a buffer around a single polygon. Accepts the polygon as GML and "
+"provides GML output for the buffered feature. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:13
+msgid "Distance to be used to calculate buffer."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:14
+msgid "GML stream describing the buffered polygon feature."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:15
+msgid "Get the centroid of a polygon. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:16
+msgid "Polygon to get the centroid"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:17
+msgid "The Centroid"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:18
+msgid "Compute the geometry centroid."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:19
+msgid "The centroid which is not necessarily within the geometry."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:20
+msgid "JSON String / GML Entity of the centroid"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:21
+msgid "Compute convex hull."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:22
+msgid "Polygon to compute convexhull"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:23
+#: locale/.cache/my_service_string_to_translate.c:26
+msgid "The convex hull of the geometry"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:24
+msgid ""
+"A new geometry object is created and returned containing the convex hull of "
+"the geometry on which the method is invoked."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:27
+msgid "Compute difference. . "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:28
+#: locale/.cache/my_service_string_to_translate.c:36
+#: locale/.cache/my_service_string_to_translate.c:50
+#: locale/.cache/my_service_string_to_translate.c:66
+#: locale/.cache/my_service_string_to_translate.c:74
+msgid "the first geometry "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:29
+#: locale/.cache/my_service_string_to_translate.c:37
+#: locale/.cache/my_service_string_to_translate.c:51
+#: locale/.cache/my_service_string_to_translate.c:67
+#: locale/.cache/my_service_string_to_translate.c:75
+msgid "the other geometry"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:30
+msgid "The difference between two geometries"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:31
+msgid ""
+"Generates a new geometry which is the region of this geometry with the "
+"region of the other geometry removed."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:32
+#: locale/.cache/my_service_string_to_translate.c:40
+#: locale/.cache/my_service_string_to_translate.c:54
+#: locale/.cache/my_service_string_to_translate.c:70
+#: locale/.cache/my_service_string_to_translate.c:78
+msgid "the first geometry to compare against."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:33
+#: locale/.cache/my_service_string_to_translate.c:41
+#: locale/.cache/my_service_string_to_translate.c:55
+#: locale/.cache/my_service_string_to_translate.c:71
+#: locale/.cache/my_service_string_to_translate.c:79
+msgid "the other geometry to compare against."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:34
+msgid "The difference between the two geometries."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:35
+msgid "Calcul la distance entre deux entites geographique. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:38
+msgid "The distance between two geometries"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:39
+msgid "Calcul de la distance entre deux entites geographique. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:42
+msgid "The shortest distance between the two geometries."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:43
+msgid "Compute geometry area."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:44
+msgid "Polygon to compute are"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:45
+msgid "Computed Area"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:46
+msgid "Computes the area for a geometry"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:48
+msgid "The Computed Area Value"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:49
+msgid "Compute intersection. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:52
+msgid "Intersection of geometries"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:53
+msgid ""
+"Generates a new geometry which is the region of intersection of the two "
+"geometries operated on."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:56
+msgid ""
+"A new geometry representing the intersection or NULL if there is no "
+"intersection or an error occurs."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:57
+msgid "Douglas-Peucker like algorithm"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:58
+msgid "Polygon to simplify"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:59
+msgid "Tolerance to use."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:60
+msgid "The simplified geometry"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:61
+msgid ""
+"Simplifies a geometry, ensuring that the result is a valid geometry having "
+"the same dimension and number of components as the input. The simplification "
+"uses a maximum distance difference algorithm similar to the one used in the "
+"Douglas-Peucker algorithm."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:63
+msgid "The approximation tolerance to use."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:64
+msgid ""
+"The result has the same number of shells and holes (rings) as the input, in "
+"the same order. The result rings touch at no more than the number of "
+"touching point in the input (although they may touch at fewer points)."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:65
+msgid "Compute symmetric difference. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:68
+msgid "The resulting geometry"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:69
+msgid ""
+"Generates a new geometry which is the symmetric difference of this geometry "
+"and the other geometry."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:72
+msgid "The symmetric difference of two geometries"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:73
+msgid "Compute union. "
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:76
+msgid "The union of two geometries"
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:77
+msgid ""
+"Generates a new geometry which is the region of union of the two geometries "
+"operated on."
+msgstr ""
+
+#: locale/.cache/my_service_string_to_translate.c:80
+msgid "The geometry representing the union of the two geometries."
+msgstr ""
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/makefile.vc	(revision 672)
@@ -0,0 +1,25 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/ogr_service.zo: service.c
+	$(CPP)  /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE -I$(GDAL_DIR)/frmts/ $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/ogr_service.zo  $(FILES) ./service.obj $(LDFLAGS) $(GEOS_DIR)/src/geos_c_i.lib /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\ogr_service.*
+
+#	link /dll /out:cgi-env/ogr_service.zo ../../../zoo-kernel/service_internal.obj ./service.obj -L$(TOOLS)/lib/libssl32.dll.a $(GEODIR)/lib/libxml2.lib $(GEODIR)/lib/gdal_i.lib $(GEODIR)/lib/geos_c_i.lib $(TPATH)/lib/libeay32.dll.a $(TPATH)/lib/libcrypto.a $(TPATH)/lib/libssl32.dll.a $(LIBINTL_CPATH)/lib/libintl.lib 
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/base-vect-ops/service.c	(revision 672)
@@ -0,0 +1,1472 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2008-2009 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "cpl_conv.h"
+#include "ogr_api.h"
+#include "ogr_geometry.h"
+
+#include "cpl_minixml.h"
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+
+#include "geos_c.h"
+#include "service.h"
+#include "service_internal.h"
+
+extern "C" {
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+  void printExceptionReportResponse(maps*,map*);
+  char *base64(const char *input, int length);
+
+  OGRGeometryH createGeometryFromGML(maps* conf,char* inputStr){
+    xmlInitParser();
+    xmlDocPtr doc = xmlParseMemory(inputStr,strlen(inputStr));
+    xmlChar *xmlbuff;
+    int buffersize;
+    xmlXPathContextPtr xpathCtx;
+    xmlXPathObjectPtr xpathObj;
+    const char * xpathExpr="/*/*/*/*/*[local-name()='Polygon' or local-name()='MultiPolygon']";
+    xpathCtx = xmlXPathNewContext(doc);
+    xpathObj = xmlXPathEvalExpression(BAD_CAST xpathExpr,xpathCtx);
+    if(!xpathObj->nodesetval){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse Input Polygon"));
+      setMapInMaps(conf,"lenv","code","InvalidParameterValue");
+      return NULL;
+    }
+    int size = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
+    /**
+     * Create a temporary XML document
+     */
+    xmlDocPtr ndoc = xmlNewDoc(BAD_CAST "1.0");
+    /**
+     * Only one polygon should be provided so we use it as the root node.
+     */
+    for(int k=size-1;k>=0;k--){ 
+      xmlDocSetRootElement(ndoc, xpathObj->nodesetval->nodeTab[k]);
+    }
+    xmlDocDumpFormatMemory(ndoc, &xmlbuff, &buffersize, 1);
+    char *tmp=(char*)calloc((xmlStrlen(xmlStrstr(xmlbuff,BAD_CAST "?>"))-1),sizeof(char));
+    sprintf(tmp,"%s",xmlStrstr(xmlbuff,BAD_CAST "?>")+2);
+    xmlXPathFreeObject(xpathObj);
+    xmlXPathFreeContext(xpathCtx);
+    xmlFree(xmlbuff);
+    xmlFreeDoc(doc);
+    xmlFreeDoc(ndoc);
+#ifndef WIN32
+    xmlCleanupParser();
+#endif
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\n Loading the geometry from GML string ...");
+#endif
+    OGRGeometryH res=OGR_G_CreateFromGML(tmp);
+    free(tmp);
+    if(res==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to call OGR_G_CreatFromGML"));
+      return NULL;
+    }
+    else
+      return res;
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Simplify(maps*& conf,maps*& inputs,maps*& outputs){
+    OGRRegisterAll();
+
+    double tolerance;
+    map* tmp0=getMapFromMaps(inputs,"Tolerance","value");
+    if(tmp0==NULL){
+      tolerance=atof("2.0");
+    }
+    else
+      tolerance=atof(tmp0->value);
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry;
+    OGRGeometry *res;
+    OGRLayer *poDstLayer;
+    const char *oDriver1;
+    OGRDataSource       *poODS;
+    map* tmp=getMapFromMaps(inputs,"InputPolygon","value");
+    if(!tmp){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    char filename[1024];
+    map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    sprintf(filename,"/vsimem/input_%d.json",getpid());
+    if(tmp1!=NULL){
+      if(strcmp(tmp1->value,"text/xml")==0){
+	sprintf(filename,"/vsimem/input_%d.xml",getpid());
+	oDriver="GML";
+      }
+    }
+    VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmp->value,strlen(tmp->value),FALSE);
+    VSIFCloseL(ifile);
+    OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+    char pszDestDataSource[100];
+    if( ipoDS == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+	
+	if( poLayer == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+	
+	OGRFeature  *poFeature;
+	
+	OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+	OGRSFDriver          *poDriver = NULL;
+	int                  iDriver;
+	
+	map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+	oDriver1="GeoJSON";
+	sprintf(pszDestDataSource,"/vsimem/result_%d.json",getpid());
+	if(tmpMap!=NULL){
+	  if(strcmp(tmpMap->value,"text/xml")==0){
+	    sprintf(pszDestDataSource,"/vsimem/result_%d.xml",getpid());
+	    oDriver1="GML";
+	  }
+	}
+	
+	for( iDriver = 0;
+	     iDriver < poR->GetDriverCount() && poDriver == NULL;
+	     iDriver++ )
+	  {
+	    if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver1) )
+	      {
+		poDriver = poR->GetDriver(iDriver);
+	      }
+	  }
+	
+	if( poDriver == NULL )
+	  {
+	    char emessage[8192];
+	    sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	    sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+	    
+	    for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	      {
+		sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	      }
+	    
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	    
+	  }
+	
+	if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+	  char emessage[1024];
+	  sprintf( emessage,  "%s driver does not support data source creation.\n",
+		   "json" );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	char **papszDSCO=NULL;
+	poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+	if( poODS == NULL ){
+	  char emessage[1024];      
+	  sprintf( emessage,  "%s driver failed to create %s\n", 
+		   "json", pszDestDataSource );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	if( !poODS->TestCapability( ODsCCreateLayer ) )
+	  {
+	    char emessage[1024];
+	    sprintf( emessage, 
+		     "Layer %s not found, and CreateLayer not supported by driver.", 
+		     "Result" );
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	  }
+	
+	poDstLayer = poODS->CreateLayer( "Result", NULL,wkbUnknown,NULL);
+	if( poDstLayer == NULL ){
+	  setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+	  return SERVICE_FAILED;
+	}
+	
+	OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
+	int iField;
+	int hasMmField=0;
+	
+	for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
+	  {
+	    OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iField);
+            if (iField >= 0)
+                poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) );
+            else
+            {
+                fprintf( stderr, "Field '%s' not found in source layer.\n", 
+                        iField );
+		return SERVICE_FAILED;
+            }
+	  }
+
+	while(TRUE){
+	  OGRFeature      *poDstFeature = NULL;
+	  poFeature = poLayer->GetNextFeature();
+	  if( poFeature == NULL )
+	    break;
+	  if(poFeature->GetGeometryRef() != NULL){
+	    poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
+	    if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    geometry=poFeature->GetGeometryRef();
+#if GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR < 11
+	    GEOSGeometry* ggeometry=((OGRGeometry *) geometry)->exportToGEOS();
+	    GEOSGeometry* gres=GEOSTopologyPreserveSimplify(ggeometry,tolerance);
+	    if(gres!=NULL)
+	      res=(OGRGeometry*)OGRGeometryFactory::createFromGEOS(gres);
+#else
+	    res=((OGRGeometry *) geometry)->SimplifyPreserveTopology(tolerance);
+#endif
+	    if(poDstFeature->SetGeometryDirectly(res) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poFeature );
+	    if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
+	      {		
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poDstFeature );
+#if GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR < 11
+	    GEOSGeom_destroy( ggeometry);
+	    GEOSGeom_destroy( gres);
+#endif
+	  }
+	}
+      }
+
+    delete poODS;
+    delete ipoDS;
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+
+}
+
+  int applyOne(maps*& conf,maps*& inputs,maps*& outputs,OGRGeometry* (OGRGeometry::*myFunc)() const,const char* schema){
+    OGRRegisterAll();
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    OGRLayer *poDstLayer;
+    const char *oDriver1;
+    OGRDataSource       *poODS;
+    map* tmp=getMapFromMaps(inputs,"InputPolygon","value");
+    if(!tmp){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    char filename[1024];
+    map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    sprintf(filename,"/vsimem/input_%d.json",getpid());
+    if(tmp1!=NULL){
+      if(strcmp(tmp1->value,"text/xml")==0){
+	sprintf(filename,"/vsimem/input_%d.xml",getpid());
+	oDriver="GML";
+      }
+    }
+    VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmp->value,strlen(tmp->value),FALSE);
+    VSIFCloseL(ifile);
+    OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+    char pszDestDataSource[100];
+    if( ipoDS == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+	
+	if( poLayer == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+	
+	OGRFeature  *poFeature;
+
+	/* -------------------------------------------------------------------- */
+	/*      Try opening the output datasource as an existing, writable      */
+	/* -------------------------------------------------------------------- */
+	
+	OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+	OGRSFDriver          *poDriver = NULL;
+	int                  iDriver;
+	
+	map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+	oDriver1="GeoJSON";
+	sprintf(pszDestDataSource,"/vsimem/result_%d.json",getpid());
+	if(tmpMap!=NULL){
+	  if(strcmp(tmpMap->value,"text/xml")==0){
+	    sprintf(pszDestDataSource,"/vsimem/result_%d.xml",getpid());
+	    oDriver1="GML";
+	  }
+	}
+	
+	for( iDriver = 0;
+	     iDriver < poR->GetDriverCount() && poDriver == NULL;
+	     iDriver++ )
+	  {
+	    if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver1) )
+	      {
+		poDriver = poR->GetDriver(iDriver);
+	      }
+	  }
+	
+	if( poDriver == NULL )
+	  {
+	    char emessage[8192];
+	    sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	    sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+	    
+	    for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	      {
+		sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	      }
+	    
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	    
+	  }
+	
+	if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+	  char emessage[1024];
+	  sprintf( emessage,  "%s driver does not support data source creation.\n",
+		   "json" );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	/* -------------------------------------------------------------------- */
+	/*      Create the output data source.                                  */
+	/* -------------------------------------------------------------------- */
+	//map* tpath=getMapFromMaps(conf,"main","tmpPath");
+	char **papszDSCO=NULL;
+	poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+	if( poODS == NULL ){
+	  char emessage[1024];      
+	  sprintf( emessage,  "%s driver failed to create %s\n", 
+		   "json", pszDestDataSource );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	/* -------------------------------------------------------------------- */
+	/*      Create the layer.                                               */
+	/* -------------------------------------------------------------------- */
+	if( !poODS->TestCapability( ODsCCreateLayer ) )
+	  {
+	    char emessage[1024];
+	    sprintf( emessage, 
+		     "Layer %s not found, and CreateLayer not supported by driver.", 
+		     "Result" );
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	  }
+	
+	//CPLErrorReset();
+	
+	poDstLayer = poODS->CreateLayer( "Result", NULL,wkbUnknown,NULL);
+	if( poDstLayer == NULL ){
+	  setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+	  return SERVICE_FAILED;
+	}
+	
+	OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
+	int iField;
+	int hasMmField=0;
+	
+	for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
+	  {
+	    OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iField);
+            if (iField >= 0)
+                poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) );
+            else
+            {
+                fprintf( stderr, "Field '%s' not found in source layer.\n", 
+                        iField );
+		return SERVICE_FAILED;
+            }
+	  }
+
+	while(TRUE){
+	  OGRFeature      *poDstFeature = NULL;
+	  poFeature = poLayer->GetNextFeature();
+	  if( poFeature == NULL )
+	    break;
+	  if(poFeature->GetGeometryRef() != NULL){
+	    poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
+	    if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    if(poDstFeature->SetGeometryDirectly((poDstFeature->GetGeometryRef()->*myFunc)()) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poFeature );
+	    if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
+	      {		
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poDstFeature );
+	  }
+	}
+
+      }
+
+    delete poODS;
+    delete ipoDS;
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+int Buffer(maps*& conf,maps*& inputs,maps*& outputs){
+    OGRRegisterAll();
+
+    double bufferDistance;
+    map* tmp0=getMapFromMaps(inputs,"BufferDistance","value");
+    if(tmp0==NULL){
+      bufferDistance=atof("10.0");
+    }
+    else
+      bufferDistance=atof(tmp0->value);
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    OGRLayer *poDstLayer;
+    const char *oDriver1;
+    OGRDataSource       *poODS;
+    map* tmp=getMapFromMaps(inputs,"InputPolygon","value");
+    if(!tmp){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    char filename[1024];
+    map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    sprintf(filename,"/vsimem/input_%d.json",getpid());
+    if(tmp1!=NULL){
+      if(strcmp(tmp1->value,"text/xml")==0){
+	sprintf(filename,"/vsimem/input_%d.xml",getpid());
+	oDriver="GML";
+      }
+    }
+    VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmp->value,strlen(tmp->value),FALSE);
+    VSIFCloseL(ifile);
+    OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+    char pszDestDataSource[100];
+    if( ipoDS == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+	
+	if( poLayer == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+	
+	OGRFeature  *poFeature;
+
+	/* -------------------------------------------------------------------- */
+	/*      Try opening the output datasource as an existing, writable      */
+	/* -------------------------------------------------------------------- */
+	
+	OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+	OGRSFDriver          *poDriver = NULL;
+	int                  iDriver;
+	
+	map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+	oDriver1="GeoJSON";
+	sprintf(pszDestDataSource,"/vsimem/result_%d.json",getpid());
+	if(tmpMap!=NULL){
+	  if(strcmp(tmpMap->value,"text/xml")==0){
+	    sprintf(pszDestDataSource,"/vsimem/result_%d.xml",getpid());
+	    oDriver1="GML";
+	  }
+	}
+	
+	for( iDriver = 0;
+	     iDriver < poR->GetDriverCount() && poDriver == NULL;
+	     iDriver++ )
+	  {
+	    if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver1) )
+	      {
+		poDriver = poR->GetDriver(iDriver);
+	      }
+	  }
+	
+	if( poDriver == NULL )
+	  {
+	    char emessage[8192];
+	    sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	    sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+	    
+	    for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	      {
+		sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	      }
+	    
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	    
+	  }
+	
+	if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+	  char emessage[1024];
+	  sprintf( emessage,  "%s driver does not support data source creation.\n",
+		   "json" );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	/* -------------------------------------------------------------------- */
+	/*      Create the output data source.                                  */
+	/* -------------------------------------------------------------------- */
+	//map* tpath=getMapFromMaps(conf,"main","tmpPath");
+	char **papszDSCO=NULL;
+	poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+	if( poODS == NULL ){
+	  char emessage[1024];      
+	  sprintf( emessage,  "%s driver failed to create %s\n", 
+		   "json", pszDestDataSource );
+	  setMapInMaps(conf,"lenv","message",emessage);
+	  return SERVICE_FAILED;
+	}
+	
+	/* -------------------------------------------------------------------- */
+	/*      Create the layer.                                               */
+	/* -------------------------------------------------------------------- */
+	if( !poODS->TestCapability( ODsCCreateLayer ) )
+	  {
+	    char emessage[1024];
+	    sprintf( emessage, 
+		     "Layer %s not found, and CreateLayer not supported by driver.", 
+		     "Result" );
+	    setMapInMaps(conf,"lenv","message",emessage);
+	    return SERVICE_FAILED;
+	  }
+
+	poDstLayer = poODS->CreateLayer( "Result", NULL,wkbUnknown,NULL);
+	if( poDstLayer == NULL ){
+	  setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+	  return SERVICE_FAILED;
+	}
+	
+	OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
+	int iField;
+	int hasMmField=0;
+	
+	for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
+	  {
+	    OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iField);
+            if (iField >= 0)
+                poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) );
+            else
+            {
+                fprintf( stderr, "Field '%s' not found in source layer.\n", 
+                        iField );
+		return SERVICE_FAILED;
+            }
+	  }
+
+	while(TRUE){
+	  OGRFeature      *poDstFeature = NULL;
+	  poFeature = poLayer->GetNextFeature();
+	  if( poFeature == NULL )
+	    break;
+	  if(poFeature->GetGeometryRef() != NULL){
+	    poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
+	    if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    if(poDstFeature->SetGeometryDirectly(poDstFeature->GetGeometryRef()->Buffer(bufferDistance,30)) != OGRERR_NONE )
+	      {
+		char tmpMsg[1024];
+		sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			 poFeature->GetFID(), poFDefn->GetName() );
+		
+		OGRFeature::DestroyFeature( poFeature );
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poFeature );
+	    if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
+	      {		
+		OGRFeature::DestroyFeature( poDstFeature );
+		return SERVICE_FAILED;
+	      }
+	    OGRFeature::DestroyFeature( poDstFeature );
+	  }
+	}
+
+      }
+
+    delete poODS;
+    delete ipoDS;
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+
+}
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Boundary(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyOne(conf,inputs,outputs,&OGRGeometry::Boundary,"http://fooa/gml/3.1.0/polygon.xsd");
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int ConvexHull(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyOne(conf,inputs,outputs,&OGRGeometry::ConvexHull,"http://fooa/gml/3.1.0/polygon.xsd");
+  }
+
+
+  OGRDataSource* loadEntity(maps* conf,maps* inputs,char **filename,const char **oDriver,const char *entity,int iter){
+    map* tmp=getMapFromMaps(inputs,entity,"value");
+    map* tmp1=getMapFromMaps(inputs,entity,"mimeType");
+    *oDriver="GeoJSON";
+    sprintf(*filename,"/vsimem/input_%d.json",getpid()+iter);
+    if(tmp1!=NULL){
+      if(strcmp(tmp1->value,"text/xml")==0){
+	sprintf(*filename,"/vsimem/input_%d.xml",getpid()+iter);
+	*oDriver="GML";
+      }
+    }
+    VSILFILE *ifile=VSIFileFromMemBuffer(*filename,(GByte*)tmp->value,strlen(tmp->value),FALSE);
+    VSIFCloseL(ifile);
+    return OGRSFDriverRegistrar::Open(*filename,FALSE);    
+  }
+
+  int applyOneBool(maps*& conf,maps*& inputs,maps*& outputs,OGRBoolean (OGRGeometry::*myFunc)() const){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\n");
+#endif
+    OGRRegisterAll();
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    OGRLayer *poDstLayer;
+    const char *oDriver1;
+    OGRDataSource       *poODS;
+#ifdef DEBUG
+    dumpMaps(cursor);
+#endif
+    map* tmp=getMapFromMaps(inputs,"InputPolygon","value");
+    if(!tmp){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    char filename[1024];
+    map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    sprintf(filename,"/vsimem/input_%d.json",getpid());
+    if(tmp1!=NULL){
+      if(strcmp(tmp1->value,"text/xml")==0){
+	sprintf(filename,"/vsimem/input_%d.xml",getpid());
+	oDriver="GML";
+      }
+    }
+    VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmp->value,strlen(tmp->value),FALSE);
+    VSIFCloseL(ifile);
+    OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+    char pszDestDataSource[100];
+    if( ipoDS == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+	
+	if( poLayer == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+	
+	OGRFeature  *poFeature;
+
+
+	while(TRUE){
+	  OGRFeature      *poDstFeature = NULL;
+	  poFeature = poLayer->GetNextFeature();
+	  if( poFeature == NULL )
+	    break;
+	  if(poFeature->GetGeometryRef() != NULL){
+	    if((poFeature->GetGeometryRef()->*myFunc)()==0){
+	      setMapInMaps(outputs,"Result","value","false");
+	      OGRFeature::DestroyFeature( poFeature );
+	      delete ipoDS;
+	      return SERVICE_SUCCEEDED;
+	    }
+	  }
+	  OGRFeature::DestroyFeature( poFeature );
+	}
+
+      }
+
+    delete ipoDS;
+    setMapInMaps(outputs,"Result","value","true");
+
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int IsSimple(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyOneBool(conf,inputs,outputs,&OGRGeometry::IsSimple);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int IsClosed(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyOneBool(conf,inputs,outputs,&OGRGeometry::IsRing);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int IsValid(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyOneBool(conf,inputs,outputs,&OGRGeometry::IsValid);
+  }
+
+  
+  int applyTwo(maps*& conf,maps*& inputs,maps*& outputs,OGRGeometry* (OGRGeometry::*myFunc)(const OGRGeometry*) const){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\n");
+#endif
+    OGRRegisterAll();
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    OGRLayer *poDstLayer;
+    //const char *oDriver1;
+    OGRDataSource       *poODS;
+#ifdef DEBUG
+    dumpMaps(cursor);
+#endif
+
+    char *filename=(char*)malloc(1024*sizeof(char));
+    const char *oDriver1;
+    OGRDataSource* ipoDS1 = loadEntity(conf,inputs,&filename,&oDriver1,"InputEntity1",1);
+
+    char *filename1=(char*)malloc(1024*sizeof(char));
+    const char *oDriver2;
+    OGRDataSource* ipoDS2 = loadEntity(conf,inputs,&filename1,&oDriver2,"InputEntity2",2);
+    const char *oDriver3;
+    char pszDestDataSource[100];
+    if( ipoDS1 == NULL || ipoDS2 == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	if( ipoDS1 == NULL )
+	  sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	if( ipoDS2 == NULL )
+	  sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename1);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS1->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer1 = ipoDS1->GetLayer(iLayer);
+	
+	if( poLayer1 == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+
+	for( int iLayer1 = 0; iLayer1 < ipoDS2->GetLayerCount();
+	     iLayer1++ )
+	  {
+	    OGRLayer        *poLayer2 = ipoDS2->GetLayer(iLayer1);
+	    
+	    if( poLayer1 == NULL )
+	      {
+		fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+			 iLayer1 );
+		char tmp[1024];
+		sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer1);
+		setMapInMaps(conf,"lenv","message",tmp);
+		return SERVICE_FAILED;
+	      }
+	
+	    OGRFeature  *poFeature1,*poFeature2;
+
+	    /* -------------------------------------------------------------------- */
+	    /*      Try opening the output datasource as an existing, writable      */
+	    /* -------------------------------------------------------------------- */
+	    
+	    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+	    OGRSFDriver          *poDriver = NULL;
+	    int                  iDriver;
+	    
+	    map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+	    oDriver3="GeoJSON";
+	    sprintf(pszDestDataSource,"/vsimem/result_%d.json",getpid());
+	    if(tmpMap!=NULL){
+	      if(strcmp(tmpMap->value,"text/xml")==0){
+		sprintf(pszDestDataSource,"/vsimem/result_%d.xml",getpid());
+		oDriver3="GML";
+	      }
+	    }
+	    
+	    for( iDriver = 0;
+		 iDriver < poR->GetDriverCount() && poDriver == NULL;
+		 iDriver++ )
+	      {
+#ifdef DEBUG
+		fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
+#endif
+		if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver3) )
+		  {
+		    poDriver = poR->GetDriver(iDriver);
+		  }
+	      }
+	    
+	    if( poDriver == NULL )
+	      {
+		char emessage[8192];
+		sprintf( emessage, "Unable to find driver `%s'.\n", oDriver1 );
+		sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+		
+		for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+		  {
+		    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+		  }
+		
+		setMapInMaps(conf,"lenv","message",emessage);
+		return SERVICE_FAILED;
+		
+	      }
+	    
+	    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+	      char emessage[1024];
+	      sprintf( emessage,  "%s driver does not support data source creation.\n",
+		       "json" );
+	      setMapInMaps(conf,"lenv","message",emessage);
+	      return SERVICE_FAILED;
+	    }
+	    
+	    /* -------------------------------------------------------------------- */
+	    /*      Create the output data source.                                  */
+	    /* -------------------------------------------------------------------- */
+	    //map* tpath=getMapFromMaps(conf,"main","tmpPath");
+	    char **papszDSCO=NULL;
+	    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+	    if( poODS == NULL ){
+	      char emessage[1024];      
+	      sprintf( emessage,  "%s driver failed to create %s\n", 
+		       "json", pszDestDataSource );
+	      setMapInMaps(conf,"lenv","message",emessage);
+	      return SERVICE_FAILED;
+	    }
+	    
+	    /* -------------------------------------------------------------------- */
+	    /*      Create the layer.                                               */
+	    /* -------------------------------------------------------------------- */
+	    if( !poODS->TestCapability( ODsCCreateLayer ) )
+	      {
+		char emessage[1024];
+		sprintf( emessage, 
+			 "Layer %s not found, and CreateLayer not supported by driver.", 
+			 "Result" );
+		setMapInMaps(conf,"lenv","message",emessage);
+		return SERVICE_FAILED;
+	      }
+	    
+	    //CPLErrorReset();
+	    
+	    poDstLayer = poODS->CreateLayer( "Result", NULL,wkbUnknown,NULL);
+	    if( poDstLayer == NULL ){
+	      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+	      return SERVICE_FAILED;
+	    }
+	    
+	    OGRFeatureDefn *poFDefn = poLayer2->GetLayerDefn();
+	    int iField;
+	    int hasMmField=0;
+	    
+	    for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
+	      {
+		OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iField);
+		if (iField >= 0)
+		  poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) );
+		else
+		  {
+		    fprintf( stderr, "Field '%s' not found in source layer.\n", 
+			     iField );
+		    return SERVICE_FAILED;
+		  }
+	      }
+	    
+	    while(TRUE){
+	      OGRFeature      *poDstFeature = NULL;
+	      poFeature1 = poLayer1->GetNextFeature();
+	      if( poFeature1 == NULL )
+		break;
+	      while(TRUE){
+		poFeature2 = poLayer2->GetNextFeature();
+		if( poFeature2 == NULL )
+		  break;
+
+		if(poFeature1->GetGeometryRef() != NULL && poFeature2->GetGeometryRef() != NULL){
+		  poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
+		  if( poDstFeature->SetFrom( poFeature2, TRUE ) != OGRERR_NONE )
+		    {
+		      char tmpMsg[1024];
+		      sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			       poFeature2->GetFID(), poFDefn->GetName() );
+		      
+		      OGRFeature::DestroyFeature( poFeature1 );
+		      OGRFeature::DestroyFeature( poFeature2 );
+		      OGRFeature::DestroyFeature( poDstFeature );
+		      return SERVICE_FAILED;
+		    }
+		  if(poDstFeature->SetGeometryDirectly((poFeature1->GetGeometryRef()->*myFunc)(poFeature2->GetGeometryRef())) != OGRERR_NONE )
+		    {
+		      char tmpMsg[1024];
+		      sprintf( tmpMsg,"Unable to translate feature %ld from layer %s.\n",
+			       poFeature2->GetFID(), poFDefn->GetName() );
+		      
+		      OGRFeature::DestroyFeature( poFeature1 );
+		      OGRFeature::DestroyFeature( poFeature2 );
+		      OGRFeature::DestroyFeature( poDstFeature );
+		      return SERVICE_FAILED;
+		    }
+		  OGRFeature::DestroyFeature( poFeature2 );
+		  if(!poDstFeature->GetGeometryRef()->IsEmpty())
+		    if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
+		      {		
+			OGRFeature::DestroyFeature( poDstFeature );
+			return SERVICE_FAILED;
+		      }
+		  OGRFeature::DestroyFeature( poDstFeature );
+		}
+	      }
+	    }
+	    OGRFeature::DestroyFeature( poFeature1 );
+	  }
+      }
+
+    delete poODS;
+    delete ipoDS1;
+    delete ipoDS2;
+    free(filename);
+    free(filename1);
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+  
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Difference(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwo(conf,inputs,outputs,&OGRGeometry::Difference);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int SymDifference(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwo(conf,inputs,outputs,&OGRGeometry::SymDifference);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Intersection(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwo(conf,inputs,outputs,&OGRGeometry::Intersection);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Union(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwo(conf,inputs,outputs,&OGRGeometry::Union);
+  }
+
+  int applyTwoBool(maps*& conf,maps*& inputs,maps*& outputs,OGRBoolean (OGRGeometry::*myFunc)(const OGRGeometry*) const){
+    OGRRegisterAll();
+
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    OGRLayer *poDstLayer;
+    OGRDataSource       *poODS;
+
+    char *filename=(char*)malloc(1024*sizeof(char));
+    const char *oDriver1;
+    OGRDataSource* ipoDS1 = loadEntity(conf,inputs,&filename,&oDriver1,"InputEntity1",1);
+
+    char *filename1=(char*)malloc(1024*sizeof(char));
+    const char *oDriver2;
+    OGRDataSource* ipoDS2 = loadEntity(conf,inputs,&filename1,&oDriver2,"InputEntity2",2);
+    const char *oDriver3;
+    char pszDestDataSource[100];
+    if( ipoDS1 == NULL || ipoDS2 == NULL )
+      {
+	OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+	
+	fprintf( stderr, "FAILURE:\n"
+		 "Unable to open datasource `%s' with the following drivers.\n",
+		 filename );
+	
+	for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+	  }
+	char tmp[1024];
+	if( ipoDS1 == NULL )
+	  sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+	if( ipoDS2 == NULL )
+	  sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename1);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+      }
+    for( int iLayer = 0; iLayer < ipoDS1->GetLayerCount();
+	 iLayer++ )
+      {
+	OGRLayer        *poLayer1 = ipoDS1->GetLayer(iLayer);
+	
+	if( poLayer1 == NULL )
+	  {
+	    fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		     iLayer );
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+	  }
+
+	for( int iLayer1 = 0; iLayer1 < ipoDS2->GetLayerCount();
+	     iLayer1++ )
+	  {
+	    OGRLayer        *poLayer2 = ipoDS2->GetLayer(iLayer1);
+	    
+	    if( poLayer1 == NULL )
+	      {
+		fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+			 iLayer1 );
+		char tmp[1024];
+		sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer1);
+		setMapInMaps(conf,"lenv","message",tmp);
+		return SERVICE_FAILED;
+	      }
+	
+	    OGRFeature  *poFeature1,*poFeature2;
+
+
+	    while(TRUE){
+	      OGRFeature      *poDstFeature = NULL;
+	      poFeature1 = poLayer1->GetNextFeature();
+	      if( poFeature1 == NULL )
+		break;
+	      while(TRUE){
+		poFeature2 = poLayer2->GetNextFeature();
+		if( poFeature2 == NULL )
+		  break;
+		if(poFeature1->GetGeometryRef() != NULL && poFeature2->GetGeometryRef() != NULL){
+		  if((poFeature1->GetGeometryRef()->*myFunc)(poFeature2->GetGeometryRef())==0){
+		    setMapInMaps(outputs,"Result","value","false");
+		    OGRFeature::DestroyFeature( poFeature1 );
+		    OGRFeature::DestroyFeature( poFeature2 );
+		    delete ipoDS1;
+		    delete ipoDS2;
+		    free(filename);
+		    free(filename1);
+		    return SERVICE_SUCCEEDED;
+		  }
+		}
+		OGRFeature::DestroyFeature( poFeature2 );
+	      }
+	      OGRFeature::DestroyFeature( poFeature1 );
+	    }
+	  }
+      }
+
+    delete ipoDS1;
+    delete ipoDS2;
+    free(filename);
+    free(filename1);
+
+    setMapInMaps(outputs,"Result","value","true");
+
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Equals(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,(OGRBoolean (OGRGeometry::*)(const OGRGeometry *) const)&OGRGeometry::Equals);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Disjoint(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Disjoint);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Touches(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Touches);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Crosses(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Crosses);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Within(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Within);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Contains(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Contains);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Overlaps(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,&OGRGeometry::Overlaps);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Intersects(maps*& conf,maps*& inputs,maps*& outputs){
+    return applyTwoBool(conf,inputs,outputs,(OGRBoolean (OGRGeometry::*)(const OGRGeometry *) const)&OGRGeometry::Intersects);
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int Distance(maps*& conf,maps*& inputs,maps*& outputs){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print1\n");
+#endif
+    fflush(stderr);
+    maps* cursor=inputs;
+    OGRGeometryH geometry1,geometry2;
+    double res;
+    {
+      map* tmp=getMapFromMaps(inputs,"InputEntity1","value");
+      map* tmp1=getMapFromMaps(inputs,"InputEntity1","mimeType");
+#ifdef DEBUG
+      fprintf(stderr,"MY MAP\n");
+      dumpMap(tmp1);
+      dumpMaps(inputs);
+      fprintf(stderr,"MY MAP\n");
+#endif
+      if(tmp1!=NULL){
+        if(strncmp(tmp1->value,"application/json",16)==0)
+      	  geometry1=OGR_G_CreateGeometryFromJson(tmp->value);
+	else
+	  geometry1=createGeometryFromGML(conf,tmp->value);
+      }
+      else
+      	geometry1=createGeometryFromGML(conf,tmp->value);
+    }
+    if(geometry1==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity1."));
+      fprintf(stderr,"SERVICE FAILED !\n");
+      return SERVICE_FAILED;
+    }
+    {
+      map* tmp=getMapFromMaps(inputs,"InputEntity2","value");
+      map* tmp1=getMapFromMaps(inputs,"InputEntity2","mimeType");
+#ifdef DEBUG
+      fprintf(stderr,"MY MAP\n");
+      dumpMap(tmp1);
+      dumpMaps(inputs);
+      fprintf(stderr,"MY MAP\n");
+#endif
+      if(tmp1!=NULL){
+        if(strncmp(tmp1->value,"application/json",16)==0)
+      	  geometry2=OGR_G_CreateGeometryFromJson(tmp->value);
+	else
+	  geometry2=createGeometryFromGML(conf,tmp->value);
+      }
+      else
+      	geometry2=createGeometryFromGML(conf,tmp->value);
+    }
+    if(geometry2==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity2."));
+      fprintf(stderr,"SERVICE FAILED !\n");
+      return SERVICE_FAILED;
+    }
+    res=OGR_G_Distance(geometry1,geometry2);    
+    char tmpres[100];
+    sprintf(tmpres,"%f",res);
+    setMapInMaps(outputs,"Distance","value",tmpres);
+    setMapInMaps(outputs,"Distance","dataType","float");
+#ifdef DEBUG
+    dumpMaps(outputs);
+    fprintf(stderr,"\nService internal print\n===\n");
+#endif
+    return SERVICE_SUCCEEDED;
+  }
+
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int GetArea(maps*& conf,maps*& inputs,maps*& outputs){
+    fprintf(stderr,"GETAREA \n");
+    double res;
+    /**
+     * Extract Geometry from the InputPolygon value
+     */
+    OGRGeometryH geometry;
+    map* tmp=getMapFromMaps(inputs,"InputPolygon","value");
+    if(tmp==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    fprintf(stderr,"geometry creation %s \n",tmp->value);
+    geometry=createGeometryFromGML(conf,tmp->value);
+    if(geometry==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry from InputPolygon"));
+      return SERVICE_FAILED;
+    }
+    fprintf(stderr,"geometry created %s \n",tmp->value);
+    res=OGR_G_Area(geometry);
+    fprintf(stderr,"area %d \n",res);
+    /**
+     * Filling the outputs
+     */
+    char tmp1[100];
+    sprintf(tmp1,"%f",res);
+    setMapInMaps(outputs,"Area","value",tmp1);
+    setMapInMaps(outputs,"Area","dataType","float");
+#ifdef DEBUG
+    dumpMaps(outputs);
+#endif
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/Makefile	(revision 672)
@@ -0,0 +1,14 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=-DZOO_SERVICE ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/ogr2ogr_service.zo: service.c $(DEP_LIBS)
+	g++ $(CFLAGS) $(CPPFLAGS) -shared -fpic $<  -o $@ ${GDAL_LIBS} -lzoo_service
+
+install:
+	install -d ${CGI_DIR}/ogr/ogr2ogr
+	install cgi-env/* ${CGI_DIR}/ogr/ogr2ogr
+
+clean:
+	rm -f cgi-env/*zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/cgi-env/Ogr2Ogr.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/cgi-env/Ogr2Ogr.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/cgi-env/Ogr2Ogr.zcfg	(revision 672)
@@ -0,0 +1,62 @@
+[Ogr2Ogr]
+ Title = Converts vector data from one format to another. 
+ Abstract = http://www.gdal.org/ogr2ogr.html
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = C
+ serviceProvider = ogr2ogr_service.zo
+ <MetaData>
+   title = My Demo
+ </MetaData>
+ <DataInputs>
+  [F]
+   Title = Format of the output data
+   Abstract = Select the output format.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+     value = ESRI ShapeFile
+    </Default>
+    <Supported>
+    </Supported>
+   </LiteralData>
+  [InputDSN]
+   Title = The input data source name
+   Abstract = The input data source name to use as source for convertion.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+    <Supported>
+    </Supported>
+   </LiteralData>
+  [OutputDSN]
+   Title = The output data source name
+   Abstract = The output data name.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+    <Supported>
+    </Supported>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [OutputedDataSourceName]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+    <Supported>
+    </Supported>
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/makefile.vc	(revision 672)
@@ -0,0 +1,11 @@
+GEODIR=c:/OSGeo4W/
+TOOLS=c:/Users/djay/GeoLabs/tools/
+CFLAGS=-I$(GEODIR)/include -I$(TOOLS)/include -I../../../zoo-kernel/ -I./ -DGDAL_1_5_0 -DZOO_SERVICE -DLINUX_FREE_ISSUE -DDEBUG
+CPP=cl /TP 
+
+cgi-env/ogr2ogr_service.zo: service.c
+	$(CPP) $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/ogr2ogr_service.zo ../../../zoo-kernel/service_internal.obj ./service.obj -L$(TOOLS)/lib/libssl32.dll.a $(GEODIR)/lib/libxml2.lib $(GEODIR)/lib/gdal_i.lib $(TOOLS)/lib/libeay32.dll.a $(TOOLS)/lib/libcrypto.a $(TOOLS)/lib/libssl32.dll.a 
+
+clean:
+	rm -f cgi-env/ogr_service.zso
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/ogr/ogr2ogr/service.c	(revision 672)
@@ -0,0 +1,1303 @@
+/******************************************************************************
+ * $Id: ogr2ogr.cpp 15473 2008-10-07 20:59:24Z warmerdam $
+ *
+ * Project:  OpenGIS Simple Features Reference Implementation
+ * Purpose:  Simple client for translating between formats.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "ogrsf_frmts.h"
+#include "ogr_p.h"
+#include "cpl_conv.h"
+#include "cpl_string.h"
+#include "ogr_api.h"
+#ifdef ZOO_SERVICE
+#include "service.h"
+#endif
+
+CPL_CVSID("$Id: ogr2ogr.cpp 15473 2008-10-07 20:59:24Z warmerdam $");
+
+#ifdef WIN32
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp 
+#endif
+
+#ifdef ZOO_SERVICE
+extern "C" {
+#endif
+
+static void Usage();
+
+static int TranslateLayer( OGRDataSource *poSrcDS, 
+                           OGRLayer * poSrcLayer,
+                           OGRDataSource *poDstDS,
+                           char ** papszLSCO,
+                           const char *pszNewLayerName,
+                           int bTransform, 
+                           OGRSpatialReference *poOutputSRS,
+                           OGRSpatialReference *poSourceSRS,
+                           char **papszSelFields,
+                           int bAppend, int eGType,
+                           int bOverwrite,
+                           double dfMaxSegmentLength);
+
+static int bSkipFailures = FALSE;
+static int nGroupTransactions = 200;
+static int bPreserveFID = TRUE;
+static int nFIDToFetch = OGRNullFID;
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+
+#ifdef ZOO_SERVICE
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+int Ogr2Ogr(maps*& conf,maps*& inputs,maps*& outputs)
+#else
+int main( int nArgc, char ** papszArgv )
+#endif
+{
+    const char  *pszFormat = "ESRI Shapefile";
+    const char  *pszDataSource = NULL;
+    const char  *pszDestDataSource = NULL;
+    const char  *pszwebDestData = NULL;
+    char        **papszLayers = NULL;
+    char        **papszDSCO = NULL, **papszLCO = NULL;
+    int         bTransform = FALSE;
+    int         bAppend = FALSE, bUpdate = FALSE, bOverwrite = FALSE;
+    const char  *pszOutputSRSDef = NULL;
+    const char  *pszSourceSRSDef = NULL;
+    OGRSpatialReference *poOutputSRS = NULL;
+    OGRSpatialReference *poSourceSRS = NULL;
+    const char  *pszNewLayerName = NULL;
+    const char  *pszWHERE = NULL;
+    OGRGeometry *poSpatialFilter = NULL;
+    const char  *pszSelect;
+    char        **papszSelFields = NULL;
+    const char  *pszSQLStatement = NULL;
+    int         eGType = -2;
+    double      dfMaxSegmentLength = 0;
+
+#ifdef ZOO_SERVICE
+    dumpMaps(inputs);
+#endif
+    /* Check strict compilation and runtime library version as we use C++ API */
+    if (! GDAL_CHECK_VERSION("ogr2ogr"))
+#ifdef ZOO_SERVICE
+	{
+		fprintf(stderr,"Not correct version of the gdal library\n");
+		setMapInMaps(conf,"lenv","message","Unable to check gdal version for ogr2ogr_service.zo");
+		return SERVICE_FAILED;
+	}
+#else
+        exit(1);
+#endif
+/* -------------------------------------------------------------------- */
+/*      Register format(s).                                             */
+/* -------------------------------------------------------------------- */
+    OGRRegisterAll();
+
+#ifdef ZOO_SERVICE
+    map *tmpMap=NULL;
+    char dataPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","dataPath");
+    if(tmpMap!=NULL)
+      sprintf(dataPath,"%s",tmpMap->value);
+    tmpMap=NULL;
+    char tempPath[1024];
+    tmpMap=getMapFromMaps(conf,"main","tmpPath");
+    if(tmpMap!=NULL){
+      sprintf(tempPath,"%s",tmpMap->value);
+    }
+    
+    tmpMap=NULL;
+    char serverAddress[1024];
+    tmpMap=getMapFromMaps(conf,"main","serverAddress");
+    if(tmpMap!=NULL){
+      sprintf(serverAddress,"%s",tmpMap->value);
+    }
+    
+    tmpMap=NULL;
+    char tmpurl[1024];
+    tmpMap=getMapFromMaps(conf,"main","tmpurl");
+    if(tmpMap!=NULL){
+      sprintf(tmpurl,"%s",tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"F","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      pszFormat=tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"DSCO","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  papszDSCO = CSLAddString(papszDSCO, tmpMap->value );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"LCO","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  papszLCO = CSLAddString(papszLCO, tmpMap->value );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"preserve_fid","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  bPreserveFID = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"skipfailure","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      bSkipFailures = TRUE;
+      nGroupTransactions = 1; /* #2409 */
+    }
+
+    /* if exist, overwrite the data with the same name */
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"overwrite","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      bOverwrite = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"append","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0){
+      bAppend = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"update","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"TRUE",4)==0){
+      bUpdate = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"fid","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      nFIDToFetch = atoi(tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"sql","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      pszSQLStatement = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"nln","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  pszNewLayerName = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"nlt","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  pszNewLayerName = tmpMap->value;
+	  if( EQUAL(tmpMap->value,"NONE") )
+		  eGType = wkbNone;
+	  else if( EQUAL(tmpMap->value,"GEOMETRY") )
+		  eGType = wkbUnknown;
+	  else if( EQUAL(tmpMap->value,"POINT") )
+		  eGType = wkbPoint;
+	  else if( EQUAL(tmpMap->value,"LINESTRING") )
+		  eGType = wkbLineString;
+	  else if( EQUAL(tmpMap->value,"POLYGON") )
+		  eGType = wkbPolygon;
+	  else if( EQUAL(tmpMap->value,"GEOMETRYCOLLECTION") )
+		  eGType = wkbGeometryCollection;
+	  else if( EQUAL(tmpMap->value,"MULTIPOINT") )
+		  eGType = wkbMultiPoint;
+	  else if( EQUAL(tmpMap->value,"MULTILINESTRING") )
+		  eGType = wkbMultiLineString;
+	  else if( EQUAL(tmpMap->value,"MULTIPOLYGON") )
+		  eGType = wkbMultiPolygon;
+	  else if( EQUAL(tmpMap->value,"GEOMETRY25D") )
+		  eGType = wkbUnknown | wkb25DBit;
+	  else if( EQUAL(tmpMap->value,"POINT25D") )
+		  eGType = wkbPoint25D;
+	  else if( EQUAL(tmpMap->value,"LINESTRING25D") )
+		  eGType = wkbLineString25D;
+	  else if( EQUAL(tmpMap->value,"POLYGON25D") )
+		  eGType = wkbPolygon25D;
+	  else if( EQUAL(tmpMap->value,"GEOMETRYCOLLECTION25D") )
+		  eGType = wkbGeometryCollection25D;
+	  else if( EQUAL(tmpMap->value,"MULTIPOINT25D") )
+		  eGType = wkbMultiPoint25D;
+	  else if( EQUAL(tmpMap->value,"MULTILINESTRING25D") )
+		  eGType = wkbMultiLineString25D;
+	  else if( EQUAL(tmpMap->value,"MULTIPOLYGON25D") )
+		  eGType = wkbMultiPolygon25D;
+	  else	  
+	  {
+		  fprintf( stderr, "-nlt %s: type not recognised.\n", 
+			  tmpMap->value );
+		  exit( 1 );
+	  }
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"tg","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  nGroupTransactions = atoi(tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"s_srs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      pszSourceSRSDef = strdup(tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"a_srs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      pszOutputSRSDef = strdup(tmpMap->value);
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"t_srs","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      pszOutputSRSDef = strdup(tmpMap->value);
+      bTransform = TRUE;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"SPAT","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      char *tmp=tmpMap->value;
+      char *t=strtok(tmp,",");
+      int cnt=0;
+      double dfULX, dfULY, dfLRX, dfLRY;
+      while(t!=NULL){
+        switch(cnt){
+        case 0:
+          dfULX = atof(t);
+          break;
+        case 1:
+          dfULY = atof(t);
+          break;
+        case 2:
+          dfLRX = atof(t);
+          break;
+        case 3:
+          dfLRY = atof(t);
+          break;
+        }
+        fprintf(stderr,"%s\n\n",t);
+        fprintf(stderr,"%f - %f - %f - %f\n\n",dfULX,dfULY,dfLRX,dfLRY);
+        t=strtok(NULL,",");
+        cnt++;
+      }
+
+      OGRLinearRing  oRing;
+      
+      oRing.addPoint( dfULX, dfULY );
+      oRing.addPoint( dfULX, dfLRY );
+      oRing.addPoint( dfLRX, dfLRY );
+      oRing.addPoint( dfLRX, dfULY );
+      oRing.addPoint( dfULX, dfULY );
+      poSpatialFilter = new OGRPolygon();
+      ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"where","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  pszWHERE = tmpMap->value;
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"select","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  pszSelect = tmpMap->value;
+	  papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,", 
+		  FALSE, FALSE );
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"segmentize","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+	  dfMaxSegmentLength = atof(tmpMap->value);
+    }
+
+    /*tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"segmentize","value");
+    if(tmpMap!=NULL){
+	  dfMaxSegmentLength = atof(tmpMap->value);
+    }*/
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"InputDSN","value");
+    if(tmpMap!=NULL && strncasecmp(tmpMap->value,"NULL",4)!=0){
+      if(strncasecmp(tmpMap->value,"PG",2)!=0 &&
+	 strncasecmp(tmpMap->value,"My",2)!=0 &&
+	 strncasecmp(tmpMap->value,"OCI",3)!=0 ){
+	if(strncasecmp(dataPath,tmpMap->value,strlen(dataPath))==0 ||
+	   strncasecmp(tempPath,tmpMap->value,strlen(tempPath))==0){
+	  pszDataSource=strdup(tmpMap->value);
+	}else{
+	  pszDataSource=(char*)malloc(sizeof(char)*(strlen(dataPath)+strlen(tmpMap->value)+2));
+	  sprintf((char*)pszDataSource,"%s/%s",dataPath,tmpMap->value);
+	}
+      }else{
+	pszDataSource=(char*)malloc(sizeof(char)*(strlen(tmpMap->value)+1));
+	sprintf((char*)pszDataSource,"%s",tmpMap->value);	
+      }
+    }
+
+    tmpMap=NULL;
+    tmpMap=getMapFromMaps(inputs,"OutputDSN","value");
+    if(tmpMap!=NULL){
+      if(strncasecmp(tmpMap->value,"PG",2)!=0 &&
+	 strncasecmp(tmpMap->value,"MY",2)!=0 &&
+	 strncasecmp(tmpMap->value,"OCI",3)!=0){
+	pszDestDataSource=(char*)malloc(sizeof(char)*(strlen(tempPath)+strlen(tmpMap->value)+4));
+	sprintf((char*)pszDestDataSource,"%s/%s",tempPath,tmpMap->value/*,ext*/);
+	pszwebDestData=(char*)malloc(sizeof(char)*(strlen(serverAddress)+strlen(tmpurl)+strlen(tmpMap->value)+4));
+	sprintf((char*)pszwebDestData,"%s%s/%s",serverAddress,tmpurl,tmpMap->value/*,ext*/);
+      }
+      else{
+	pszDestDataSource=(char*)malloc(sizeof(char)*(strlen(tmpMap->value)+1));
+	sprintf((char*)pszDestDataSource,"%s",tmpMap->value/*,ext*/);
+	pszwebDestData=(char*)malloc(sizeof(char)*(strlen(serverAddress)+strlen(tmpurl)+strlen(tmpMap->value)+4));
+	sprintf((char*)pszwebDestData,"%s%s/%s",serverAddress,tmpurl,tmpMap->value/*,ext*/);
+      }
+    }
+
+    fprintf(stderr,"Message %s\n",pszDestDataSource);
+#else
+/* -------------------------------------------------------------------- */
+/*      Processing command line arguments.                              */
+/* -------------------------------------------------------------------- */
+    nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
+    
+    if( nArgc < 1 )
+        exit( -nArgc );
+
+    for( int iArg = 1; iArg < nArgc; iArg++ )
+    {
+        if( EQUAL(papszArgv[iArg], "--utility_version") )
+        {
+				printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
+                   papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
+            return 0;
+        }
+        else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 )
+        {
+            pszFormat = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-dsco") && iArg < nArgc-1 )
+        {
+            papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg] );
+        }
+        else if( EQUAL(papszArgv[iArg],"-lco") && iArg < nArgc-1 )
+        {
+            papszLCO = CSLAddString(papszLCO, papszArgv[++iArg] );
+        }
+        else if( EQUAL(papszArgv[iArg],"-preserve_fid") )
+        {
+            bPreserveFID = TRUE;
+        }
+        else if( EQUALN(papszArgv[iArg],"-skip",5) )
+        {
+            bSkipFailures = TRUE;
+            nGroupTransactions = 1; /* #2409 */
+        }
+        else if( EQUAL(papszArgv[iArg],"-append") )
+        {
+            bAppend = TRUE;
+        }
+        else if( EQUAL(papszArgv[iArg],"-overwrite") )
+        {
+            bOverwrite = TRUE;
+        }
+        else if( EQUAL(papszArgv[iArg],"-update") )
+        {
+            bUpdate = TRUE;
+        }
+        else if( EQUAL(papszArgv[iArg],"-fid") && papszArgv[iArg+1] != NULL )
+        {
+            nFIDToFetch = atoi(papszArgv[++iArg]);
+        }
+        else if( EQUAL(papszArgv[iArg],"-sql") && papszArgv[iArg+1] != NULL )
+        {
+            pszSQLStatement = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-nln") && iArg < nArgc-1 )
+        {
+            pszNewLayerName = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-nlt") && iArg < nArgc-1 )
+        {
+            if( EQUAL(papszArgv[iArg+1],"NONE") )
+                eGType = wkbNone;
+            else if( EQUAL(papszArgv[iArg+1],"GEOMETRY") )
+                eGType = wkbUnknown;
+            else if( EQUAL(papszArgv[iArg+1],"POINT") )
+                eGType = wkbPoint;
+            else if( EQUAL(papszArgv[iArg+1],"LINESTRING") )
+                eGType = wkbLineString;
+            else if( EQUAL(papszArgv[iArg+1],"POLYGON") )
+                eGType = wkbPolygon;
+            else if( EQUAL(papszArgv[iArg+1],"GEOMETRYCOLLECTION") )
+                eGType = wkbGeometryCollection;
+            else if( EQUAL(papszArgv[iArg+1],"MULTIPOINT") )
+                eGType = wkbMultiPoint;
+            else if( EQUAL(papszArgv[iArg+1],"MULTILINESTRING") )
+                eGType = wkbMultiLineString;
+            else if( EQUAL(papszArgv[iArg+1],"MULTIPOLYGON") )
+                eGType = wkbMultiPolygon;
+            else if( EQUAL(papszArgv[iArg+1],"GEOMETRY25D") )
+                eGType = wkbUnknown | wkb25DBit;
+            else if( EQUAL(papszArgv[iArg+1],"POINT25D") )
+                eGType = wkbPoint25D;
+            else if( EQUAL(papszArgv[iArg+1],"LINESTRING25D") )
+                eGType = wkbLineString25D;
+            else if( EQUAL(papszArgv[iArg+1],"POLYGON25D") )
+                eGType = wkbPolygon25D;
+            else if( EQUAL(papszArgv[iArg+1],"GEOMETRYCOLLECTION25D") )
+                eGType = wkbGeometryCollection25D;
+            else if( EQUAL(papszArgv[iArg+1],"MULTIPOINT25D") )
+                eGType = wkbMultiPoint25D;
+            else if( EQUAL(papszArgv[iArg+1],"MULTILINESTRING25D") )
+                eGType = wkbMultiLineString25D;
+            else if( EQUAL(papszArgv[iArg+1],"MULTIPOLYGON25D") )
+                eGType = wkbMultiPolygon25D;
+            else
+            {
+                fprintf( stderr, "-nlt %s: type not recognised.\n", 
+                         papszArgv[iArg+1] );
+                exit( 1 );
+            }
+            iArg++;
+        }
+        else if( (EQUAL(papszArgv[iArg],"-tg") ||
+                  EQUAL(papszArgv[iArg],"-gt")) && iArg < nArgc-1 )
+        {
+            nGroupTransactions = atoi(papszArgv[++iArg]);
+        }
+        else if( EQUAL(papszArgv[iArg],"-s_srs") && iArg < nArgc-1 )
+        {
+            pszSourceSRSDef = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-a_srs") && iArg < nArgc-1 )
+        {
+            pszOutputSRSDef = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-t_srs") && iArg < nArgc-1 )
+        {
+            pszOutputSRSDef = papszArgv[++iArg];
+            bTransform = TRUE;
+        }
+        else if( EQUAL(papszArgv[iArg],"-spat") 
+                 && papszArgv[iArg+1] != NULL 
+                 && papszArgv[iArg+2] != NULL 
+                 && papszArgv[iArg+3] != NULL 
+                 && papszArgv[iArg+4] != NULL )
+        {
+            OGRLinearRing  oRing;
+
+            oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
+            oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
+            oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
+            oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
+            oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
+
+            poSpatialFilter = new OGRPolygon();
+            ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
+            iArg += 4;
+        }
+        else if( EQUAL(papszArgv[iArg],"-where") && papszArgv[iArg+1] != NULL )
+        {
+            pszWHERE = papszArgv[++iArg];
+        }
+        else if( EQUAL(papszArgv[iArg],"-select") && papszArgv[iArg+1] != NULL)
+        {
+            pszSelect = papszArgv[++iArg];
+            papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,", 
+                                                      FALSE, FALSE );
+        }
+        else if( EQUAL(papszArgv[iArg],"-segmentize") && iArg < nArgc-1 )
+        {
+            dfMaxSegmentLength = atof(papszArgv[++iArg]);
+        }
+        else if( papszArgv[iArg][0] == '-' )
+        {
+            Usage();
+        }
+        else if( pszDestDataSource == NULL )
+            pszDestDataSource = papszArgv[iArg];
+        else if( pszDataSource == NULL )
+            pszDataSource = papszArgv[iArg];
+        else
+            papszLayers = CSLAddString( papszLayers, papszArgv[iArg] );
+    }
+#endif
+
+    if( pszDataSource == NULL )
+#ifdef ZOO_SERVICE
+	{
+#else
+	  Usage();
+#endif
+#ifdef ZOO_SERVICE
+	  setMapInMaps(conf,"lenv","message","Wrong parameter");
+	  return SERVICE_FAILED;
+	}
+#endif
+
+/* -------------------------------------------------------------------- */
+/*      Open data source.                                               */
+/* -------------------------------------------------------------------- */
+    OGRDataSource       *poDS;
+        
+    poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
+
+/* -------------------------------------------------------------------- */
+/*      Report failure                                                  */
+/* -------------------------------------------------------------------- */
+    if( poDS == NULL )
+    {
+        OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+        
+        fprintf( stderr, "FAILURE:\n"
+                "Unable to open datasource `%s' with the following drivers.\n",
+                pszDataSource );
+
+        for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+        {
+            fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+        }
+#ifdef ZOO_SERVICE
+	char tmp[1024];
+	sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",pszDataSource);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return SERVICE_FAILED;
+#else
+        exit( 1 );
+#endif
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Try opening the output datasource as an existing, writable      */
+/* -------------------------------------------------------------------- */
+    OGRDataSource       *poODS;
+    
+    if( bUpdate )
+    {
+        poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, TRUE );
+        if( poODS == NULL )
+        {
+            fprintf( stderr, "FAILURE:\n"
+                    "Unable to open existing output datasource `%s'.\n",
+                    pszDestDataSource );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"Unable to open existing output datasource `%s'.",pszDestDataSource);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+        exit( 1 );
+#endif
+        }
+
+        if( CSLCount(papszDSCO) > 0 )
+        {
+            fprintf( stderr, "WARNING: Datasource creation options ignored since an existing datasource\n"
+                    "         being updated.\n" );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Find the output driver.                                         */
+/* -------------------------------------------------------------------- */
+    else
+    {
+        OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+        OGRSFDriver          *poDriver = NULL;
+        int                  iDriver;
+
+        for( iDriver = 0;
+             iDriver < poR->GetDriverCount() && poDriver == NULL;
+             iDriver++ )
+        {
+            if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) )
+            {
+                poDriver = poR->GetDriver(iDriver);
+            }
+        }
+
+        if( poDriver == NULL )
+        {
+            fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
+            fprintf( stderr,  "The following drivers are available:\n" );
+        
+            for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+            {
+                fprintf( stderr,  "  -> `%s'\n", poR->GetDriver(iDriver)->GetName() );
+            }
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"Unable to find driver `%s'.",pszFormat);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+
+        if( !poDriver->TestCapability( ODrCCreateDataSource ) )
+        {
+            fprintf( stderr,  "%s driver does not support data source creation.\n",
+                    pszFormat );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"%s driver does not support data source creation.",pszFormat);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Create the output data source.                                  */
+/* -------------------------------------------------------------------- */
+        poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+        if( poODS == NULL )
+        {
+            fprintf( stderr,  "%s driver failed to create %s\n", 
+                    pszFormat, pszDestDataSource );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"%s driver failed to create %s",pszFormat, pszDestDataSource);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse the output SRS definition if possible.                    */
+/* -------------------------------------------------------------------- */
+    if( pszOutputSRSDef != NULL )
+    {
+        poOutputSRS = new OGRSpatialReference();
+        if( poOutputSRS->SetFromUserInput( pszOutputSRSDef ) != OGRERR_NONE )
+        {
+            fprintf( stderr,  "Failed to process SRS definition: %s\n", 
+                    pszOutputSRSDef );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"Failed to process SRS definition: %s",pszOutputSRSDef);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse the source SRS definition if possible.                    */
+/* -------------------------------------------------------------------- */
+    if( pszSourceSRSDef != NULL )
+    {
+        poSourceSRS = new OGRSpatialReference();
+        if( poSourceSRS->SetFromUserInput( pszSourceSRSDef ) != OGRERR_NONE )
+        {
+            fprintf( stderr,  "Failed to process SRS definition: %s\n", 
+                    pszSourceSRSDef );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"Failed to process SRS definition: %s",pszOutputSRSDef);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Special case for -sql clause.  No source layers required.       */
+/* -------------------------------------------------------------------- */
+    if( pszSQLStatement != NULL )
+    {
+        OGRLayer *poResultSet;
+
+        if( pszWHERE != NULL )
+            fprintf( stderr,  "-where clause ignored in combination with -sql.\n" );
+        if( CSLCount(papszLayers) > 0 )
+	  fprintf( stderr,  "layer names ignored in combination with -sql. (%s)\n", pszSQLStatement);
+        
+        poResultSet = poDS->ExecuteSQL( pszSQLStatement, poSpatialFilter, 
+                                        NULL );
+
+        if( poResultSet != NULL )
+        {
+            if( !TranslateLayer( poDS, poResultSet, poODS, papszLCO, 
+                                 pszNewLayerName, bTransform, poOutputSRS,
+                                 poSourceSRS, papszSelFields, bAppend, eGType,
+                                 bOverwrite, dfMaxSegmentLength ))
+            {
+                CPLError( CE_Failure, CPLE_AppDefined, 
+                          "Terminating translation prematurely after failed\n"
+                          "translation from sql statement." );
+
+                exit( 1 );
+            }
+            poDS->ReleaseResultSet( poResultSet );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Process each data source layer.                                 */
+/* -------------------------------------------------------------------- */
+    for( int iLayer = 0; 
+         pszSQLStatement == NULL && iLayer < poDS->GetLayerCount(); 
+         iLayer++ )
+    {
+        OGRLayer        *poLayer = poDS->GetLayer(iLayer);
+
+        if( poLayer == NULL )
+        {
+            fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+                    iLayer );
+#ifdef ZOO_SERVICE
+	    char tmp[1024];
+	    sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	    setMapInMaps(conf,"lenv","message",tmp);
+	    return SERVICE_FAILED;
+#else
+	    exit( 1 );
+#endif
+        }
+
+        if( CSLCount(papszLayers) == 0
+            || CSLFindString( papszLayers,
+                              poLayer->GetLayerDefn()->GetName() ) != -1 )
+        {
+            if( pszWHERE != NULL )
+                poLayer->SetAttributeFilter( pszWHERE );
+            
+            if( poSpatialFilter != NULL )
+                poLayer->SetSpatialFilter( poSpatialFilter );
+            
+            if( !TranslateLayer( poDS, poLayer, poODS, papszLCO, 
+                                 pszNewLayerName, bTransform, poOutputSRS,
+                                 poSourceSRS, papszSelFields, bAppend, eGType,
+                                 bOverwrite, dfMaxSegmentLength ) 
+                && !bSkipFailures )
+            {
+#ifdef ZOO_SERVICE
+		char tmp[1024];
+		sprintf(tmp,"Terminating translation prematurely after failed of layer %s",poLayer->GetLayerDefn()->GetName() );
+		setMapInMaps(conf,"lenv","message",tmp);
+		return SERVICE_FAILED;
+#else
+                CPLError( CE_Failure, CPLE_AppDefined, 
+                          "Terminating translation prematurely after failed\n"
+                          "translation of layer %s (use -skipfailures to skip errors)\n", 
+                          poLayer->GetLayerDefn()->GetName() );
+
+                exit( 1 );
+#endif
+            }
+        }
+    }
+
+#ifdef ZOO_SERVICE
+    outputs->content=createMap("value",(char*)pszwebDestData);
+#endif
+
+/* -------------------------------------------------------------------- */
+/*      Close down.                                                     */
+/* -------------------------------------------------------------------- */
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    delete poOutputSRS;
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    delete poSourceSRS;
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    delete poODS;
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    delete poDS;
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+
+#ifndef ZOO_SERVICE
+    CSLDestroy(papszSelFields);
+    CSLDestroy( papszArgv );
+#endif
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    CSLDestroy( papszLayers );
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+#ifndef ZOO_SERVICE
+    CSLDestroy( papszDSCO );
+    CSLDestroy( papszLCO );
+#endif
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+
+    OGRCleanupAll();
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+
+#ifdef DBMALLOC
+    malloc_dump(1);
+#endif
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    
+#ifdef ZOO_SERVICE
+    return SERVICE_SUCCEEDED;
+#else
+    return 0;
+#endif
+}
+
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage()
+
+{
+    OGRSFDriverRegistrar        *poR = OGRSFDriverRegistrar::GetRegistrar();
+
+#ifdef ZOO_SERVICE
+	fprintf(stderr,
+#else
+	printf(
+#endif
+		"Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update] [-gt n]\n"
+		"               [-select field_list] [-where restricted_where] \n"
+		"               [-sql <sql statement>] \n" 
+		"               [-spat xmin ymin xmax ymax] [-preserve_fid] [-fid FID]\n"
+		"               [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n"
+		"               [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n"
+		"               [-segmentize max_dist]\n"
+		"               dst_datasource_name src_datasource_name\n"
+		"               [-lco NAME=VALUE] [-nln name] [-nlt type] [layer [layer ...]]\n"
+		"\n"
+		" -f format_name: output file format name, possible values are:\n");
+    
+    for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+    {
+        OGRSFDriver *poDriver = poR->GetDriver(iDriver);
+
+        if( poDriver->TestCapability( ODrCCreateDataSource ) )
+            printf( "     -f \"%s\"\n", poDriver->GetName() );
+    }
+
+#ifdef ZOO_SERVICE
+	fprintf(stderr,
+#else
+	printf(
+#endif
+		" -append: Append to existing layer instead of creating new if it exists\n"
+		" -overwrite: delete the output layer and recreate it empty\n"
+		" -update: Open existing output datasource in update mode\n"
+		" -select field_list: Comma-delimited list of fields from input layer to\n"
+		"                     copy to the new layer (defaults to all)\n" 
+		" -where restricted_where: Attribute query (like SQL WHERE)\n" 
+		" -sql statement: Execute given SQL statement and save result.\n"
+		" -skipfailures: skip features or layers that fail to convert\n"
+		" -gt n: group n features per transaction (default 200)\n"
+		" -spat xmin ymin xmax ymax: spatial query extents\n"
+		" -segmentize max_dist: maximum distance between 2 nodes.\n"
+		"                       Used to create intermediate points\n"
+		" -dsco NAME=VALUE: Dataset creation option (format specific)\n"
+		" -lco  NAME=VALUE: Layer creation option (format specific)\n"
+		" -nln name: Assign an alternate name to the new layer\n"
+		" -nlt type: Force a geometry type for new layer.  One of NONE, GEOMETRY,\n"
+		"      POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n"
+		"      MULTIPOLYGON, or MULTILINESTRING.  Add \"25D\" for 3D layers.\n"
+		"      Default is type of source layer.\n" );
+
+#ifdef ZOO_SERVICE
+	fprintf(stderr,
+#else
+	printf(
+#endif
+		" -a_srs srs_def: Assign an output SRS\n"
+		" -t_srs srs_def: Reproject/transform to this SRS on output\n"
+		" -s_srs srs_def: Override source SRS\n"
+		"\n" 
+		" Srs_def can be a full WKT definition (hard to escape properly),\n"
+		" or a well known definition (ie. EPSG:4326) or a file with a WKT\n"
+		" definition.\n" );
+
+
+#ifndef ZOO_SERVICE
+	exit( 1 );
+#endif
+}
+
+/************************************************************************/
+/*                           TranslateLayer()                           */
+/************************************************************************/
+
+static int TranslateLayer( OGRDataSource *poSrcDS, 
+                           OGRLayer * poSrcLayer,
+                           OGRDataSource *poDstDS,
+                           char **papszLCO,
+                           const char *pszNewLayerName,
+                           int bTransform, 
+                           OGRSpatialReference *poOutputSRS,
+                           OGRSpatialReference *poSourceSRS,
+                           char **papszSelFields,
+                           int bAppend, int eGType, int bOverwrite,
+                           double dfMaxSegmentLength)
+		
+{
+    OGRLayer    *poDstLayer;
+    OGRFeatureDefn *poFDefn;
+    OGRErr      eErr;
+    int         bForceToPolygon = FALSE;
+    int         bForceToMultiPolygon = FALSE;
+
+    if( pszNewLayerName == NULL )
+        pszNewLayerName = poSrcLayer->GetLayerDefn()->GetName();
+
+    if( wkbFlatten(eGType) == wkbPolygon )
+        bForceToPolygon = TRUE;
+    else if( wkbFlatten(eGType) == wkbMultiPolygon )
+        bForceToMultiPolygon = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Setup coordinate transformation if we need it.                  */
+/* -------------------------------------------------------------------- */
+    OGRCoordinateTransformation *poCT = NULL;
+
+    if( bTransform )
+    {
+        if( poSourceSRS == NULL )
+            poSourceSRS = poSrcLayer->GetSpatialRef();
+
+        if( poSourceSRS == NULL )
+        {
+            fprintf( stderr, "Can't transform coordinates, source layer has no\n"
+                    "coordinate system.  Use -s_srs to set one.\n" );
+#ifdef ZOO_SERVICE
+            return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+
+        CPLAssert( NULL != poSourceSRS );
+        CPLAssert( NULL != poOutputSRS );
+
+        poCT = OGRCreateCoordinateTransformation( poSourceSRS, poOutputSRS );
+        if( poCT == NULL )
+        {
+            char        *pszWKT = NULL;
+
+            fprintf( stderr, "Failed to create coordinate transformation between the\n"
+                   "following coordinate systems.  This may be because they\n"
+                   "are not transformable, or because projection services\n"
+                   "(PROJ.4 DLL/.so) could not be loaded.\n" );
+            
+            poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
+            fprintf( stderr,  "Source:\n%s\n", pszWKT );
+            
+            poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
+            fprintf( stderr,  "Target:\n%s\n", pszWKT );
+#ifdef ZOO_SERVICE
+            return SERVICE_FAILED;
+#else
+            exit( 1 );
+#endif
+        }
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Get other info.                                                 */
+/* -------------------------------------------------------------------- */
+    poFDefn = poSrcLayer->GetLayerDefn();
+    
+    if( poOutputSRS == NULL )
+        poOutputSRS = poSrcLayer->GetSpatialRef();
+
+/* -------------------------------------------------------------------- */
+/*      Find the layer.                                                 */
+/* -------------------------------------------------------------------- */
+    int iLayer = -1;
+    poDstLayer = NULL;
+
+    for( iLayer = 0; iLayer < poDstDS->GetLayerCount(); iLayer++ )
+    {
+        OGRLayer        *poLayer = poDstDS->GetLayer(iLayer);
+
+        if( poLayer != NULL 
+            && EQUAL(poLayer->GetLayerDefn()->GetName(),pszNewLayerName) )
+        {
+            poDstLayer = poLayer;
+            break;
+        }
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      If the user requested overwrite, and we have the layer in       */
+/*      question we need to delete it now so it will get recreated      */
+/*      (overwritten).                                                  */
+/* -------------------------------------------------------------------- */
+    if( poDstLayer != NULL && bOverwrite )
+    {
+        if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
+        {
+            fprintf( stderr, 
+                     "DeleteLayer() failed when overwrite requested.\n" );
+            return FALSE;
+        }
+        poDstLayer = NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the layer does not exist, then create it.                    */
+/* -------------------------------------------------------------------- */
+    if( poDstLayer == NULL )
+    {
+        if( eGType == -2 )
+            eGType = poFDefn->GetGeomType();
+
+        if( !poDstDS->TestCapability( ODsCCreateLayer ) )
+        {
+            fprintf( stderr, 
+              "Layer %s not found, and CreateLayer not supported by driver.", 
+                     pszNewLayerName );
+            return FALSE;
+        }
+
+        CPLErrorReset();
+
+        poDstLayer = poDstDS->CreateLayer( pszNewLayerName, poOutputSRS,
+                                           (OGRwkbGeometryType) eGType, 
+                                           papszLCO );
+
+        if( poDstLayer == NULL )
+            return FALSE;
+
+        bAppend = FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise we will append to it, if append was requested.        */
+/* -------------------------------------------------------------------- */
+    else if( !bAppend )
+    {
+        fprintf( stderr, "FAILED: Layer %s already exists, and -append not specified.\n"
+                "        Consider using -append, or -overwrite.\n",
+                pszNewLayerName );
+        return FALSE;
+    }
+    else
+    {
+        if( CSLCount(papszLCO) > 0 )
+        {
+            fprintf( stderr, "WARNING: Layer creation options ignored since an existing layer is\n"
+                    "         being appended to.\n" );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add fields.  Default to copy all field.                         */
+/*      If only a subset of all fields requested, then output only      */
+/*      the selected fields, and in the order that they were            */
+/*      selected.                                                       */
+/* -------------------------------------------------------------------- */
+    int         iField;
+    int hasMmField=-1;
+
+    if (papszSelFields && !bAppend )
+    {
+        for( iField=0; papszSelFields[iField] != NULL; iField++)
+        {
+            int iSrcField = poFDefn->GetFieldIndex(papszSelFields[iField]);
+	    OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iSrcField);
+	    fprintf(stderr,"NAME: %s\n",tmp->GetNameRef());
+	    fflush(stderr);
+	    if(tmp!=NULL && strncasecmp(tmp->GetNameRef(),"MMID",4)==0)
+	      hasMmField=1;
+            if (iSrcField >= 0)
+                poDstLayer->CreateField( poFDefn->GetFieldDefn(iSrcField) );
+            else
+            {
+                fprintf( stderr, "Field '%s' not found in source layer.\n", 
+                        papszSelFields[iField] );
+                if( !bSkipFailures )
+                    return FALSE;
+            }
+        }
+
+    }
+    else if( !bAppend )
+    {
+      for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ){
+            poDstLayer->CreateField( poFDefn->GetFieldDefn(iField) );
+	    OGRFieldDefn *tmp=poFDefn->GetFieldDefn(iField);
+	    if(tmp!=NULL && strncasecmp(tmp->GetNameRef(),"MMID",4)==0)
+	      hasMmField=1;
+	    fprintf(stderr,"NAME: %s\n",tmp->GetNameRef());
+      }
+    }
+    /*if(hasMmField<0){
+      OGRFieldDefn oField( "MMID", OFTInteger );
+      poDstLayer->CreateField( &oField );
+      }*/
+
+/* -------------------------------------------------------------------- */
+/*      Transfer features.                                              */
+/* -------------------------------------------------------------------- */
+    OGRFeature  *poFeature;
+    int         nFeaturesInTransaction = 0;
+    int fCount=0;
+    poSrcLayer->ResetReading();
+
+    if( nGroupTransactions )
+        poDstLayer->StartTransaction();
+
+    while( TRUE )
+    {
+        OGRFeature      *poDstFeature = NULL;
+
+        if( nFIDToFetch != OGRNullFID )
+        {
+            // Only fetch feature on first pass.
+            if( nFeaturesInTransaction == 0 )
+                poFeature = poSrcLayer->GetFeature(nFIDToFetch);
+            else
+                poFeature = NULL;
+        }
+        else
+            poFeature = poSrcLayer->GetNextFeature();
+
+        if( poFeature == NULL )
+            break;
+
+	//poFeature->SetField((poFeature->GetFieldCount()-1),fCount);
+
+        if( ++nFeaturesInTransaction == nGroupTransactions )
+        {
+            poDstLayer->CommitTransaction();
+            poDstLayer->StartTransaction();
+            nFeaturesInTransaction = 0;
+        }
+
+        CPLErrorReset();
+        poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
+
+        if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE )
+        {
+            if( nGroupTransactions )
+                poDstLayer->CommitTransaction();
+            
+            CPLError( CE_Failure, CPLE_AppDefined,
+                      "Unable to translate feature %ld from layer %s.\n",
+                      poFeature->GetFID(), poFDefn->GetName() );
+            
+            OGRFeature::DestroyFeature( poFeature );
+            OGRFeature::DestroyFeature( poDstFeature );
+            return FALSE;
+        }
+
+        if( bPreserveFID )
+            poDstFeature->SetFID( poFeature->GetFID() );
+
+	/*if(hasMmField<0){
+	  poDstFeature->SetField((poDstFeature->GetFieldCount()-1),fCount);
+	  fCount++;
+	}*/
+
+#ifndef GDAL_1_5_0
+        if (poDstFeature->GetGeometryRef() != NULL && dfMaxSegmentLength > 0)
+            poDstFeature->GetGeometryRef()->segmentize(dfMaxSegmentLength);
+#endif
+
+        if( poCT && poDstFeature->GetGeometryRef() != NULL )
+        {
+            eErr = poDstFeature->GetGeometryRef()->transform( poCT );
+            if( eErr != OGRERR_NONE )
+            {
+                if( nGroupTransactions )
+                    poDstLayer->CommitTransaction();
+
+                fprintf( stderr, "Failed to reproject feature %d (geometry probably out of source or destination SRS).\n", 
+                        (int) poFeature->GetFID() );
+                if( !bSkipFailures )
+                {
+                    OGRFeature::DestroyFeature( poFeature );
+                    OGRFeature::DestroyFeature( poDstFeature );
+                    return FALSE;
+                }
+            }
+        }
+
+        if( poDstFeature->GetGeometryRef() != NULL && bForceToPolygon )
+        {
+            poDstFeature->SetGeometryDirectly( 
+                OGRGeometryFactory::forceToPolygon(
+                    poDstFeature->StealGeometry() ) );
+        }
+                    
+        if( poDstFeature->GetGeometryRef() != NULL && bForceToMultiPolygon )
+        {
+            poDstFeature->SetGeometryDirectly( 
+                OGRGeometryFactory::forceToMultiPolygon(
+                    poDstFeature->StealGeometry() ) );
+        }
+                    
+        OGRFeature::DestroyFeature( poFeature );
+
+        CPLErrorReset();
+        if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE 
+            && !bSkipFailures )
+        {
+            if( nGroupTransactions )
+                poDstLayer->RollbackTransaction();
+
+            OGRFeature::DestroyFeature( poDstFeature );
+            return FALSE;
+        }
+
+        OGRFeature::DestroyFeature( poDstFeature );
+    }
+
+    if( nGroupTransactions )
+        poDstLayer->CommitTransaction();
+
+/* -------------------------------------------------------------------- */
+/*      Cleaning                                                        */
+/* -------------------------------------------------------------------- */
+    delete poCT;
+
+    return TRUE;
+}
+
+#ifdef ZOO_SERVICE
+}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Exporter.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Exporter.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Exporter.py	(revision 672)
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+#
+# Author : Gérald FENOY
+#
+# Copyright 2008-2013 GeoLabs SARL. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including with
+# out limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import uno
+import getopt, sys
+
+from unohelper import Base, systemPathToFileUrl, absolutize
+
+from com.sun.star.beans import PropertyValue
+from com.sun.star.script import CannotConvertException
+from com.sun.star.lang import IllegalArgumentException
+from com.sun.star.task import ErrorCodeIOException
+from com.sun.star.io import IOException, XOutputStream
+
+class OutputStream( Base, XOutputStream ):
+    def __init__( self ):
+        self.closed = 0
+    def closeOutput(self):
+        self.closed = 1
+    def writeBytes( self, seq ):
+        sys.stdout.write( seq.value )
+    def flush( self ):
+        pass
+
+def OdtConverter(conf,inputs,outputs):
+	# get the uno component context from the PyUNO runtime  
+	localContext = uno.getComponentContext()
+
+	# create the UnoUrlResolver 
+	# on a single line
+	resolver = 	localContext.ServiceManager.createInstanceWithContext	("com.sun.star.bridge.UnoUrlResolver", localContext )
+
+	# connect to the running office                                 
+	ctx = resolver.resolve( conf["oo"]["server"].replace("::","=")+";urp;StarOffice.ComponentContext" )
+	smgr = ctx.ServiceManager
+
+	# get the central desktop object
+	desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
+
+	# get the file name
+	adressDoc=systemPathToFileUrl(conf["main"]["dataPath"]+"/"+inputs["InputDoc"]["value"])
+
+	propFich=PropertyValue("Hidden", 0, True, 0),
+
+	myDocument=0
+	try:
+	    myDocument = desktop.loadComponentFromURL(adressDoc,"_blank",0,propFich)
+	except CannotConvertException, e:
+	    print >> sys.stderr,  'Impossible de convertir le fichier pour les raisons suivantes : \n'
+	    print >> sys.stderr,  e
+	    sys.exit(0)
+	except IllegalArgumentException, e:
+	    print >> sys.stderr,  'Impossible de convertir le fichier pour les 	raisons suivantes : \n'
+	    print >> sys.stderr,  e
+	    sys.exit(0)
+
+	outputDoc=systemPathToFileUrl(conf["main"]["tmpPath"]+"/"+inputs["OutputDoc"]["value"])
+
+	tmp=inputs["OutputDoc"]["value"].split('.');
+
+	outputFormat={"pdf": "writer_pdf_Export", "html": "HTML (StarWriter)","odt": "writer8","doc": "MS Word 97","rtf": "Rich Text Format"}
+
+	for i in range(len(outputFormat)) :
+	    if tmp[1]==outputFormat.keys()[i] :
+	        filterName=outputFormat[tmp[1]]
+	        prop1Fich = (
+	            PropertyValue( "FilterName" , 0, filterName , 0 ),
+		        PropertyValue( "Overwrite" , 0, True , 0 )
+	        )
+	        break
+
+	myDocument.storeToURL(outputDoc,prop1Fich)
+	myDocument.close(True)
+	ctx.ServiceManager
+	outputs["OutputedDocument"]={"value": inputs["OutputDoc"]["value"],"dataType": "string"}
+	return 3
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/OdtConverter.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/OdtConverter.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/OdtConverter.zcfg	(revision 672)
@@ -0,0 +1,43 @@
+[OdtConverter]
+ Title = Converts Open Documents. 
+ Abstract = Converts open documents.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = Python
+ serviceProvider = Exporter
+ <MetaData>
+   title = My Demo
+ </MetaData>
+ <DataInputs>
+  [InputDoc]
+   Title = The input data source name
+   Abstract = The input data source name
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+  [OutputDoc]
+   Title = The output data source name
+   Abstract = The output data source name to use as source.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [OutputedDoc]
+   Title = The resulting converted file
+   Abstract = The file name resulting of the convertion
+   <LiteralData>
+    DataType = string
+    <Default>
+    </Default>	
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Xml2Pdf.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Xml2Pdf.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/Xml2Pdf.zcfg	(revision 672)
@@ -0,0 +1,39 @@
+[Xml2Pdf]
+ Title = Convert XML and Open Document to PDF format. 
+ Abstract = Converts XML to PDF format.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceType = Python
+ serviceProvider = oo_service
+ <DataInputs>
+  [doc]
+   Title = The input Open Document Text
+   Abstract = The input Open Document Text including all required Styles
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default/>
+   </LiteralData>
+  [xml]
+   Title = The input XML file
+   Abstract = The input XML file to convert.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default/>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Document]
+   Title = The resulting file
+   Abstract = The file content resulting of the convertion from XML to PDF
+   <ComplexData>
+    <Default>
+     mimeType=application/pdf
+     extension=pdf
+    </Default>	
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/oo_service.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/oo_service.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/openoffice/cgi-env/oo_service.py	(revision 672)
@@ -0,0 +1,144 @@
+#
+# Author : Gérald FENOY
+#
+# Copyright 2008-2013 GeoLabs SARL. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+import uno
+import getopt, sys, os
+
+from unohelper import Base, systemPathToFileUrl, absolutize
+
+from com.sun.star.beans import PropertyValue
+from com.sun.star.script import CannotConvertException
+from com.sun.star.lang import IllegalArgumentException
+from com.sun.star.task import ErrorCodeIOException
+from com.sun.star.io import IOException, XOutputStream
+from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER
+from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
+
+from xml.dom import minidom 
+import sys 
+
+keep_trace=''
+
+def addToText(cursor,text,level,value):
+    if level==1:
+        cursor.NumberingStyleName = "NONE"
+        cursor.ParaStyleName="Heading 1"
+        text.insertString( cursor, value , 0 )
+        text.insertControlCharacter( cursor, PARAGRAPH_BREAK , 0 )
+        #print  >> sys.stderr,' * Main Title : ' + value
+    else:
+        i=0
+        prefix=''
+        while i < level-1:
+            prefix+=' '
+            i+=1
+        cursor.NumberingStyleName="List "+str(level-1)
+        text.insertString( cursor, prefix+value , 0 )
+        text.insertControlCharacter( cursor, PARAGRAPH_BREAK , 0 )
+        cursor.NumberingStyleName = "NONE"
+	#print  >> sys.stderr,dir(sys.stderr)
+        #print >> sys.stderr,prefix+' * NumberingStyleName '+str(level-1)+' '+value.encode('iso-8859-15')
+
+def printChildren(cursor,text,node,level,keep_trace):
+    if node.nodeType==3:
+        level-=1
+
+    if not(node.nodeValue!=None and len(node.nodeValue.replace(' ',''))!=1 and keep_trace!='' and keep_trace!=None):
+        if keep_trace!='':
+            addToText(cursor,text,level-1,keep_trace)
+        keep_trace=node.nodeName
+
+    if node.hasChildNodes():
+        for i in node.childNodes:
+            printChildren(cursor,text,i,level+1,keep_trace)
+            keep_trace=''
+    else:
+        if node.nodeValue != None and len(node.nodeValue.replace(' ',''))>1:
+            addToText(cursor,text,level-1,keep_trace+' : '+node.nodeValue)
+            keep_trace=''
+        else:
+            if node.nodeValue != None and len(node.nodeValue.replace(' ',''))>1:
+                addToText(cursor,text,level-1,keep_trace+' : '+node.nodeValue)
+                keep_trace=''
+            else:
+                if keep_trace!='#text':
+                    addToText(cursor,text,level-1,keep_trace)
+                    keep_trace=''
+
+    if node.nodeType==1 and node.hasAttributes():
+        i=0
+        while i<node.attributes.length:
+            addToText(cursor,text,level,'(attr) '+node.attributes.keys()[i] + ' : ' + node.attributes[node.attributes.keys()[i]].value)
+            i+=1
+
+        
+
+def Xml2Pdf(conf,input,output):
+    localContext = uno.getComponentContext()
+    resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
+    ctx = resolver.resolve( "uno:socket,host=127.0.0.1,port=3662;urp;StarOffice.ComponentContext" )
+    smgr = ctx.ServiceManager
+    desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
+    adressDoc=systemPathToFileUrl(input["doc"]["value"])
+    propFich=PropertyValue("Hidden", 0, True, 0),
+    try:
+        myDocument = desktop.loadComponentFromURL(adressDoc,"_blank",0,propFich)
+	#Prefer to create a new document without any style ?
+        #myDocument = desktop.loadComponentFromURL("private:factory/writer","_blank",0,propFich)
+    except:
+        conf["lenv"]["message"]='Unable to load input document'
+	return 4
+    text = myDocument.Text
+    cursor = text.createTextCursor()
+    cursor.gotoStart(0)
+    cursor.gotoEnd(1)
+    xmldoc = minidom.parseString(input['xml']['value'])
+
+    if xmldoc.hasChildNodes():
+        for i in xmldoc.childNodes:
+            if i.nodeType==1:
+                cursor.ParaStyleName="Title"
+                text.insertString( cursor, i.nodeName , 0 )
+                text.insertControlCharacter( cursor, PARAGRAPH_BREAK , 0 )
+                #print >> sys.stderr,' * 1st level' + i.nodeName
+                if i.hasChildNodes():
+                    for j in i.childNodes:
+                        printChildren(cursor,text,j,2,'')
+
+    tmp=myDocument.StyleFamilies.getByName("NumberingStyles")
+
+    tmp1=tmp.getByName("Puce 1")
+
+    prop1Fich = ( PropertyValue( "FilterName" , 0, "writer_pdf_Export", 0 ),PropertyValue( "Overwrite" , 0, True , 0 ) )
+    outputDoc=systemPathToFileUrl("/tmp/output.pdf")
+    myDocument.storeToURL(outputDoc,prop1Fich)
+
+    myDocument.close(True)
+    ctx.ServiceManager
+    output["Document"]["value"]= open('/tmp/output.pdf', 'r').read()
+    print >> sys.stderr,len(output["Document"]["value"])
+    return 3
+
+#To run test from command line uncomment the following line:
+#xml2pdf({},{"file":{"value":"/tmp/demo.xml"},"doc":{"value":"/tmp/demo.odt"}},{})
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/Makefile	(revision 672)
@@ -0,0 +1,10 @@
+ZRPATH=../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CC=gcc
+
+cgi-env/qrencode.zo: qrenc-service.c
+	g++ -DZOO_SERVICE_PROVIDER ${CFLAGS} -shared -fpic -o cgi-env/qrencode.zo ./qrenc-service.c -lqrencode ${GDAL_LIBS} -lpng ${MACOS_LD_FLAGS}
+
+clean:
+	rm -f cgi-env/*.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/cgi-env/QREncode.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/cgi-env/QREncode.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/cgi-env/QREncode.zcfg	(revision 672)
@@ -0,0 +1,69 @@
+[QREncode]
+ Title = Encode a string into a QR Code
+ Abstract = Multiply two values and store the result in Result.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = qrencode.zo
+ serviceType = C
+ <DataInputs>
+  [Text]
+   Title = the input string
+   Abstract = The string to encode using QREncode.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+     uom = meters
+    </Default>
+    <Supported>
+     uom = feet
+    </Supported>
+   </LiteralData>
+  [fgcolor]
+   Title = the input string
+   Abstract = The string (RRGGBBAA) for for foreground color.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+     value=000000
+    </Default>
+   </LiteralData>
+  [bgcolor]
+   Title = the input string
+   Abstract = The string (RRGGBBAA) for for background color.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+     value=ffffff
+    </Default>
+   </LiteralData>
+  [size]
+   Title = the image size
+   Abstract = The generated image size.
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    dataType = integer
+    <Default>
+     value=3
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [QR]
+   Title = the QR Code image 
+   Abstract = The QRCode corresponding to the string encoded.
+   minOccurs = 1
+   maxOccurs = 1
+   <ComplexData>
+       <Default>
+            mimeType = image/png
+       </Default>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/makefile.vc	(revision 672)
@@ -0,0 +1,23 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj 
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+qrencode.zo: qrenc-service.c
+	$(CPP) -Ivc8\qrcode /DOGR_ENABLED /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE_PROVIDER -I$(GDAL_DIR)/frmts/ -I$(GDAL_DIR)/alg/ $(CFLAGS) -I$(PNG_DIR) /c qrenc-service.c
+	link /dll /out:cgi-env/qrencode.zo  $(FILES) ./qrenc-service.obj $(LDFLAGS) $(PNG_DIR)/libpng15.lib $(QRENCODE_DIR)vc8/.build/Release-Lib/qrcodelib.lib /FORCE:MULTIPLE /NODEFAULTLIB:library
+
+clean:
+	erase qrencode.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/qrenc-service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/qrenc-service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/qrencode/qrenc-service.c	(revision 672)
@@ -0,0 +1,1215 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-*/
+
+/**
+ * qrencode - QR Code encoder
+ *
+ * QR Code encoding tool
+ * Copyright (C) 2006-2012 Kentaro Fukuchi <kentaro@fukuchi.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+#include <getopt.h>
+
+#ifdef ZOO_SERVICE_PROVIDER
+#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
+#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)
+#ifdef WIN32
+#include "windows.h"
+#endif
+#include "service.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
+#include "qrencode.h"
+
+#define INCHES_PER_METER (100.0/2.54)
+
+static int casesensitive = 1;
+static int eightbit = 0;
+static int version = 0;
+static int size = 3;
+static int margin = -1;
+static int dpi = 72;
+static int structured = 0;
+static int micro = 0;
+static QRecLevel level = QR_ECLEVEL_L;
+static QRencodeMode hint = QR_MODE_8;
+static unsigned int fg_color[4] = {0, 0, 0, 255};
+static unsigned int bg_color[4] = {255, 255, 255, 255};
+
+enum imageType {
+	PNG_TYPE,
+	EPS_TYPE,
+	SVG_TYPE,
+	ANSI_TYPE,
+	ANSI256_TYPE,
+	ASCII_TYPE,
+	ASCIIi_TYPE,
+	UTF8_TYPE,
+	ANSIUTF8_TYPE
+};
+
+static enum imageType image_type = PNG_TYPE;
+
+static const struct option options[] = {
+	{"help"         , no_argument      , NULL, 'h'},
+	{"output"       , required_argument, NULL, 'o'},
+	{"level"        , required_argument, NULL, 'l'},
+	{"size"         , required_argument, NULL, 's'},
+	{"symversion"   , required_argument, NULL, 'v'},
+	{"margin"       , required_argument, NULL, 'm'},
+	{"dpi"          , required_argument, NULL, 'd'},
+	{"type"         , required_argument, NULL, 't'},
+	{"structured"   , no_argument      , NULL, 'S'},
+	{"kanji"        , no_argument      , NULL, 'k'},
+	{"casesensitive", no_argument      , NULL, 'c'},
+	{"ignorecase"   , no_argument      , NULL, 'i'},
+	{"8bit"         , no_argument      , NULL, '8'},
+	{"micro"        , no_argument      , NULL, 'M'},
+	{"foreground"	, required_argument, NULL, 'f'},
+	{"background"	, required_argument, NULL, 'b'},
+	{"version"      , no_argument      , NULL, 'V'},
+	{NULL, 0, NULL, 0}
+};
+
+static char *optstring = "ho:l:s:v:m:d:t:Skci8MV";
+
+static void usage(int help, int longopt)
+{
+	fprintf(stderr,
+"qrencode version %s\n"
+"Copyright (C) 2006-2012 Kentaro Fukuchi\n", QRcode_APIVersionString());
+	if(help) {
+		if(longopt) {
+			fprintf(stderr,
+"Usage: qrencode [OPTION]... [STRING]\n"
+"Encode input data in a QR Code and save as a PNG or EPS image.\n\n"
+"  -h, --help   display the help message. -h displays only the help of short\n"
+"               options.\n\n"
+"  -o FILENAME, --output=FILENAME\n"
+"               write image to FILENAME. If '-' is specified, the result\n"
+"               will be output to standard output. If -S is given, structured\n"
+"               symbols are written to FILENAME-01.png, FILENAME-02.png, ...\n"
+"               (suffix is removed from FILENAME, if specified)\n"
+"  -s NUMBER, --size=NUMBER\n"
+"               specify module size in dots (pixels). (default=3)\n\n"
+"  -l {LMQH}, --level={LMQH}\n"
+"               specify error correction level from L (lowest) to H (highest).\n"
+"               (default=L)\n\n"
+"  -v NUMBER, --symversion=NUMBER\n"
+"               specify the version of the symbol. (default=auto)\n\n"
+"  -m NUMBER, --margin=NUMBER\n"
+"               specify the width of the margins. (default=4 (2 for Micro)))\n\n"
+"  -d NUMBER, --dpi=NUMBER\n"
+"               specify the DPI of the generated PNG. (default=72)\n\n"
+"  -t {PNG,EPS,SVG,ANSI,ANSI256,ASCII,ASCIIi,UTF8,ANSIUTF8}, --type={PNG,EPS,\n"
+"               SVG,ANSI,ANSI256,ASCII,ASCIIi,UTF8,ANSIUTF8}\n"
+"               specify the type of the generated image. (default=PNG)\n\n"
+"  -S, --structured\n"
+"               make structured symbols. Version must be specified.\n\n"
+"  -k, --kanji  assume that the input text contains kanji (shift-jis).\n\n"
+"  -c, --casesensitive\n"
+"               encode lower-case alphabet characters in 8-bit mode. (default)\n\n"
+"  -i, --ignorecase\n"
+"               ignore case distinctions and use only upper-case characters.\n\n"
+"  -8, --8bit   encode entire data in 8-bit mode. -k, -c and -i will be ignored.\n\n"
+"  -M, --micro  encode in a Micro QR Code. (experimental)\n\n"
+"  --foreground=RRGGBB[AA]\n"
+"  --background=RRGGBB[AA]\n"
+"               specify foreground/background color in hexadecimal notation.\n"
+"               6-digit (RGB) or 8-digit (RGBA) form are supported.\n"
+"               Color output support available only in PNG and SVG.\n"
+"  -V, --version\n"
+"               display the version number and copyrights of the qrencode.\n\n"
+"  [STRING]     input data. If it is not specified, data will be taken from\n"
+"               standard input.\n"
+			);
+		} else {
+			fprintf(stderr,
+"Usage: qrencode [OPTION]... [STRING]\n"
+"Encode input data in a QR Code and save as a PNG or EPS image.\n\n"
+"  -h           display this message.\n"
+"  --help       display the usage of long options.\n"
+"  -o FILENAME  write image to FILENAME. If '-' is specified, the result\n"
+"               will be output to standard output. If -S is given, structured\n"
+"               symbols are written to FILENAME-01.png, FILENAME-02.png, ...\n"
+"               (suffix is removed from FILENAME, if specified)\n"
+"  -s NUMBER    specify module size in dots (pixels). (default=3)\n"
+"  -l {LMQH}    specify error correction level from L (lowest) to H (highest).\n"
+"               (default=L)\n"
+"  -v NUMBER    specify the version of the symbol. (default=auto)\n"
+"  -m NUMBER    specify the width of the margins. (default=4 (2 for Micro))\n"
+"  -d NUMBER    specify the DPI of the generated PNG. (default=72)\n"
+"  -t {PNG,EPS,SVG,ANSI,ANSI256,ASCII,ASCIIi,UTF8,ANSIUTF8}\n"
+"               specify the type of the generated image. (default=PNG)\n"
+"  -S           make structured symbols. Version must be specified.\n"
+"  -k           assume that the input text contains kanji (shift-jis).\n"
+"  -c           encode lower-case alphabet characters in 8-bit mode. (default)\n"
+"  -i           ignore case distinctions and use only upper-case characters.\n"
+"  -8           encode entire data in 8-bit mode. -k, -c and -i will be ignored.\n"
+"  -M           encode in a Micro QR Code.\n"
+"  --foreground=RRGGBB[AA]\n"
+"  --background=RRGGBB[AA]\n"
+"               specify foreground/background color in hexadecimal notation.\n"
+"               6-digit (RGB) or 8-digit (RGBA) form are supported.\n"
+"               Color output support available only in PNG and SVG.\n"
+"  -V           display the version number and copyrights of the qrencode.\n"
+"  [STRING]     input data. If it is not specified, data will be taken from\n"
+"               standard input.\n"
+			);
+		}
+	}
+}
+
+static int color_set(unsigned int color[4], const char *value)
+{
+	int len = strlen(value);
+	int count;
+	if(len == 6) {
+		count = sscanf(value, "%02x%02x%02x%n", &color[0], &color[1], &color[2], &len);
+		if(count < 3 || len != 6) {
+			return -1;
+		}
+		color[3] = 255;
+	} else if(len == 8) {
+		count = sscanf(value, "%02x%02x%02x%02x%n", &color[0], &color[1], &color[2], &color[3], &len);
+		if(count < 4 || len != 8) {
+			return -1;
+		}
+	} else {
+		return -1;
+	}
+	return 0;
+}
+
+#define MAX_DATA_SIZE (7090 * 16) /* from the specification */
+static unsigned char *readStdin(int *length)
+{
+	unsigned char *buffer;
+	int ret;
+
+	buffer = (unsigned char *)malloc(MAX_DATA_SIZE + 1);
+	if(buffer == NULL) {
+		fprintf(stderr, "Memory allocation failed.\n");
+		exit(EXIT_FAILURE);
+	}
+	ret = fread(buffer, 1, MAX_DATA_SIZE, stdin);
+	if(ret == 0) {
+		fprintf(stderr, "No input data.\n");
+		exit(EXIT_FAILURE);
+	}
+	if(feof(stdin) == 0) {
+		fprintf(stderr, "Input data is too large.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	buffer[ret] = '\0';
+	*length = ret;
+
+	return buffer;
+}
+
+static FILE *openFile(const char *outfile)
+{
+	FILE *fp;
+
+	if(outfile == NULL || (outfile[0] == '-' && outfile[1] == '\0')) {
+		fp = stdout;
+	} else {
+		fp = fopen(outfile, "wb");
+		if(fp == NULL) {
+			fprintf(stderr, "Failed to create file: %s\n", outfile);
+			perror(NULL);
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	return fp;
+}
+
+static int writePNG(QRcode *qrcode, const char *outfile)
+{
+	static FILE *fp; // avoid clobbering by setjmp.
+	png_structp png_ptr;
+	png_infop info_ptr;
+	png_colorp palette;
+	png_byte alpha_values[2];
+	unsigned char *row, *p, *q;
+	int x, y, xx, yy, bit;
+	int realwidth;
+
+	realwidth = (qrcode->width + margin * 2) * size;
+	row = (unsigned char *)malloc((realwidth + 7) / 8);
+	if(row == NULL) {
+		fprintf(stderr, "Failed to allocate memory.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if(outfile[0] == '-' && outfile[1] == '\0') {
+		fp = stdout;
+	} else {
+		fp = fopen(outfile, "wb");
+		if(fp == NULL) {
+			fprintf(stderr, "Failed to create file: %s\n", outfile);
+			perror(NULL);
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if(png_ptr == NULL) {
+		fprintf(stderr, "Failed to initialize PNG writer.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	info_ptr = png_create_info_struct(png_ptr);
+	if(info_ptr == NULL) {
+		fprintf(stderr, "Failed to initialize PNG write.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if(setjmp(png_jmpbuf(png_ptr))) {
+		png_destroy_write_struct(&png_ptr, &info_ptr);
+		fprintf(stderr, "Failed to write PNG image.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	palette = (png_colorp) malloc(sizeof(png_color) * 2);
+	palette[0].red   = fg_color[0];
+	palette[0].green = fg_color[1];
+	palette[0].blue  = fg_color[2];
+	palette[1].red   = bg_color[0];
+	palette[1].green = bg_color[1];
+	palette[1].blue  = bg_color[2];
+	alpha_values[0] = fg_color[3];
+	alpha_values[1] = bg_color[3];
+	png_set_PLTE(png_ptr, info_ptr, palette, 2);
+	png_set_tRNS(png_ptr, info_ptr, alpha_values, 2, NULL);
+
+	png_init_io(png_ptr, fp);
+	png_set_IHDR(png_ptr, info_ptr,
+			realwidth, realwidth,
+			1,
+			PNG_COLOR_TYPE_PALETTE,
+			PNG_INTERLACE_NONE,
+			PNG_COMPRESSION_TYPE_DEFAULT,
+			PNG_FILTER_TYPE_DEFAULT);
+	png_set_pHYs(png_ptr, info_ptr,
+			dpi * INCHES_PER_METER,
+			dpi * INCHES_PER_METER,
+			PNG_RESOLUTION_METER);
+	png_write_info(png_ptr, info_ptr);
+
+	/* top margin */
+	memset(row, 0xff, (realwidth + 7) / 8);
+	for(y=0; y<margin * size; y++) {
+		png_write_row(png_ptr, row);
+	}
+
+	/* data */
+	p = qrcode->data;
+	for(y=0; y<qrcode->width; y++) {
+		bit = 7;
+		memset(row, 0xff, (realwidth + 7) / 8);
+		q = row;
+		q += margin * size / 8;
+		bit = 7 - (margin * size % 8);
+		for(x=0; x<qrcode->width; x++) {
+			for(xx=0; xx<size; xx++) {
+				*q ^= (*p & 1) << bit;
+				bit--;
+				if(bit < 0) {
+					q++;
+					bit = 7;
+				}
+			}
+			p++;
+		}
+		for(yy=0; yy<size; yy++) {
+			png_write_row(png_ptr, row);
+		}
+	}
+	/* bottom margin */
+	memset(row, 0xff, (realwidth + 7) / 8);
+	for(y=0; y<margin * size; y++) {
+		png_write_row(png_ptr, row);
+	}
+
+	png_write_end(png_ptr, info_ptr);
+	png_destroy_write_struct(&png_ptr, &info_ptr);
+
+	fclose(fp);
+	free(row);
+
+	return 0;
+}
+
+static int writeEPS(QRcode *qrcode, const char *outfile)
+{
+	FILE *fp;
+	unsigned char *row, *p;
+	int x, y, yy;
+	int realwidth;
+
+	fp = openFile(outfile);
+   
+	realwidth = (qrcode->width + margin * 2) * size;
+	/* EPS file header */
+	fprintf(fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"
+				"%%%%BoundingBox: 0 0 %d %d\n"
+				"%%%%Pages: 1 1\n"
+				"%%%%EndComments\n", realwidth, realwidth);
+	/* draw point */
+	fprintf(fp, "/p { "
+				"moveto "
+				"0 1 rlineto "
+				"1 0 rlineto "
+				"0 -1 rlineto "
+				"fill "
+				"} bind def "
+				"%d %d scale ", size, size);
+	
+	/* data */
+	p = qrcode->data;
+	for(y=0; y<qrcode->width; y++) {
+		row = (p+(y*qrcode->width));
+		yy = (margin + qrcode->width - y - 1);
+		
+		for(x=0; x<qrcode->width; x++) {
+			if(*(row+x)&0x1) {
+				fprintf(fp, "%d %d p ", margin + x,  yy);
+			}
+		}
+	}
+
+	fprintf(fp, "\n%%%%EOF\n");
+	fclose(fp);
+
+	return 0;
+}
+
+static void writeSVG_writeRect(FILE *fp, int x, int y, int width, char* col, float opacity)
+{
+	if(fg_color[3] != 255) {
+		fprintf(fp, "\t\t\t<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"1\" "\
+				"fill=\"#%s\" fill-opacity=\"%f\" />\n", 
+				x, y, width, col, opacity );
+	} else {
+		fprintf(fp, "\t\t\t<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"1\" "\
+				"fill=\"#%s\" />\n", 
+				x, y, width, col );
+	}
+}
+
+static int writeSVG( QRcode *qrcode, const char *outfile )
+{
+	FILE *fp;
+	unsigned char *row, *p;
+	int x, y, x0, pen;
+	int symwidth, realwidth;
+	float scale;
+	char fg[7], bg[7];
+	float fg_opacity;
+	float bg_opacity;
+
+	fp = openFile(outfile);
+
+	scale = dpi * INCHES_PER_METER / 100.0;
+
+	symwidth = qrcode->width + margin * 2;
+	realwidth = symwidth * size;
+
+	snprintf(fg, 7, "%02x%02x%02x", fg_color[0], fg_color[1],  fg_color[2]);
+	snprintf(bg, 7, "%02x%02x%02x", bg_color[0], bg_color[1],  bg_color[2]);
+	fg_opacity = (float)fg_color[3] / 255;
+	bg_opacity = (float)bg_color[3] / 255;
+
+	/* XML declaration */
+	fputs( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", fp );
+
+	/* DTD 
+	   No document type specified because "while a DTD is provided in [the SVG] 
+	   specification, the use of DTDs for validating XML documents is known to be 
+	   problematic. In particular, DTDs do not handle namespaces gracefully. It 
+	   is *not* recommended that a DOCTYPE declaration be included in SVG 
+	   documents." 
+	   http://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#Namespace
+	*/
+
+	/* Vanity remark */
+	fprintf( fp, "<!-- Created with qrencode %s (http://fukuchi.org/works/qrencode/index.html.en) -->\n", 
+			QRcode_APIVersionString() );
+
+	/* SVG code start */
+	fprintf( fp, "<svg width=\"%0.2fcm\" height=\"%0.2fcm\" viewBox=\"0 0 %d %d\""\
+			" preserveAspectRatio=\"none\" version=\"1.1\""\
+			" xmlns=\"http://www.w3.org/2000/svg\">\n", 
+			realwidth / scale, realwidth / scale, symwidth, symwidth
+		   );
+
+	/* Make named group */
+	fputs( "\t<g id=\"QRcode\">\n", fp );
+
+	/* Make solid background */
+	if(bg_color[3] != 255) {
+		fprintf(fp, "\t\t<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" fill-opacity=\"%f\" />\n", symwidth, symwidth, bg, bg_opacity);
+	} else {
+		fprintf(fp, "\t\t<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", symwidth, symwidth, bg);
+	}
+
+	/* Create new viewbox for QR data */
+	fputs( "\t\t<g id=\"Pattern\">\n", fp);
+
+	/* Write data */
+	p = qrcode->data;
+	for(y=0; y<qrcode->width; y++) {
+		row = (p+(y*qrcode->width));
+
+		/* simple RLE */
+		pen = 0;
+		x0  = 0;
+		for(x=0; x<qrcode->width; x++) {
+			if( !pen ) {
+				pen = *(row+x)&0x1;
+				x0 = x;
+			} else {
+				if(!(*(row+x)&0x1)) {
+					writeSVG_writeRect(fp, x0 + margin, y + margin, x-x0, fg, fg_opacity);
+					pen = 0;
+				}
+			}
+		}
+		if( pen ) {
+			writeSVG_writeRect(fp, x0 + margin, y + margin, qrcode->width - x0, fg, fg_opacity);
+		}
+	}
+
+	/* Close QR data viewbox */
+	fputs( "\t\t</g>\n", fp );
+
+	/* Close group */
+	fputs( "\t</g>\n", fp );
+
+	/* Close SVG code */
+	fputs( "</svg>\n", fp );
+	fclose( fp );
+
+	return 0;
+}
+
+static void writeANSI_margin(FILE* fp, int realwidth,
+                             char* buffer, int buffer_s,
+                             char* white, int white_s )
+{
+	int y;
+
+	strncpy(buffer, white, white_s);
+	memset(buffer + white_s, ' ', realwidth * 2);
+	strcpy(buffer + white_s + realwidth * 2, "\033[0m\n"); // reset to default colors
+	for(y=0; y<margin; y++ ){
+		fputs(buffer, fp);
+	}
+}
+
+static int writeANSI(QRcode *qrcode, const char *outfile)
+{
+	FILE *fp;
+	unsigned char *row, *p;
+	int x, y;
+	int realwidth;
+	int last;
+
+	char *white, *black, *buffer;
+	int white_s, black_s, buffer_s;
+
+	if( image_type == ANSI256_TYPE ){
+		/* codes for 256 color compatible terminals */
+		white = "\033[48;5;231m";
+		white_s = 11;
+		black = "\033[48;5;16m";
+		black_s = 10;
+	} else {
+		white = "\033[47m";
+		white_s = 5;
+		black = "\033[40m";
+		black_s = 5;
+	}
+
+	size = 1;
+
+	fp = openFile(outfile);
+
+	realwidth = (qrcode->width + margin * 2) * size;
+	buffer_s = ( realwidth * white_s ) * 2;
+	buffer = (char *)malloc( buffer_s );
+	if(buffer == NULL) {
+		fprintf(stderr, "Failed to allocate memory.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	/* top margin */
+	writeANSI_margin(fp, realwidth, buffer, buffer_s, white, white_s);
+
+	/* data */
+	p = qrcode->data;
+	for(y=0; y<qrcode->width; y++) {
+		row = (p+(y*qrcode->width));
+
+		bzero( buffer, buffer_s );
+		strncpy( buffer, white, white_s );
+		for(x=0; x<margin; x++ ){
+			strncat( buffer, "  ", 2 );
+		}
+		last = 0;
+
+		for(x=0; x<qrcode->width; x++) {
+			if(*(row+x)&0x1) {
+				if( last != 1 ){
+					strncat( buffer, black, black_s );
+					last = 1;
+				}
+			} else {
+				if( last != 0 ){
+					strncat( buffer, white, white_s );
+					last = 0;
+				}
+			}
+			strncat( buffer, "  ", 2 );
+		}
+
+		if( last != 0 ){
+			strncat( buffer, white, white_s );
+		}
+		for(x=0; x<margin; x++ ){
+			strncat( buffer, "  ", 2 );
+		}
+		strncat( buffer, "\033[0m\n", 5 );
+		fputs( buffer, fp );
+	}
+
+	/* bottom margin */
+	writeANSI_margin(fp, realwidth, buffer, buffer_s, white, white_s);
+
+	fclose(fp);
+	free(buffer);
+
+	return 0;
+}
+
+static void writeUTF8_margin(FILE* fp, int realwidth,
+			     const char* white, const char *reset,
+			     int use_ansi)
+{
+	int x, y;
+
+	for (y = 0; y < margin/2; y++) {
+		fputs(white, fp);
+		for (x = 0; x < realwidth; x++)
+			fputs("\342\226\210", fp);
+		fputs(reset, fp);
+		fputc('\n', fp);
+	}
+}
+
+static int writeUTF8(QRcode *qrcode, const char *outfile, int use_ansi)
+{
+	FILE *fp;
+	int x, y;
+	int realwidth;
+	unsigned char *p;
+	const char *white, *reset;
+
+	if (use_ansi){
+		white = "\033[40;37;1m";
+		reset = "\033[0m";
+	} else {
+		white = "";
+		reset = "";
+	}
+
+	fp = openFile(outfile);
+
+	realwidth = (qrcode->width + margin * 2);
+
+	/* top margin */
+	writeUTF8_margin(fp, realwidth, white, reset, use_ansi);
+
+	/* data */
+	p = qrcode->data;
+	for(y = 0; y < qrcode->width; y += 2) {
+		unsigned char *row1, *row2;
+		row1 = p + y*qrcode->width;
+		row2 = p + y*qrcode->width + qrcode->width;
+
+		fputs(white, fp);
+
+		for (x = 0; x < margin; x++)
+			fputs("\342\226\210", fp);
+
+		for (x = 0; x < qrcode->width; x++) {
+			if ((*(row1 + x) & 1) && (*(row2 + x) & 1))
+				fputc(' ', fp);
+			else if (*(row1 + x) & 1)
+				fputs("\342\226\204", fp);
+			else if (*(row2 + x) & 1)
+				fputs("\342\226\200", fp);
+			else
+				fputs("\342\226\210", fp);
+		}
+
+		for (x = 0; x < margin; x++)
+			fputs("\342\226\210", fp);
+
+		fputs(reset, fp);
+		fputc('\n', fp);
+	}
+
+	/* bottom margin */
+	writeUTF8_margin(fp, realwidth, white, reset, use_ansi);
+
+	fclose(fp);
+
+	return 0;
+}
+
+static void writeASCII_margin(FILE* fp, int realwidth, char* buffer, int buffer_s, int invert)
+{
+	int y, h;
+
+	h = margin;
+
+	memset(buffer, (invert?'#':' '), realwidth);
+	buffer[realwidth] = '\n';
+	buffer[realwidth + 1] = '\0';
+	for(y=0; y<h; y++ ){
+		fputs(buffer, fp);
+	}
+}
+
+static int writeASCII(QRcode *qrcode, const char *outfile, int invert)
+{
+	FILE *fp;
+	unsigned char *row;
+	int x, y;
+	int realwidth;
+	char *buffer, *p;
+	int buffer_s;
+	char black = '#';
+	char white = ' ';
+
+	if(invert) {
+		black = ' ';
+		white = '#';
+	}
+
+	size = 1;
+
+	fp = openFile(outfile);
+
+	realwidth = (qrcode->width + margin * 2) * 2;
+	buffer_s = realwidth + 1;
+	buffer = (char *)malloc( buffer_s );
+	if(buffer == NULL) {
+		fprintf(stderr, "Failed to allocate memory.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	/* top margin */
+	writeASCII_margin(fp, realwidth, buffer, buffer_s, invert);
+
+	/* data */
+	for(y=0; y<qrcode->width; y++) {
+		row = qrcode->data+(y*qrcode->width);
+		p = buffer;
+
+		memset(p, white, margin * 2);
+		p += margin * 2;
+
+		for(x=0; x<qrcode->width; x++) {
+			if(row[x]&0x1) {
+				*p++ = black;
+				*p++ = black;
+			} else {
+				*p++ = white;
+				*p++ = white;
+			}
+		}
+
+		memset(p, white, margin * 2);
+		p += margin * 2;
+		*p++ = '\n';
+		*p++ = '\0';
+		fputs( buffer, fp );
+	}
+
+	/* bottom margin */
+	writeASCII_margin(fp, realwidth, buffer, buffer_s, invert);
+
+	fclose(fp);
+	free(buffer);
+
+	return 0;
+}
+
+static QRcode *encode(const unsigned char *intext, int length)
+{
+	QRcode *code;
+
+	if(micro) {
+		if(eightbit) {
+			code = QRcode_encodeDataMQR(length, intext, version, level);
+		} else {
+			code = QRcode_encodeStringMQR((char *)intext, version, level, hint, casesensitive);
+		}
+	} else {
+		if(eightbit) {
+			code = QRcode_encodeData(length, intext, version, level);
+		} else {
+			code = QRcode_encodeString((char *)intext, version, level, hint, casesensitive);
+		}
+	}
+
+	return code;
+}
+
+static void qrencode(const unsigned char *intext, int length, const char *outfile)
+{
+	QRcode *qrcode;
+	
+	qrcode = encode(intext, length);
+	if(qrcode == NULL) {
+		perror("Failed to encode the input data");
+		exit(EXIT_FAILURE);
+	}
+	switch(image_type) {
+		case PNG_TYPE:
+			writePNG(qrcode, outfile);
+			break;
+		case EPS_TYPE:
+			writeEPS(qrcode, outfile);
+			break;
+		case SVG_TYPE:
+			writeSVG(qrcode, outfile);
+			break;
+		case ANSI_TYPE:
+		case ANSI256_TYPE:
+			writeANSI(qrcode, outfile);
+			break;
+		case ASCIIi_TYPE:
+			writeASCII(qrcode, outfile,  1);
+			break;
+		case ASCII_TYPE:
+			writeASCII(qrcode, outfile,  0);
+			break;
+		case UTF8_TYPE:
+			writeUTF8(qrcode, outfile, 0);
+			break;
+		case ANSIUTF8_TYPE:
+			writeUTF8(qrcode, outfile, 1);
+			break;
+		default:
+			fprintf(stderr, "Unknown image type.\n");
+			exit(EXIT_FAILURE);
+	}
+	QRcode_free(qrcode);
+}
+
+static QRcode_List *encodeStructured(const unsigned char *intext, int length)
+{
+	QRcode_List *list;
+
+	if(eightbit) {
+		list = QRcode_encodeDataStructured(length, intext, version, level);
+	} else {
+		list = QRcode_encodeStringStructured((char *)intext, version, level, hint, casesensitive);
+	}
+
+	return list;
+}
+
+static void qrencodeStructured(const unsigned char *intext, int length, const char *outfile)
+{
+	QRcode_List *qrlist, *p;
+	char filename[FILENAME_MAX];
+	char *base, *q, *suffix = NULL;
+	const char *type_suffix;
+	int i = 1;
+	size_t suffix_size;
+
+	switch(image_type) {
+		case PNG_TYPE:
+			type_suffix = ".png";
+			break;
+		case EPS_TYPE:
+			type_suffix = ".eps";
+			break;
+		case SVG_TYPE:
+			type_suffix = ".svg";
+			break;
+		case ANSI_TYPE:
+		case ANSI256_TYPE:
+		case ASCII_TYPE:
+		case UTF8_TYPE:
+		case ANSIUTF8_TYPE:
+			type_suffix = ".txt";
+			break;
+		default:
+			fprintf(stderr, "Unknown image type.\n");
+			exit(EXIT_FAILURE);
+	}
+
+	if(outfile == NULL) {
+		fprintf(stderr, "An output filename must be specified to store the structured images.\n");
+		exit(EXIT_FAILURE);
+	}
+	base = strdup(outfile);
+	if(base == NULL) {
+		fprintf(stderr, "Failed to allocate memory.\n");
+		exit(EXIT_FAILURE);
+	}
+	suffix_size = strlen(type_suffix);
+	if(strlen(base) > suffix_size) {
+		q = base + strlen(base) - suffix_size;
+		if(strcasecmp(type_suffix, q) == 0) {
+			suffix = strdup(q);
+			*q = '\0';
+		}
+	}
+	
+	qrlist = encodeStructured(intext, length);
+	if(qrlist == NULL) {
+		perror("Failed to encode the input data");
+		exit(EXIT_FAILURE);
+	}
+
+	for(p = qrlist; p != NULL; p = p->next) {
+		if(p->code == NULL) {
+			fprintf(stderr, "Failed to encode the input data.\n");
+			exit(EXIT_FAILURE);
+		}
+		if(suffix) {
+			snprintf(filename, FILENAME_MAX, "%s-%02d%s", base, i, suffix);
+		} else {
+			snprintf(filename, FILENAME_MAX, "%s-%02d", base, i);
+		}
+		switch(image_type) {
+			case PNG_TYPE: 
+				writePNG(p->code, filename);
+				break;
+			case EPS_TYPE: 
+				writeEPS(p->code, filename);
+				break;
+			case SVG_TYPE: 
+				writeSVG(p->code, filename);
+				break;
+			case ANSI_TYPE:
+			case ANSI256_TYPE:
+				writeANSI(p->code, filename);
+				break;
+			case ASCIIi_TYPE:
+				writeASCII(p->code, filename, 1);
+				break;
+			case ASCII_TYPE:
+				writeASCII(p->code, filename, 0);
+				break;
+			case UTF8_TYPE:
+				writeUTF8(p->code, filename, 0);
+				break;
+			case ANSIUTF8_TYPE:
+				writeUTF8(p->code, filename, 0);
+				break;
+
+			default:
+				fprintf(stderr, "Unknown image type.\n");
+				exit(EXIT_FAILURE);
+		}
+		i++;
+	}
+
+	free(base);
+	if(suffix) {
+		free(suffix);
+	}
+
+	QRcode_List_free(qrlist);
+}
+
+#ifndef ZOO_SERVICE_PROVIDER
+int main(int argc, char **argv)
+#else
+	extern "C" {
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+int QREncode(maps*& conf, maps*& inputs, maps*& outputs)
+#endif
+{
+	int opt, lindex = -1;
+	char *outfile = NULL;
+	unsigned char *intext = NULL;
+	int length = 0;
+
+#ifndef ZOO_SERVICE_PROVIDER
+	while((opt = getopt_long(argc, argv, optstring, options, &lindex)) != -1) {
+		switch(opt) {
+			case 'h':
+				if(lindex == 0) {
+					usage(1, 1);
+				} else {
+					usage(1, 0);
+				}
+				exit(EXIT_SUCCESS);
+				break;
+			case 'o':
+				outfile = optarg;
+				break;
+			case 's':
+				size = atoi(optarg);
+				if(size <= 0) {
+					fprintf(stderr, "Invalid size: %d\n", size);
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'v':
+				version = atoi(optarg);
+				if(version < 0) {
+					fprintf(stderr, "Invalid version: %d\n", version);
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'l':
+				switch(*optarg) {
+					case 'l':
+					case 'L':
+						level = QR_ECLEVEL_L;
+						break;
+					case 'm':
+					case 'M':
+						level = QR_ECLEVEL_M;
+						break;
+					case 'q':
+					case 'Q':
+						level = QR_ECLEVEL_Q;
+						break;
+					case 'h':
+					case 'H':
+						level = QR_ECLEVEL_H;
+						break;
+					default:
+						fprintf(stderr, "Invalid level: %s\n", optarg);
+						exit(EXIT_FAILURE);
+						break;
+				}
+				break;
+			case 'm':
+				margin = atoi(optarg);
+				if(margin < 0) {
+					fprintf(stderr, "Invalid margin: %d\n", margin);
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'd':
+				dpi = atoi(optarg);
+				if( dpi < 0 ) {
+					fprintf(stderr, "Invalid DPI: %d\n", dpi);
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 't':
+				if(strcasecmp(optarg, "png") == 0) {
+					image_type = PNG_TYPE;
+				} else if(strcasecmp(optarg, "eps") == 0) {
+					image_type = EPS_TYPE;
+				} else if(strcasecmp(optarg, "svg") == 0) {
+					image_type = SVG_TYPE;
+				} else if(strcasecmp(optarg, "ansi") == 0) {
+					image_type = ANSI_TYPE;
+				} else if(strcasecmp(optarg, "ansi256") == 0) {
+					image_type = ANSI256_TYPE;
+				} else if(strcasecmp(optarg, "asciii") == 0) {
+					image_type = ASCIIi_TYPE;
+				} else if(strcasecmp(optarg, "ascii") == 0) {
+					image_type = ASCII_TYPE;
+				} else if(strcasecmp(optarg, "utf8") == 0) {
+					image_type = UTF8_TYPE;
+				} else if(strcasecmp(optarg, "ansiutf8") == 0) {
+					image_type = ANSIUTF8_TYPE;
+				} else {
+					fprintf(stderr, "Invalid image type: %s\n", optarg);
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'S':
+				structured = 1;
+			case 'k':
+				hint = QR_MODE_KANJI;
+				break;
+			case 'c':
+				casesensitive = 1;
+				break;
+			case 'i':
+				casesensitive = 0;
+				break;
+			case '8':
+				eightbit = 1;
+				break;
+			case 'M':
+				micro = 1;
+				break;
+			case 'f':
+				if(color_set(fg_color, optarg)) {
+					fprintf(stderr, "Invalid foreground color value.\n");
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'b':
+				if(color_set(bg_color, optarg)) {
+					fprintf(stderr, "Invalid background color value.\n");
+					exit(EXIT_FAILURE);
+				}
+				break;
+			case 'V':
+				usage(0, 0);
+				exit(EXIT_SUCCESS);
+				break;
+			default:
+				fprintf(stderr, "Try `qrencode --help' for more information.\n");
+				exit(EXIT_FAILURE);
+				break;
+		}
+	}
+
+	if(argc == 1) {
+		usage(1, 0);
+		exit(EXIT_SUCCESS);
+	}
+
+	if(outfile == NULL && image_type == PNG_TYPE) {
+		fprintf(stderr, "No output filename is given.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if(optind < argc) {
+		intext = (unsigned char *)argv[optind];
+		length = strlen((char *)intext);
+	}
+	if(intext == NULL) {
+		intext = readStdin(&length);
+	}
+#else
+	outfile=(char*)malloc(1024*sizeof(char));
+	map *tmpMap=getMapFromMaps(conf,"main","tmpPath");
+	sprintf(outfile,"%s/qr_%d.png",tmpMap->value,getpid());
+	tmpMap=getMapFromMaps(inputs,"Text","value");
+	intext=(unsigned char*)tmpMap->value;
+	dpi = 92;
+	level = QR_ECLEVEL_H;
+	map* tmp1=getMapFromMaps(inputs,"size","value");
+	if(tmp1!=NULL)
+		size = atoi(tmp1->value);
+	tmp1=getMapFromMaps(inputs,"bgcolor","value");
+	if(tmp1!=NULL && color_set(bg_color, tmp1->value)){
+		setMapInMaps(conf,"lenv","message","Unable to parse bgcolor settings");
+		return SERVICE_FAILED;
+	}
+	tmp1=getMapFromMaps(inputs,"fgcolor","value");
+	if(tmp1!=NULL && color_set(fg_color, tmp1->value)){
+		setMapInMaps(conf,"lenv","message","Unable to parse fgcolor settings");
+		return SERVICE_FAILED;
+	}
+#endif
+	
+	if(micro && version > MQRSPEC_VERSION_MAX) {
+		fprintf(stderr, "Version should be less or equal to %d.\n", MQRSPEC_VERSION_MAX);
+		exit(EXIT_FAILURE);
+	} else if(!micro && version > QRSPEC_VERSION_MAX) {
+		fprintf(stderr, "Version should be less or equal to %d.\n", QRSPEC_VERSION_MAX);
+		exit(EXIT_FAILURE);
+	}
+
+	if(margin < 0) {
+		if(micro) {
+			margin = 2;
+		} else {
+			margin = 4;
+		}
+	}
+
+	if(micro) {
+		if(version == 0) {
+			fprintf(stderr, "Version must be specified to encode a Micro QR Code symbol.\n");
+			exit(EXIT_FAILURE);
+		}
+		if(structured) {
+			fprintf(stderr, "Micro QR Code does not support structured symbols.\n");
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if(structured) {
+		if(version == 0) {
+			fprintf(stderr, "Version must be specified to encode structured symbols.\n");
+			exit(EXIT_FAILURE);
+		}
+		qrencodeStructured(intext, length, outfile);
+	} else {
+		qrencode(intext, length, outfile);
+	}
+
+#ifdef ZOO_SERVICE_PROVIDER
+	FILE * fichier=fopen(outfile,"rb");
+	fseek(fichier, 0, SEEK_END);
+	long count = ftell(fichier);
+	rewind(fichier);
+	
+	struct stat file_status;
+	stat(outfile, &file_status);
+	if(fichier==NULL){
+		fprintf(stderr,"Failed to open file %s for reading purpose.\n",outfile);
+		setMapInMaps(conf,"lenv","message","Unable to read produced file. Please try again later");
+		return SERVICE_FAILED;
+	}
+
+	maps* tmp=getMaps(outputs,"QR");
+	map* tmpMap1=getMapFromMaps(outputs,"QR","value");
+	if(tmpMap1==NULL){
+		addToMap(outputs->content,"value","null");
+		tmpMap1=getMapFromMaps(outputs,"QR","value");
+	}
+	free(tmpMap1->value);
+	tmpMap1->value=(char*) malloc((count+1)*sizeof(char));  
+	fread(tmpMap1->value,1,count*sizeof(char),fichier);
+	fclose(fichier);
+	unlink(outfile);
+
+	char rsize[100];
+	sprintf(rsize,"%d",count*sizeof(char));
+	addToMap(tmpMap1,"size",rsize);  
+	return SERVICE_SUCCEEDED;
+#endif
+
+	return 0;
+}
+#ifdef ZOO_SERVICE_PROVIDER
+	}
+#endif
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/Makefile
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/Makefile	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/Makefile	(revision 672)
@@ -0,0 +1,12 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+
+cgi-env/wps_status.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/wps_status.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} -lfcgi -lzoo_service
+
+install:
+	install -d ${CGI_DIR}
+	install cgi-env/* ${CGI_DIR}/
+clean:
+	rm -f cgi-env/wps_status.zo
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/GetStatus.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/GetStatus.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/GetStatus.zcfg	(revision 672)
@@ -0,0 +1,43 @@
+[GetStatus]
+ Title = Produce an updated ExecuteResponse document. 
+ Abstract = Create an ExecuteResponse document from a sid (Service ID), it will use the niternal ZOO Kernel mechanisms to access the current status from a running Service and update the percentCompleted from the original backup file used by the ZOO Kernel when running a Service in background. 
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_status.zo
+ serviceType = C
+ <MetaData>
+   title = Demo GetStatus request
+ </MetaData>
+ <DataInputs>
+  [sid]
+   Title = Service ID
+   Abstract = The ZOO Service ID of the ZOO Service we want to get the current status.
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = integer
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = ExecuteResponse document
+   Abstract = The resulting ExecuteResponse document.
+   <MetaData>
+    title = Demo XSL use case
+   </MetaData>   
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd
+    </Default>
+    <Supported>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/demo.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/demo.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/demo.zcfg	(revision 672)
@@ -0,0 +1,32 @@
+[demo]
+ Title = Demo long process. 
+ Abstract = This service doesn't do anything except taking its time to return an error message, it demonstrates how to use the update_status function of the Python ZOO-API from your services code.
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = service
+ serviceType = Python
+ <DataInputs>
+  [sid]
+   Title = Service ID
+   Abstract = A ZOO Service ID (unused).
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    dataType = integer
+    <Default />
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = ExecuteResponse document
+   Abstract = The resulting ExecuteResponse document.
+   <MetaData>
+    title = Demo XSL use case
+   </MetaData>   
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/longProcess.zcfg
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/longProcess.zcfg	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/longProcess.zcfg	(revision 672)
@@ -0,0 +1,36 @@
+[longProcess]
+ Title = Demo long process. 
+ Abstract = This service doesn't do anything except taking its time, it demonstrates how to use the updateStatus function from your ZOO Service. 
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_status.zo
+ serviceType = C
+ <MetaData>
+   title = Demo GetStatus request
+ </MetaData>
+ <DataInputs>
+  [sid]
+   Title = Service ID
+   Abstract = A ZOO Service ID (unused).
+   minOccurs = 0
+   maxOccurs = 1
+   <LiteralData>
+    dataType = integer
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = ExecuteResponse document
+   Abstract = The resulting ExecuteResponse document.
+   <MetaData>
+    title = Demo XSL use case
+   </MetaData>   
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataOutputs>  
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/service.py
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/service.py	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/service.py	(revision 672)
@@ -0,0 +1,14 @@
+def demo(conf,inputs,outputs):
+    import zoo,time
+    i=0
+    while i < 100:
+        conf["lenv"]["message"]="Step "+str(i)
+        zoo.update_status(conf,i)
+        time.sleep(0.5)
+        i+=1
+    conf["lenv"]["message"]=zoo._("Error executing the service")
+    return zoo.SERVICE_FAILED
+
+def demo1(conf,inputs,outputs):
+    conf["lenv"]["message"]=zoo._("Error executing the service")
+    return zoo.SERVICE_FAILED
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/updateStatus.xsl
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/updateStatus.xsl	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/cgi-env/updateStatus.xsl	(revision 672)
@@ -0,0 +1,26 @@
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:ows="http://www.opengis.net/ows/1.1"
+                xmlns:wps="http://www.opengis.net/wps/1.0.0"
+                xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:output method="xml"/>
+  <xsl:param name="value" select="string('-1')"/>
+  <xsl:param name="message" select="string('-1')"/>
+
+  <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="/wps:ExecuteResponse/wps:Status/wps:ProcessStarted">
+    <xsl:copy>
+      <xsl:attribute name="percentCompleted">
+	<xsl:value-of select="$value"/>
+      </xsl:attribute>
+      <xsl:value-of select="$message" />
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/fr_FR.utf8.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/fr_FR.utf8.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/fr_FR.utf8.po	(revision 672)
@@ -0,0 +1,91 @@
+# French translations for PACKAGE package.
+# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# root <gerald.fenoy@geolabs.fr>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: zoo-services\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-30 03:46+0200\n"
+"PO-Revision-Date: 2010-09-30 03:50+0200\n"
+"Last-Translator: root <gerald.fenoy@geolabs.fr>\n"
+"Language-Team: French\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: ../.cache/my_service_string_to_translate.c:1
+msgid "Produce an updated ExecuteResponse document. "
+msgstr ""
+"Produit un document ExecuteResponse à jour par rapport à l'exécution d'un service en "
+"tâche de fond."
+
+#: ../.cache/my_service_string_to_translate.c:2
+#: ../.cache/my_service_string_to_translate.c:8
+msgid "Service ID"
+msgstr "identifiant de service"
+
+#: ../.cache/my_service_string_to_translate.c:3
+#: ../.cache/my_service_string_to_translate.c:9
+msgid "ExecuteResponse document"
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:4
+msgid ""
+"Create an ExecuteResponse document from a sid (Service ID), it will use the "
+"niternal ZOO Kernel mechanisms to access the current status from a running "
+"Service and update the percentCompleted from the original backup file used "
+"by the ZOO Kernel when running a Service in background. "
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:5
+msgid ""
+"The ZOO Service ID of the ZOO Service we want to get the current status."
+msgstr ""
+"L'identifiant de Service ZOO dont ont veut obetnir le status."
+
+#: ../.cache/my_service_string_to_translate.c:6
+#: ../.cache/my_service_string_to_translate.c:12
+msgid "The resulting ExecuteResponse document."
+msgstr "Le document ExecuteResponse resultant."
+
+#: ../.cache/my_service_string_to_translate.c:7
+msgid "Demo long process. "
+msgstr "Service de démonstration."
+
+#: ../.cache/my_service_string_to_translate.c:10
+msgid ""
+"This service doesn't do anything except taking its time, it demonstrates how "
+"to use the updateStatus function from your ZOO Service. "
+msgstr ""
+"Ce service se contente de prendre son temps, il permet de montrer comment utiliser "
+"la fonction updateStatus depuis vos services ZOO."
+
+#: ../.cache/my_service_string_to_translate.c:11
+msgid "A ZOO Service ID (unused)."
+msgstr "Un identifiant de Service ZOO."
+
+#: ../.cache/my_service_string_to_translate.c:94
+#, c-format
+msgid ""
+"GetStatus was unable to use the tmpPath value set in main.cfg file as "
+"directory %s."
+msgstr ""
+"Le service GetStatus n'a pas été en mesure d'accéder au répertoire correspondant à la "
+"variable tmpPath définie dans le fichier main.cfg comme : %s."
+
+#: ../.cache/my_service_string_to_translate.c:100
+#, c-format
+msgid "GetStatus was unable to find any cache file for Service ID %s."
+msgstr "Le service GetStatus n'a pas été en mesure de trouver un fichier pour l'identifiant de Servicer ZOO %s."
+
+#: ../.cache/my_service_string_to_translate.c:126
+#, c-format
+msgid ""
+"ZOO GetStatus Service was unable to parse the cache xml file available for "
+"the Service ID %s."
+msgstr ""
+"Le Service ZOO GetStatus n'a pas été en mesure de charger le fichier xml pour "
+"l'identifiant %s."
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/messages.po
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/messages.po	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/locale/po/messages.po	(revision 672)
@@ -0,0 +1,82 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: zoo-services\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-09-30 03:46+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../.cache/my_service_string_to_translate.c:1
+msgid "Produce an updated ExecuteResponse document. "
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:2
+#: ../.cache/my_service_string_to_translate.c:8
+msgid "Service ID"
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:3
+#: ../.cache/my_service_string_to_translate.c:9
+msgid "ExecuteResponse document"
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:4
+msgid ""
+"Create an ExecuteResponse document from a sid (Service ID), it will use the "
+"niternal ZOO Kernel mechanisms to access the current status from a running "
+"Service and update the percentCompleted from the original backup file used "
+"by the ZOO Kernel when running a Service in background. "
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:5
+msgid ""
+"The ZOO Service ID of the ZOO Service we want to get the current status."
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:6
+#: ../.cache/my_service_string_to_translate.c:12
+msgid "The resulting ExecuteResponse document."
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:7
+msgid "Demo long process. "
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:10
+msgid ""
+"This service doesn't do anything except taking its time, it demonstrates how "
+"to use the updateStatus function from your ZOO Service. "
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:11
+msgid "A ZOO Service ID (unused)."
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:94
+#, c-format
+msgid ""
+"GetStatus was unable to use the tmpPath value set in main.cfg file as "
+"directory %s."
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:100
+#, c-format
+msgid "GetStatus was unable to find any cache file for Service ID %s."
+msgstr ""
+
+#: ../.cache/my_service_string_to_translate.c:126
+#, c-format
+msgid ""
+"ZOO GetStatus Service was unable to parse the cache xml file available for "
+"the Service ID %s."
+msgstr ""
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/makefile.vc
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/makefile.vc	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/makefile.vc	(revision 672)
@@ -0,0 +1,24 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/wps_status.zo: service.c
+	$(CPP) /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/wps_status.zo $(FILES) ./service.obj $(LDFLAGS) $(XSLT_DIR)\win32\bin.msvc\libxslt.lib /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\*_status.*
+	erase *.obj
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/service.c
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/service.c	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/service.c	(revision 672)
@@ -0,0 +1,156 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2008-2009 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service.h"
+#include "service_internal.h"
+
+extern "C" {
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+
+#include <dirent.h>
+
+  /**
+   * GetStatus ZOO Service :
+   * This service is used in the ZOO-Project to get information about Services
+   * running as background tasks. The service will first get the XML document 
+   * cached by the ZOO-Kernel before calling effectively the Service, then 
+   * will access the shared memory space created by the Kernel to extract the 
+   * current status of the running Service. Using a simple XSL file it will 
+   * finally produce the final ExecuteResponse including the updated 
+   * percentCompleted attribute of the ProcessStarted node of the cached
+   * document if any (so if the Service is currently running) else it will 
+   * return the final ExecuteResponse stored on the Server file system.
+   */
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int GetStatus(maps*& conf,maps*& inputs,maps*& outputs){
+    const char *params[4 + 1];
+    int xmlLoadExtDtdDefaultValue;
+    map* tmpMap=NULL,*tmpMmap=NULL, *tmpTmap=NULL;
+
+    tmpMap=getMapFromMaps(inputs,"sid","value");
+    tmpTmap=getMapFromMaps(conf,"main","tmpPath");
+    tmpMmap=getMapFromMaps(conf,"main","dataPath");
+    if(tmpMmap==NULL)
+      tmpMmap=tmpTmap;
+    xmlInitParser();
+    int hasFile=-1;
+    char xslFileName[1024];
+    char* mem=_getStatusFile(conf,tmpMap->value);
+    if(mem==NULL){
+      char tmp[1024];
+      snprintf(tmp,1024,_ss("GetStatus was unable to find any cache file for Service ID %s."),tmpMap->value);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return SERVICE_FAILED;
+    }
+    sprintf(xslFileName,"%s/updateStatus.xsl",tmpMmap->value);
+    xmlSubstituteEntitiesDefault(1);
+    xmlLoadExtDtdDefaultValue = 0;
+    xsltStylesheetPtr cur = NULL;
+    xmlDocPtr doc, res;
+    cur = xsltParseStylesheetFile(BAD_CAST xslFileName);
+    doc = xmlParseMemory(mem,strlen(mem));
+    //doc = xmlParseFile(fileName);
+    if(cur!=NULL && doc!=NULL){
+      /**
+       * Parse Status to extract Status / Message
+       */
+      char *tmpStr=_getStatus(conf,tmpMap->value);
+#ifdef DEBUG
+      fprintf(stderr,"DEBUG: %s \n",tmpStr);
+#endif
+      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
+	char *tmpStr1=strdup(tmpStr);
+	char *tmpStr0=strdup(strstr(tmpStr,"|")+1);
+	free(tmpStr);
+	tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
+	char *tmpStrFinal=(char*)malloc((strlen(tmpStr0)+11)*sizeof(char));
+	sprintf(tmpStrFinal,"string(\"%s\")",tmpStr0);
+	params[0]="value";
+	params[1]=tmpStr1;
+	params[2]="message";
+	params[3]=tmpStrFinal;
+	params[4]=NULL;
+	res = xsltApplyStylesheet(cur, doc, params);
+	xmlChar *xmlbuff;
+	int buffersize;
+	xmlDocDumpFormatMemory(res, &xmlbuff, &buffersize, 1);
+	setMapInMaps(outputs,"Result","value",(char*)xmlbuff);
+	xmlFree(xmlbuff);
+	free(tmpStr1);
+	free(tmpStr0);
+	free(tmpStrFinal);
+      }else{
+	xmlChar *xmlbuff;
+	int buffersize;
+	xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
+	setMapInMaps(outputs,"Result","value",(char*)xmlbuff);
+	xmlFree(xmlbuff);
+      }
+    }
+    else{
+      char tmp[1024];
+      sprintf(tmp,_ss("ZOO GetStatus Service was unable to parse the cache xml file available for the Service ID %s."),tmpMap->value);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return SERVICE_FAILED;
+    }
+    return SERVICE_SUCCEEDED;
+  }
+
+
+  /**
+   * longProcess ZOO Service :
+   * Simple Service which just loop over 100 times then return a welcome message
+   * string, at each step the service will sleep for one second.
+   */
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int longProcess(maps*& conf,maps*& inputs,maps*& outputs){
+    int i=0;
+    while(i<100){
+      char message[10];
+      sprintf(message,"Step %d",i);
+      updateStatus(conf,i,message);
+#ifndef WIN32
+      sleep(1);
+#else
+      Sleep(1000);
+#endif
+      i+=5;
+    }
+    setOutputValue(outputs,"Result",(char*)"\"Long process run successfully\"",-1);
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/test.sh
===================================================================
--- /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/test.sh	(revision 672)
+++ /branches/PublicaMundi_David_integration_01-devel/zoo-project/zoo-services/utils/status/test.sh	(revision 672)
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+rm -f log log1
+
+./zoo_loader.cgi "request=Execute&service=WPS&version=1.0.0&Identifier=longProcess&DataInputs=&storeExecuteResponse=true&status=true" > log
+
+if [ -z "$(grep "ows:ExceptionReport" log)" ]; then
+    while [ -z "$(grep "wps:ProcessSucceeded" log1)" ]; 
+    do 
+	./zoo_loader.cgi $(grep statusLocation= ./log | cut -d'?' -f2 | cut -d'"' -f1 | sed "s:amp;::g") > log1 ;
+	cat log1 ; 
+    done
+    cat log1
+else
+    echo "Service failed, please make sure that your main.cfg file contains"
+    echo "in the [main] section valid values for both tmpPath and dataPath."
+    echo 
+    cat log
+fi
