[magics] 01/07: upstream release 3.0.0

Alastair McKinstry mckinstry at moszumanska.debian.org
Wed Jan 3 12:58:13 UTC 2018


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

mckinstry pushed a commit to branch debian/master
in repository magics.

commit 81a9288d3d50e08616a5a510eb524b08c9817dc4
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Tue Dec 26 09:23:15 2017 +0000

    upstream release 3.0.0
---
 CMakeLists.txt                                     |   47 +-
 VERSION.cmake                                      |    3 +-
 cmake/FindAIO.cmake                                |   52 +-
 cmake/FindGd.cmake                                 |   59 +
 cmake/FindPangoCairo.cmake                         |   25 +-
 cmake/VERSION.cmake                                |    4 +-
 cmake/contrib/FindNetCDF4.cmake                    |    4 +-
 .../contrib/GreatCMakeCookOff/AddCPP11Flags.cmake  |   48 +-
 cmake/ecbuild_add_library.cmake                    |   62 +-
 cmake/ecbuild_add_test.cmake                       |   48 +-
 cmake/ecbuild_define_options.cmake                 |    6 +
 cmake/ecbuild_policies.cmake                       |   10 +-
 magics.sublime-project                             |    2 +-
 notebook/WCS.ipynb                                 |  156 -
 notebook/epsgrams.ipynb                            |  304 -
 python/CMakeLists.txt                              |   13 +-
 python/Magics.i.in                                 |   69 -
 python/Magics.py.in                                |  500 ++
 python/Magics/macro.py                             |  210 +-
 python/Magics/metgram.py                           |   47 +-
 python/Magics/toolbox.py                           |  475 +-
 python/Magics_interface.cc                         |  255 -
 python/numpy.i                                     | 1634 -----
 python/setup.py.in                                 |   18 -
 python/test_for_ctypes/array.py                    |   57 +
 python/test_for_ctypes/test_ctypes.py              |   28 +
 python/test_for_ctypes/test_ctypes_graph.py        |   58 +
 share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake     |   18 +-
 share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake      |    6 +
 share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake    |    6 +
 share/magics/cream/coastlines.json                 |   98 +-
 share/magics/dark/coastlines.json                  |  211 +-
 share/magics/dark/contours.json                    |  165 +-
 share/magics/epsg.json                             |    3 +-
 share/magics/netcdf-convention.json                |   18 +
 share/magics/palettes.json                         | 6719 ++++++++++++++++++++
 share/magics/table_128.xml                         |   36 -
 .../ObsCloud.xml => share/magics/table_228.xml     |   17 +-
 share/projections.json                             |  214 +
 src/CMakeLists.txt                                 |   97 +-
 src/basic/BasicGraphicsObject.h                    |    9 +-
 src/basic/FortranMagics.cc                         |   45 +-
 src/basic/FortranMagics.h                          |    2 +-
 src/basic/Layer.cc                                 |   98 +-
 src/basic/Layer.h                                  |   31 +-
 src/basic/LegendVisitor.cc                         |   71 +-
 src/basic/LegendVisitor.h                          |    9 +-
 src/basic/MagicsEvent.h                            |   37 +-
 src/basic/ViewNode.cc                              |   58 +-
 src/basic/ViewNode.h                               |    5 +-
 src/basic/VisualAction.cc                          |   14 +-
 src/boost/range/adaptor/adjacent_filtered.hpp      |  238 -
 src/boost/range/adaptor/argument_fwd.hpp           |   80 -
 src/boost/range/adaptor/copied.hpp                 |   58 -
 src/boost/range/adaptor/define_adaptor.hpp         |  109 -
 src/boost/range/adaptor/filtered.hpp               |  101 -
 src/boost/range/adaptor/indexed.hpp                |  156 -
 src/boost/range/adaptor/indirected.hpp             |   88 -
 src/boost/range/adaptor/map.hpp                    |  187 -
 src/boost/range/adaptor/replaced.hpp               |  134 -
 src/boost/range/adaptor/replaced_if.hpp            |  136 -
 src/boost/range/adaptor/reversed.hpp               |   90 -
 src/boost/range/adaptor/sliced.hpp                 |   82 -
 src/boost/range/adaptor/strided.hpp                |  350 -
 src/boost/range/adaptor/tokenized.hpp              |  137 -
 src/boost/range/adaptor/transformed.hpp            |  104 -
 src/boost/range/adaptor/type_erased.hpp            |  184 -
 src/boost/range/adaptor/uniqued.hpp                |   90 -
 src/boost/range/adaptors.hpp                       |   30 -
 src/boost/range/algorithm.hpp                      |  104 -
 src/boost/range/algorithm/adjacent_find.hpp        |  125 -
 src/boost/range/algorithm/binary_search.hpp        |   49 -
 src/boost/range/algorithm/copy.hpp                 |   41 -
 src/boost/range/algorithm/copy_backward.hpp        |   43 -
 src/boost/range/algorithm/count.hpp                |   50 -
 src/boost/range/algorithm/count_if.hpp             |   51 -
 src/boost/range/algorithm/equal.hpp                |  198 -
 src/boost/range/algorithm/equal_range.hpp          |   80 -
 src/boost/range/algorithm/fill.hpp                 |   49 -
 src/boost/range/algorithm/fill_n.hpp               |   53 -
 src/boost/range/algorithm/find.hpp                 |   80 -
 src/boost/range/algorithm/find_end.hpp             |  152 -
 src/boost/range/algorithm/find_first_of.hpp        |  155 -
 src/boost/range/algorithm/find_if.hpp              |   81 -
 src/boost/range/algorithm/for_each.hpp             |  109 -
 src/boost/range/algorithm/generate.hpp             |   49 -
 src/boost/range/algorithm/heap_algorithm.hpp       |  194 -
 src/boost/range/algorithm/inplace_merge.hpp        |   74 -
 .../range/algorithm/lexicographical_compare.hpp    |   58 -
 src/boost/range/algorithm/lower_bound.hpp          |  124 -
 src/boost/range/algorithm/max_element.hpp          |  115 -
 src/boost/range/algorithm/merge.hpp                |   61 -
 src/boost/range/algorithm/min_element.hpp          |  115 -
 src/boost/range/algorithm/mismatch.hpp             |  195 -
 src/boost/range/algorithm/nth_element.hpp          |   74 -
 src/boost/range/algorithm/partial_sort.hpp         |   76 -
 src/boost/range/algorithm/partial_sort_copy.hpp    |   82 -
 src/boost/range/algorithm/partition.hpp            |   74 -
 src/boost/range/algorithm/permutation.hpp          |  108 -
 src/boost/range/algorithm/random_shuffle.hpp       |   68 -
 src/boost/range/algorithm/remove.hpp               |   74 -
 src/boost/range/algorithm/remove_copy.hpp          |   44 -
 src/boost/range/algorithm/remove_copy_if.hpp       |   38 -
 src/boost/range/algorithm/remove_if.hpp            |   75 -
 src/boost/range/algorithm/replace.hpp              |   53 -
 src/boost/range/algorithm/replace_copy.hpp         |   42 -
 src/boost/range/algorithm/replace_copy_if.hpp      |   46 -
 src/boost/range/algorithm/replace_if.hpp           |   54 -
 src/boost/range/algorithm/reverse.hpp              |   50 -
 src/boost/range/algorithm/reverse_copy.hpp         |   40 -
 src/boost/range/algorithm/rotate.hpp               |   51 -
 src/boost/range/algorithm/rotate_copy.hpp          |   44 -
 src/boost/range/algorithm/search.hpp               |  134 -
 src/boost/range/algorithm/search_n.hpp             |  360 --
 src/boost/range/algorithm/set_algorithm.hpp        |  198 -
 src/boost/range/algorithm/sort.hpp                 |   68 -
 src/boost/range/algorithm/stable_partition.hpp     |   73 -
 src/boost/range/algorithm/stable_sort.hpp          |   68 -
 src/boost/range/algorithm/swap_ranges.hpp          |  132 -
 src/boost/range/algorithm/transform.hpp            |   97 -
 src/boost/range/algorithm/unique.hpp               |  107 -
 src/boost/range/algorithm/unique_copy.hpp          |   51 -
 src/boost/range/algorithm/upper_bound.hpp          |  127 -
 src/boost/range/algorithm_ext.hpp                  |   28 -
 src/boost/range/algorithm_ext/copy_n.hpp           |   53 -
 src/boost/range/algorithm_ext/erase.hpp            |   61 -
 src/boost/range/algorithm_ext/for_each.hpp         |   86 -
 src/boost/range/algorithm_ext/insert.hpp           |   42 -
 src/boost/range/algorithm_ext/iota.hpp             |   54 -
 src/boost/range/algorithm_ext/is_sorted.hpp        |   57 -
 src/boost/range/algorithm_ext/overwrite.hpp        |   84 -
 src/boost/range/algorithm_ext/push_back.hpp        |   40 -
 src/boost/range/algorithm_ext/push_front.hpp       |   40 -
 src/boost/range/any_range.hpp                      |  205 -
 src/boost/range/as_array.hpp                       |   45 -
 src/boost/range/as_literal.hpp                     |  127 -
 src/boost/range/atl.hpp                            |  733 ---
 src/boost/range/begin.hpp                          |  143 -
 src/boost/range/category.hpp                       |   29 -
 src/boost/range/combine.hpp                        |  304 -
 src/boost/range/concepts.hpp                       |  366 --
 src/boost/range/config.hpp                         |   54 -
 src/boost/range/const_iterator.hpp                 |   67 -
 src/boost/range/const_reverse_iterator.hpp         |   32 -
 src/boost/range/counting_range.hpp                 |   66 -
 src/boost/range/detail/any_iterator.hpp            |  586 --
 src/boost/range/detail/any_iterator_buffer.hpp     |  117 -
 src/boost/range/detail/any_iterator_interface.hpp  |  258 -
 src/boost/range/detail/any_iterator_wrapper.hpp    |  590 --
 src/boost/range/detail/as_literal.hpp              |   33 -
 src/boost/range/detail/begin.hpp                   |   94 -
 src/boost/range/detail/collection_traits.hpp       |  266 -
 .../range/detail/collection_traits_detail.hpp      |  621 --
 src/boost/range/detail/common.hpp                  |  117 -
 src/boost/range/detail/const_iterator.hpp          |   71 -
 .../range/detail/demote_iterator_traversal_tag.hpp |   91 -
 src/boost/range/detail/detail_str.hpp              |  376 --
 src/boost/range/detail/difference_type.hpp         |  121 -
 src/boost/range/detail/empty.hpp                   |  120 -
 src/boost/range/detail/end.hpp                     |  101 -
 src/boost/range/detail/extract_optional_type.hpp   |   52 -
 src/boost/range/detail/implementation_help.hpp     |  103 -
 src/boost/range/detail/iterator.hpp                |   78 -
 src/boost/range/detail/join_iterator.hpp           |  344 -
 src/boost/range/detail/microsoft.hpp               |  931 ---
 src/boost/range/detail/misc_concept.hpp            |   33 -
 src/boost/range/detail/range_return.hpp            |  180 -
 src/boost/range/detail/remove_extent.hpp           |  157 -
 src/boost/range/detail/safe_bool.hpp               |   72 -
 src/boost/range/detail/sfinae.hpp                  |   77 -
 src/boost/range/detail/size.hpp                    |  159 -
 src/boost/range/detail/size_type.hpp               |   55 -
 src/boost/range/detail/sizer.hpp                   |   35 -
 src/boost/range/detail/str_types.hpp               |   38 -
 src/boost/range/detail/value_type.hpp              |   72 -
 src/boost/range/detail/vc6/end.hpp                 |  170 -
 src/boost/range/detail/vc6/size.hpp                |  166 -
 src/boost/range/difference_type.hpp                |   29 -
 src/boost/range/distance.hpp                       |   34 -
 src/boost/range/empty.hpp                          |   34 -
 src/boost/range/end.hpp                            |  136 -
 src/boost/range/functions.hpp                      |   27 -
 src/boost/range/has_range_iterator.hpp             |   62 -
 src/boost/range/irange.hpp                         |  230 -
 src/boost/range/istream_range.hpp                  |   37 -
 src/boost/range/iterator.hpp                       |   72 -
 src/boost/range/iterator_range.hpp                 |   16 -
 src/boost/range/iterator_range_core.hpp            |  650 --
 src/boost/range/iterator_range_io.hpp              |   93 -
 src/boost/range/join.hpp                           |   91 -
 src/boost/range/metafunctions.hpp                  |   31 -
 src/boost/range/mfc.hpp                            |  984 ---
 src/boost/range/mutable_iterator.hpp               |   67 -
 src/boost/range/numeric.hpp                        |  118 -
 src/boost/range/pointer.hpp                        |   29 -
 src/boost/range/rbegin.hpp                         |   65 -
 src/boost/range/reference.hpp                      |   29 -
 src/boost/range/rend.hpp                           |   65 -
 src/boost/range/result_iterator.hpp                |   33 -
 src/boost/range/reverse_iterator.hpp               |   40 -
 src/boost/range/reverse_result_iterator.hpp        |   32 -
 src/boost/range/size.hpp                           |   52 -
 src/boost/range/size_type.hpp                      |   89 -
 src/boost/range/sub_range.hpp                      |  182 -
 src/boost/range/value_type.hpp                     |   34 -
 src/clipper/CMakeLists.txt                         |    9 +
 src/clipper/License.txt                            |   24 +
 src/clipper/README                                 |  413 ++
 src/clipper/clipper.cpp                            | 4629 ++++++++++++++
 src/clipper/clipper.hpp                            |  406 ++
 src/common/Colour.cc                               |    2 +-
 src/common/ColourTableDefinition.h                 |    2 +-
 src/common/ColourTableDefinitionCompute.cc         |    7 +-
 src/common/Coordinate.h                            |   19 +-
 src/common/Data.h                                  |    2 +-
 src/common/GeoRectangularProjection.cc             |    3 +-
 src/common/Layout.cc                               |    8 +-
 src/common/Layout.h                                |   17 +-
 src/common/MagicsCalls.cc                          |   46 +-
 src/common/MagicsFormat.cc                         |   31 +
 src/common/Matrix.cc                               |   31 +-
 src/common/Matrix.h                                |    4 +-
 src/common/MatrixHandler.h                         |  138 +-
 src/common/ParameterManager.h                      |   10 +-
 src/common/PointsHandler.cc                        |    1 +
 src/common/Proj4Projection.cc                      |   66 +-
 src/common/Proj4Projection.h                       |   10 +-
 src/common/Symbol.h                                |    2 +-
 src/common/Transformation.cc                       |   40 +-
 src/common/magics_api.h                            |    2 +-
 src/decoders/CMakeLists.txt                        |    4 +-
 src/decoders/GribDecoder.cc                        |   22 +-
 src/decoders/GribDecoder.h                         |    5 +-
 src/decoders/GribRegularInterpretor.cc             |   41 +-
 src/decoders/InputMatrix.cc                        |    4 +-
 src/decoders/InputMatrixInterpretor.cc             |    7 +
 src/decoders/Netcdf.cc                             |  321 -
 src/decoders/NetcdfData.cc                         |  433 ++
 src/decoders/{Netcdf.h => NetcdfData.h}            |  292 +-
 src/decoders/NetcdfDecoder.cc                      |   16 +-
 src/decoders/NetcdfDecoder.h                       |    3 +
 src/decoders/NetcdfGeoMatrixInterpretor.cc         |   71 +-
 src/decoders/NetcdfGeoMatrixInterpretor.h          |   21 +-
 src/decoders/NetcdfGeopointsInterpretor.cc         |   11 +-
 src/decoders/NetcdfGeopointsInterpretor.h          |   30 +-
 src/decoders/NetcdfInterpretor.cc                  |  119 +-
 src/decoders/NetcdfInterpretor.h                   |   70 +
 src/decoders/NetcdfMatrixInterpretor.cc            |   74 +-
 src/decoders/NetcdfMatrixInterpretor.h             |   24 +-
 src/decoders/NetcdfOrcaInterpretor.cc              |   10 +-
 src/decoders/NetcdfOrcaInterpretor.h               |   12 +-
 src/decoders/NetcdfVectorInterpretor.cc            |   34 +-
 src/decoders/NetcdfVectorInterpretor.h             |   63 +-
 src/decoders/ShapeDecoder.cc                       |   59 +-
 src/drivers/BaseDriver.cc                          |   89 +-
 src/drivers/CMakeLists.txt                         |   19 +-
 src/drivers/CairoDriver.cc                         |  111 +-
 src/drivers/CairoDriver.h                          |    8 +-
 src/drivers/GDDriver.cc                            |   54 +-
 src/drivers/GDDriver.h                             |    9 +-
 src/drivers/GeoJsonDriver.cc                       |   11 +-
 src/drivers/KMLDriver.cc                           |    6 +-
 src/drivers/MgQ/MgQLayerItem.cc                    |    3 +
 src/drivers/MgQ/MgQPlotScene.cc                    |    6 +-
 src/drivers/MgQ/MgQSceneItem.cc                    |   11 +-
 src/drivers/PostScriptDriver.cc                    |   72 +-
 src/drivers/QtDriver.cc                            |   43 +-
 src/drivers/SVGDriver.cc                           |    6 +-
 src/drivers/libimagequant/CHANGELOG                |  130 -
 src/drivers/libimagequant/COPYRIGHT                |   36 -
 src/drivers/libimagequant/MANUAL.md                |  511 --
 src/drivers/libimagequant/Makefile                 |   63 -
 src/drivers/libimagequant/blur.c                   |  119 -
 src/drivers/libimagequant/blur.h                   |    4 -
 src/drivers/libimagequant/configure                |  216 -
 src/drivers/libimagequant/libimagequant.c          | 1752 -----
 src/drivers/libimagequant/libimagequant.h          |  118 -
 src/drivers/libimagequant/mediancut.c              |  507 --
 src/drivers/libimagequant/mediancut.h              |    2 -
 src/drivers/libimagequant/mempool.c                |   68 -
 src/drivers/libimagequant/mempool.h                |   13 -
 src/drivers/libimagequant/nearest.c                |  193 -
 src/drivers/libimagequant/nearest.h                |    8 -
 src/drivers/libimagequant/pam.c                    |  273 -
 src/drivers/libimagequant/pam.h                    |  273 -
 src/drivers/libimagequant/pngquant.c               |  295 -
 src/drivers/libimagequant/pngquant.h               |   71 -
 src/drivers/libimagequant/rwpng.c                  |  620 --
 src/drivers/libimagequant/rwpng.h                  |  125 -
 src/drivers/libimagequant/viter.c                  |   96 -
 src/drivers/libimagequant/viter.h                  |   19 -
 src/libMagWrapper/MagPlus.cc                       |  101 +-
 src/libMagWrapper/MagPlus.h                        |    8 +
 src/params/AdvancedColourTechnique.xml             |   30 +
 src/params/Akima474Method.xml                      |    3 +-
 src/params/ArrowPlotting.xml                       |    3 +
 src/params/Axis.xml                                |    2 +-
 src/params/Bar.xml                                 |    2 +-
 src/params/BothValuePlotMethod.xml                 |    5 +
 src/params/Boundaries.xml                          |    2 +-
 src/params/CMakeLists.txt                          |   22 +-
 src/params/Cities.xml                              |    4 +
 src/params/FortranRootSceneNode.xml                |    2 +-
 src/params/FortranSceneNode.xml                    |    4 +-
 src/params/GradientsColourTechnique.xml            |   11 +-
 src/params/IsoPlot.xml                             |    6 +-
 src/params/IsoShading.xml                          |    3 +-
 src/params/NetcdfDecoder.xml                       |    5 +-
 src/params/NetcdfGeoMatrixInterpretor.xml          |   38 +-
 src/params/NetcdfGeoPolarMatrixInterpretor.xml     |   17 +-
 src/params/NetcdfGeoVectorInterpretor.xml          |   21 +-
 src/params/NetcdfGeopointsInterpretor.xml          |   11 +-
 .../{ObsCloud.xml => NetcdfGuessInterpretor.xml}   |    7 +-
 src/params/NetcdfInterpretor.xml                   |  149 +-
 src/params/NetcdfMatrixInterpretor.xml             |   31 +-
 src/params/NetcdfOrcaInterpretor.xml               |   25 +-
 src/params/NetcdfVectorInterpretor.xml             |   20 +-
 src/params/NetcdfXYpointsInterpretor.xml           |   24 +-
 src/params/ObsCloud.xml                            |    1 -
 src/params/PaletteColourTechnique.xml              |   37 +
 src/params/ValuePlotMethod.xml                     |    9 +
 src/visualisers/ArrowPlotting.cc                   |    7 +
 src/visualisers/AutomaticContourMethod.h           |   11 +-
 src/visualisers/Axis.cc                            |    6 +-
 src/visualisers/Bar.cc                             |    4 +-
 src/visualisers/BothValuePlotMethod.h              |   16 +-
 src/visualisers/CalcStreamlines.cc                 |   75 +-
 src/visualisers/CalmIndicator.h                    |    2 +-
 src/visualisers/CellShading.cc                     |   28 +-
 src/visualisers/Cities.cc                          |   21 +-
 src/visualisers/Coastlines.cc                      |   10 +-
 src/visualisers/ColourTechnique.cc                 |   27 +
 src/visualisers/ColourTechnique.h                  |   45 +-
 src/visualisers/Contour.cc                         |   30 +-
 src/visualisers/ContourLibrary.cc                  |   11 +-
 src/visualisers/ContourLibrary.h                   |    2 +-
 src/visualisers/EpsGraph.cc                        |    3 +-
 src/visualisers/FlagPlotting.cc                    |    2 +
 src/visualisers/GradientsColourTechnique.cc        |  184 +-
 src/visualisers/IsoPlot.cc                         |  143 +-
 src/visualisers/IsoShading.cc                      |    2 +-
 src/visualisers/IsoShading.h                       |   21 +-
 src/visualisers/LevelListSelectionType.cc          |    1 +
 src/visualisers/LevelListSelectionType.h           |    1 +
 src/visualisers/OriginMarker.h                     |   10 +-
 src/visualisers/PolyShadingTechnique.cc            |    7 +-
 src/visualisers/ShadingTechnique.h                 |    4 +-
 src/visualisers/Streamlines.cc                     |  208 +-
 src/visualisers/SymbolAdvancedTableMode.cc         |   14 +-
 src/visualisers/SymbolAdvancedTableMode.h          |   20 +-
 src/visualisers/SymbolMode.cc                      |    5 +
 src/visualisers/SymbolMode.h                       |    8 +-
 src/visualisers/SymbolPlotting.cc                  |    9 +-
 src/visualisers/ValuePlotMethod.h                  |   16 +-
 src/web/GeoJSon.cc                                 |   89 +-
 src/web/MagConfig.cc                               |  180 +-
 src/web/MagConfig.h                                |   97 +-
 test/bufr.py                                       |    2 +-
 test/cairo.py                                      |    2 +-
 test/grib.py                                       |    7 +-
 tools/RPM_build_specs/EmosLib.spec                 |  118 -
 tools/RPM_build_specs/emoslib/EmosLib.spec         |  155 -
 tools/RPM_build_specs/emoslib/generateRPM.sh       |   55 -
 tools/RPM_build_specs/grib_api/rpms/grib_api.spec  |   96 -
 tools/docs.json                                    | 6421 +++++++++++++++++++
 tools/docs.template                                |  161 +
 tools/header.template                              |   81 +
 tools/source.template                              |  162 +
 tools/x                                            |    1 -
 tools/xml2cc.py                                    |  186 +
 tools/xml2docs.py                                  |   73 +
 tools/xml2milana.json                              |    7 +
 tools/xml2milana.py                                |   11 +
 tools/xml2mv.py                                    |   40 +-
 374 files changed, 24476 insertions(+), 30461 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index af3263c..7f18b19 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,12 +11,6 @@
 #       -DCMAKE_PREFIX_PATH=/path/to/jasper:/path/to/any/package/out/of/place
 #       -DBUILD_SHARED_LIBS=OFF
 
-# TODO:
-#  * fix python module generation Magics.py to __init__.py
-#  * cpack ecbuild/cmake macros into tar.gz
-#  * unit tests check that certain files are produced and not empty
-#  * pkg-config needed for metview
-
 # Missing dependencies:
 #   * ghostscript ( is it really needed? -- to confirm )
 
@@ -39,8 +33,6 @@ ecbuild_requires_macro_version( 2.6 )
 ###############################################################################
 # some variables of this project
 
-ecbuild_add_option( FEATURE ECCODES DESCRIPTION "" DEFAULT ON )
-
 set(ECCODES_FAIL_MSG "Note: grib_api can be used instead (select with -DENABLE_ECCODES=OFF), "
                       "but we strongly advise you to upgrade to ecCodes. "
                       "See https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home\n"
@@ -80,7 +72,7 @@ ecbuild_add_option( FEATURE ODB
 ecbuild_add_option( FEATURE CAIRO
                     DEFAULT ON
                     DESCRIPTION "cairo support[png/jpeg]"
-                    REQUIRED_PACKAGES PangoCairo )
+                    REQUIRED_PACKAGES PangoCairo Pango PNG)
 
 ecbuild_add_option( FEATURE GEOTIFF
                     DEFAULT OFF
@@ -91,7 +83,7 @@ ecbuild_add_option( FEATURE GEOTIFF
 ecbuild_add_option( FEATURE NETCDF
                     DEFAULT ON
                     DESCRIPTION "enable netcdf support"
-                    REQUIRED_PACKAGES "NetCDF 4 COMPONENTS C CXX" )
+                    REQUIRED_PACKAGES "NetCDF 4 COMPONENTS C" )
 
 ecbuild_add_option( FEATURE SPOT
                     DEFAULT OFF
@@ -101,7 +93,7 @@ ecbuild_add_option( FEATURE SPOT
 ecbuild_add_option( FEATURE PYTHON
                     DEFAULT ON
                     DESCRIPTION "enable python interface"
-                    REQUIRED_PACKAGES "Python NO_LIBS" SWIG NumPy )
+                    REQUIRED_PACKAGES "Python NO_LIBS" NumPy )
 
 ecbuild_add_option( FEATURE FORTRAN
                     DEFAULT ON
@@ -120,18 +112,8 @@ ecbuild_add_option( FEATURE METVIEW_NO_QT
                     DESCRIPTION "enable Metview interface without Qt" )
 
 ecbuild_add_option( FEATURE QT5
-                    DEFAULT OFF
-                    DESCRIPTION "use Qt5 instead of version 4" )
-
-ecbuild_add_option( FEATURE PNG
-                    DESCRIPTION "support for PNG decoding/encoding"
                     DEFAULT ON
-                    REQUIRED_PACKAGES PNG
-)
-
-if( HAVE_PNG )
-    add_definitions( ${PNG_DEFINITIONS} )
-endif()
+                    DESCRIPTION "use Qt5 instead of version 4" )
 
 option( BUILD_SHARED_LIBS  "Set to BOTH to build static library in addition to shared"  ON )
 option( ENABLE_REGRESSION        "Internal use only: enable regression test"  OFF  )
@@ -188,13 +170,13 @@ if( HAVE_METVIEW )
       else()
           ecbuild_critical("Qt5 was NOT found ...")
       endif()
-    else()
-    find_package(Qt4 4.4.3 REQUIRED QtCore QtGui QtXml )
-    if( QT_FOUND )
-		  include( ${QT_USE_FILE} )
-		  set( MAGICS_QT 1)
-		  set( qt yes)
-    endif()
+    else( HAVE_QT5 )
+      find_package(Qt4 4.6.2 REQUIRED QtCore QtGui QtXml )
+      if( QT_FOUND )
+		    include( ${QT_USE_FILE} )
+		    set( MAGICS_QT 1)
+		    set( qt yes)
+      endif()
     endif()
 endif()
 
@@ -211,14 +193,14 @@ find_package( Threads )
 # set(Boost_USE_MULTITHREADED      ON)
 #ecbuild_add_extra_search_paths( boost )
 
-find_package( Boost 1.49.0 REQUIRED)
+find_package( Boost 1.53.0 REQUIRED)
 find_package( Proj4 REQUIRED )
 find_package( EXPAT REQUIRED )
 
 ###############################################################################
 # contents
 
-set( MAGICS_TPLS grib_api spot EXPAT NetCDF PNG Proj4 libemos )
+set( MAGICS_TPLS grib_api spot EXPAT NetCDF Proj4 libemos )
 
 set( MAGICS_INCLUDE_DIRS
      ${CMAKE_CURRENT_SOURCE_DIR}/src
@@ -240,7 +222,7 @@ set( MAGICS_INCLUDE_DIRS
      ${Boost_INCLUDE_DIRS} )
 
 if( HAVE_CAIRO )
-  list( APPEND MAGICS_TPLS PangoCairo )
+  list( APPEND MAGICS_TPLS PangoCairo PNG PANGO)
   list( APPEND MAGICS_INCLUDE_DIRS ${PANGOCAIRO_INCLUDE_DIRS} )
 endif()
 
@@ -330,6 +312,7 @@ ecbuild_add_resources( TARGET old_ressources
 		regression
 		docs
 		toolsjs
+		notebook
 		test/old
 		tools/xml
 		tools/use_scripts
diff --git a/VERSION.cmake b/VERSION.cmake
index 1e17ff8..2cd05b5 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -6,7 +6,8 @@
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
-set ( metabuilder_version 2.34.3 )
+set ( metabuilder_version 3.0.0 )
+set ( _version 3.0.0 )
 
 if ( MAGICS_BUILD )
   set( ${PROJECT_NAME}_VERSION_STR  "${metabuilder_version}-${MAGICS_BUILD}" )
diff --git a/cmake/FindAIO.cmake b/cmake/FindAIO.cmake
index 5dd9244..5606529 100644
--- a/cmake/FindAIO.cmake
+++ b/cmake/FindAIO.cmake
@@ -1,8 +1,8 @@
 # (C) Copyright 1996-2017 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
@@ -32,34 +32,38 @@ if( AIO_FOUND )
 
 	include( CheckCSourceCompiles )
 	include( CMakePushCheckState )
-    
+
     cmake_push_check_state()
-    
+
 		set( CMAKE_REQUIRED_INCLUDES ${AIO_INCLUDE_DIRS} )
 
 		if( AIO_LIBRARIES )
 			set( CMAKE_REQUIRED_LIBRARIES ${AIO_LIBRARIES} )
 		endif()
 
-		check_c_source_compiles( "#include <aio.h>
-								  #include <fcntl.h>
-								  int main(){
-									  struct aiocb* aiocbp;
-									  int n = aio_write(aiocbp);
-									  n = aio_read(aiocbp);
-									  n = aio_fsync(O_SYNC,aiocbp);
-									  return 0; }"
-								EC_HAVE_AIOCB )
-
-		check_c_source_compiles( "#include <aio.h>
-								  #include <fcntl.h>
-								  int main(){
-									  struct aiocb64* aiocbp;
-									  int n = aio_write64(aiocbp);
-									  n = aio_read64(aiocbp);
-									  n = aio_fsync64(O_SYNC,aiocbp);
-									  return 0; }"
-								EC_HAVE_AIOCB64 )
+		if( NOT DEFINED EC_HAVE_AIOCB )
+			ecbuild_cache_check_c_source_compiles( "#include <aio.h>
+									  #include <fcntl.h>
+									  int main(){
+										  struct aiocb* aiocbp;
+										  int n = aio_write(aiocbp);
+										  n = aio_read(aiocbp);
+										  n = aio_fsync(O_SYNC,aiocbp);
+										  return 0; }"
+									EC_HAVE_AIOCB )
+		endif()
+
+		if( NOT DEFINED EC_HAVE_AIOCB64 )
+			check_c_source_compiles( "#include <aio.h>
+									  #include <fcntl.h>
+									  int main(){
+										  struct aiocb64* aiocbp;
+										  int n = aio_write64(aiocbp);
+										  n = aio_read64(aiocbp);
+										  n = aio_fsync64(O_SYNC,aiocbp);
+										  return 0; }"
+									EC_HAVE_AIOCB64 )
+		endif()
 
     cmake_pop_check_state()
 
diff --git a/cmake/FindGd.cmake b/cmake/FindGd.cmake
new file mode 100644
index 0000000..01b2586
--- /dev/null
+++ b/cmake/FindGd.cmake
@@ -0,0 +1,59 @@
+# - Try to find the GD library
+# Once done this will define
+#
+# GD_FOUND - system has GD
+# GD_INCLUDE_DIRS - the GD include directory
+# GD_LIBRARIES - Link these to use GD
+#
+# Define GD_MIN_VERSION for which version desired.
+
+
+if( NOT DEFINED GD_PATH AND NOT "$ENV{GD_PATH}" STREQUAL "" )
+    set( APPEND GD_PATH "$ENV{GD_PATH}" )
+endif()
+
+if( NOT DEFINED GD_PATH )
+
+    include(FindPkgConfig)
+
+    if(GD_FIND_REQUIRED)
+        set(_pkgconfig_REQUIRED "REQUIRED")
+    else()
+        set(_pkgconfig_REQUIRED "")
+    endif()
+
+    if(GD_MIN_VERSION)
+        pkg_check_modules(PKGD ${_pkgconfig_REQUIRED} GD>=${GD_MIN_VERSION})
+    else()
+        pkg_check_modules(PKGD ${_pkgconfig_REQUIRED} GD)
+    endif()
+
+    if( PKG_CONFIG_FOUND AND PKGD_FOUND )
+
+        find_path(GD_INCLUDE_DIR gd.h HINTS ${PKGD_INCLUDEDIR} ${PKGD_INCLUDE_DIRS} PATH_SUFFIXES GD NO_DEFAULT_PATH )
+        find_library(GD_LIBRARY  gd   HINTS ${PKGD_LIBDIR}     ${PKGD_LIBRARY_DIRS} PATH_SUFFIXES GD NO_DEFAULT_PATH )
+
+    endif()
+
+else()
+
+    find_path(GD_INCLUDE_DIR gd.h PATHS ${GD_PATH}/include PATH_SUFFIXES GD NO_DEFAULT_PATH )
+    find_library(GD_LIBRARY  gd   PATHS ${GD_PATH}/lib     PATH_SUFFIXES GD NO_DEFAULT_PATH )
+
+endif()
+
+find_path(GD_INCLUDE_DIR gd.h PATH_SUFFIXES GD )
+find_library( GD_LIBRARY gd   PATH_SUFFIXES GD )
+
+set( GD_LIBRARIES    ${GD_LIBRARY} )
+set( GD_INCLUDE_DIRS ${GD_INCLUDE_DIR} )
+
+include(FindPackageHandleStandardArgs)
+
+# handle the QUIET and REQUIRED arguments and set GD_FOUND to TRUE
+# if all listed variables are TRUE
+# Note: capitalisation of the package name must be the same as in the file name
+find_package_handle_standard_args(GD  DEFAULT_MSG
+                                  GD_LIBRARY GD_INCLUDE_DIR)
+
+mark_as_advanced( GD_INCLUDE_DIR GD_LIBRARY )
diff --git a/cmake/FindPangoCairo.cmake b/cmake/FindPangoCairo.cmake
index cb70737..15e2da4 100644
--- a/cmake/FindPangoCairo.cmake
+++ b/cmake/FindPangoCairo.cmake
@@ -3,8 +3,8 @@
 # This software is licensed under the terms of the Apache Licence Version 2.0
 # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 # In applying this licence, ECMWF does not waive the privileges and immunities
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
 
 # - Try to find PangoCairo
 
@@ -40,8 +40,6 @@ else()
 
     # this is to get magics compiling on mac with macbrew
 
-    include(FindPackageHandleStandardArgs)
-
     set(PANGO_VERSION 1.0)
     set(GLIB_VERSION 2.0)
 
@@ -69,7 +67,7 @@ else()
         ${_CAIRO_INCLUDE_DIRS}
         ${_GLIB_INCLUDE_DIRS_1}
         ${_GLIB_INCLUDE_DIRS_2}
-	${X11_INCLUDE_DIR}
+        ${X11_INCLUDE_DIR}
     )
 
     find_library( _PANGOCAIRO_LIBRARIES NAMES pangocairo pangocairo-${PANGO_VERSION})
@@ -82,15 +80,26 @@ else()
         ${_PANGO_LIBRARIES}
         ${_CAIRO_LIBRARIES}
         ${_GLIB_LIBRARIES}
-	${X11_LIBRARIES}
+        ${X11_LIBRARIES}
     )
 
+    include(FindPackageHandleStandardArgs)
+
     # Handle the QUIET and REQUIRED arguments and set PANGOCAIRO_FOUND to TRUE
     # if all listed variables are TRUE
     # Note: capitalisation of the package name must be the same as in file name
     find_package_handle_standard_args( PangoCairo  DEFAULT_MSG
-                                       PANGOCAIRO_LIBRARIES
-                                       PANGOCAIRO_INCLUDE_DIRS  )
+                                       _PANGOCAIRO_INCLUDE_DIRS
+                                       _CAIRO_INCLUDE_DIRS
+                                       _GLIB_INCLUDE_DIRS_1
+                                       _GLIB_INCLUDE_DIRS_2
+                                       X11_INCLUDE_DIR
+                                       _PANGOCAIRO_LIBRARIES
+                                       _PANGO_LIBRARIES
+                                       _CAIRO_LIBRARIES
+                                       _GLIB_LIBRARIES
+                                       X11_LIBRARIES )
 
 endif()
 
+mark_as_advanced( PANGOCAIRO_INCLUDE_DIRS PANGOCAIRO_LIBRARIES )
diff --git a/cmake/VERSION.cmake b/cmake/VERSION.cmake
index af2b0d2..3b36296 100644
--- a/cmake/VERSION.cmake
+++ b/cmake/VERSION.cmake
@@ -1,7 +1,7 @@
 set( ECBUILD_MAJOR_VERSION "2" )
 set( ECBUILD_MINOR_VERSION "7" )
-set( ECBUILD_PATCH_VERSION "1" )
+set( ECBUILD_PATCH_VERSION "3" )
 
-set( ECBUILD_VERSION_STR  "2.7.1" )
+set( ECBUILD_VERSION_STR  "2.7.3" )
 
 set( ECBUILD_MACRO_VERSION "${ECBUILD_VERSION_STR}" )
diff --git a/cmake/contrib/FindNetCDF4.cmake b/cmake/contrib/FindNetCDF4.cmake
index 70e54af..d050f01 100644
--- a/cmake/contrib/FindNetCDF4.cmake
+++ b/cmake/contrib/FindNetCDF4.cmake
@@ -195,15 +195,13 @@ else()
             list( APPEND NETCDF_INCLUDE_DIRS ${NETCDF_${INC}_INCLUDE_DIR} )
           else()
             list( FIND NETCDF_REQUIRED ${INC} location )
-            if( ${location} EQUAL -1 )
-              else()
+            if( ${location} GREATER -1 )
               if(NETCDF_FIND_REQUIRED)
                 ecbuild_error( "\"${INC}\" is not found for NetCDF component ${LANGUAGE}" )
               elseif( NOT NETCDF_FIND_QUIETLY )
                 message( STATUS "\"${INC}\" is not found for NetCDF component ${LANGUAGE}" )
               endif()
               set( NETCDF_${LANGUAGE}_FOUND 0 )
-            else()
             endif()
           endif()
         endforeach()
diff --git a/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake b/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
index ac7f456..eb17be5 100644
--- a/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
+++ b/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
@@ -27,24 +27,36 @@ if(CMAKE_VERSION VERSION_LESS 2.8.9)
   endmacro ()
 endif(CMAKE_VERSION VERSION_LESS 2.8.9)
 
-check_cxx_compiler_flag(-std=c++11 has_std_cpp11)
-check_cxx_compiler_flag(-std=c++0x has_std_cpp0x)
-check_cxx_compiler_flag(-hstd=c++11 has_hstd_cpp11)
-if(MINGW) 
-  check_cxx_compiler_flag(-std=gnu++11 has_std_gnupp11)
-  check_cxx_compiler_flag(-std=gnu++0x has_std_gnupp0x)
-endif(MINGW)
-if(has_std_gnupp11)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
-elseif(has_std_gnupp0x)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
-elseif(has_std_cpp11)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-elseif(has_std_cpp0x)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
-elseif(has_hstd_cpp11)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -hstd=c++11")
-endif(has_std_gnupp11)
+if( CXX11_FLAG )
+
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG}")
+
+else()
+
+  if(MINGW)
+    LIST( APPEND CHECK_CXX11_FLAGS
+      "-std=gnu++11"
+      "-std=gnu++0x"
+    )
+  endif(MINGW)
+
+  LIST( APPEND CHECK_CXX11_FLAGS
+    "-std=c++11"
+    "-hstd=c++11"
+    "-std=c++0x"
+  )
+
+  set( __N 1 )
+  foreach( _cxx11_flag ${CHECK_CXX11_FLAGS} )
+    check_cxx_compiler_flag( ${_cxx11_flag} has_cxx11_flag_${__N} )
+    if( has_cxx11_flag_${__N} )
+      set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_cxx11_flag}" )
+      break()
+    endif()
+    math( EXPR __N '${__N}+1' )
+  endforeach()
+
+endif()
 
 if(MSVC) 
   set(MSWINDOBE TRUE)
diff --git a/cmake/ecbuild_add_library.cmake b/cmake/ecbuild_add_library.cmake
index f9f567f..e267333 100644
--- a/cmake/ecbuild_add_library.cmake
+++ b/cmake/ecbuild_add_library.cmake
@@ -298,7 +298,11 @@ function( ecbuild_add_library_impl )
       list(REMOVE_ITEM _PAR_LIBS optimized)
       foreach( lib ${_PAR_LIBS} ) # skip NOTFOUND
         if( lib )
-          ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): linking with ${lib}")
+
+          string(REGEX REPLACE "[ ]+$" "" ${lib} "${${lib}}") # strips leading whitespaces
+          string(REGEX REPLACE "^[ ]+" "" ${lib} "${${lib}}") # strips trailing whitespaces
+
+          ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): linking with [${lib}]")
           target_link_libraries( ${_PAR_TARGET} ${lib} )
         else()
           ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): ${lib} not found - not linking")
@@ -445,41 +449,45 @@ function( ecbuild_add_library_impl )
         set( _h_destination "${INSTALL_INCLUDE_DIR}" )
       endif()
 
-      if( _PAR_INSTALL_HEADERS )
-        if( _PAR_INSTALL_HEADERS MATCHES "LISTED" )
-          foreach( file ${${_PAR_TARGET}_h_srcs} )
-            get_filename_component( _file_dir ${file} PATH )
-            install( FILES ${file} DESTINATION "${_h_destination}/${_file_dir}" )
-          endforeach()
-          if( DEFINED _PAR_TEMPLATES )
-            foreach( file ${_PAR_TEMPLATES} )
+      if(ECBUILD_INSTALL_LIBRARY_HEADERS)
+
+        if( _PAR_INSTALL_HEADERS )
+          if( _PAR_INSTALL_HEADERS MATCHES "LISTED" )
+            foreach( file ${${_PAR_TARGET}_h_srcs} )
               get_filename_component( _file_dir ${file} PATH )
               install( FILES ${file} DESTINATION "${_h_destination}/${_file_dir}" )
             endforeach()
+            if( DEFINED _PAR_TEMPLATES )
+              foreach( file ${_PAR_TEMPLATES} )
+                get_filename_component( _file_dir ${file} PATH )
+                install( FILES ${file} DESTINATION "${_h_destination}/${_file_dir}" )
+              endforeach()
+            endif()
+            if( DEFINED _PAR_PERSISTENT )
+              foreach( file ${_PAR_PERSISTENT} )
+                get_filename_component( _file_dir ${file} PATH )
+                get_filename_component( _file_we  ${file} NAME_WE )
+                set( pfile "${CMAKE_CURRENT_BINARY_DIR}/${_file_dir}/${_file_we}.b" )
+                install( FILES ${pfile} DESTINATION "${_h_destination}/${_file_dir}" )
+              endforeach()
+            endif()
           endif()
-          if( DEFINED _PAR_PERSISTENT )
-            foreach( file ${_PAR_PERSISTENT} )
-              get_filename_component( _file_dir ${file} PATH )
-              get_filename_component( _file_we  ${file} NAME_WE )
-              set( pfile "${CMAKE_CURRENT_BINARY_DIR}/${_file_dir}/${_file_we}.b" )
-              install( FILES ${pfile} DESTINATION "${_h_destination}/${_file_dir}" )
-            endforeach()
+          if( _PAR_INSTALL_HEADERS MATCHES "ALL" ) # "(\\.h|\\.b|\\.hxx|\\.hh|\\.hpp|\\.H)" ????
+            install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.h" )
+            install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.hh" )
+            install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.hpp" )
+            install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.H" )
           endif()
         endif()
-        if( _PAR_INSTALL_HEADERS MATCHES "ALL" ) # "(\\.h|\\.b|\\.hxx|\\.hh|\\.hpp|\\.H)" ????
-          install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.h" )
-          install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.hh" )
-          install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.hpp" )
-          install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "*.H" )
+
+        if( DEFINED _PAR_INSTALL_HEADERS_LIST )
+          install( FILES ${_PAR_INSTALL_HEADERS_LIST} DESTINATION ${_h_destination} )
         endif()
-      endif()
 
-      if( DEFINED _PAR_INSTALL_HEADERS_LIST )
-        install( FILES ${_PAR_INSTALL_HEADERS_LIST} DESTINATION ${_h_destination} )
-      endif()
+        if( DEFINED _PAR_INSTALL_HEADERS_REGEX )
+          install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "${_PAR_INSTALL_HEADERS_REGEX}")
+        endif()
 
-      if( DEFINED _PAR_INSTALL_HEADERS_REGEX )
-        install( DIRECTORY ./  DESTINATION ${_h_destination} FILES_MATCHING PATTERN "${_PAR_INSTALL_HEADERS_REGEX}")
       endif()
 
       # set build location
diff --git a/cmake/ecbuild_add_test.cmake b/cmake/ecbuild_add_test.cmake
index da0bd22..7050159 100644
--- a/cmake/ecbuild_add_test.cmake
+++ b/cmake/ecbuild_add_test.cmake
@@ -224,30 +224,6 @@ macro( ecbuild_add_test )
     endif()
   endif()
 
-  if( _PAR_TYPE MATCHES "PYTHON" )
-    if( PYTHONINTERP_FOUND )
-      set( _PAR_COMMAND ${PYTHON_EXECUTABLE} )
-      set( _PAR_LABELS python ${_PAR_LABELS} )
-    else()
-      ecbuild_warn( "Requested a python test but python interpreter not found - disabling test\nPYTHON_EXECUTABLE: [${PYTHON_EXECUTABLE}]" )
-      set( _PAR_ENABLED 0 )
-    endif()
-  endif()
-
-  ### further checks
-
-  if( _PAR_ENABLED AND NOT _PAR_TARGET AND NOT _PAR_COMMAND )
-    ecbuild_critical("The call to ecbuild_add_test() defines neither a TARGET nor a COMMAND.")
-  endif()
-
-  if( _PAR_ENABLED AND NOT _PAR_COMMAND AND NOT _PAR_SOURCES )
-    ecbuild_critical("The call to ecbuild_add_test() defines neither a COMMAND nor SOURCES, so no test can be defined or built.")
-  endif()
-
-  if( _PAR_TYPE MATCHES "SCRIPT" AND NOT _PAR_COMMAND )
-    ecbuild_critical("The call to ecbuild_add_test() defines a 'script' but doesn't specify the COMMAND.")
-  endif()
-
   ### conditional build
 
   if( DEFINED _PAR_CONDITION )
@@ -285,6 +261,30 @@ macro( ecbuild_add_test )
 
   if( ENABLE_TESTS AND _${_PAR_TARGET}_condition )
 
+    if( _PAR_TYPE MATCHES "PYTHON" )
+      if( PYTHONINTERP_FOUND )
+        set( _PAR_COMMAND ${PYTHON_EXECUTABLE} )
+        set( _PAR_LABELS python ${_PAR_LABELS} )
+      else()
+        ecbuild_warn( "Requested a python test but python interpreter not found - disabling test\nPYTHON_EXECUTABLE: [${PYTHON_EXECUTABLE}]" )
+        set( _PAR_ENABLED 0 )
+      endif()
+    endif()
+
+    ### further checks
+
+    if( _PAR_ENABLED AND NOT _PAR_TARGET AND NOT _PAR_COMMAND )
+      ecbuild_critical("The call to ecbuild_add_test() defines neither a TARGET nor a COMMAND.")
+    endif()
+
+    if( _PAR_ENABLED AND NOT _PAR_COMMAND AND NOT _PAR_SOURCES )
+      ecbuild_critical("The call to ecbuild_add_test() defines neither a COMMAND nor SOURCES, so no test can be defined or built.")
+    endif()
+
+    if( _PAR_TYPE MATCHES "SCRIPT" AND NOT _PAR_COMMAND )
+      ecbuild_critical("The call to ecbuild_add_test() defines a 'script' but doesn't specify the COMMAND.")
+    endif()
+
     # add resources
 
     if( DEFINED _PAR_RESOURCES )
diff --git a/cmake/ecbuild_define_options.cmake b/cmake/ecbuild_define_options.cmake
index fc6376e..cf5ff00 100644
--- a/cmake/ecbuild_define_options.cmake
+++ b/cmake/ecbuild_define_options.cmake
@@ -33,6 +33,12 @@ option( CHECK_UNUSED_FILES       "check for unused project files (slow)"  OFF )
 mark_as_advanced( DEVELOPER_MODE  )
 mark_as_advanced( CHECK_UNUSED_FILES  )
 
+option( ECBUILD_INSTALL_LIBRARY_HEADERS "Will install library headers" ON )
+mark_as_advanced( ECBUILD_INSTALL_LIBRARY_HEADERS )
+
+option( ECBUILD_INSTALL_FORTRAN_MODULES "Will install Fortran modules" ON )
+mark_as_advanced( ECBUILD_INSTALL_FORTRAN_MODULES )
+
 include( CMakeDependentOption ) # make options depend on one another
 
 cmake_dependent_option( ENABLE_OS_TYPES_TEST     "Run sizeof tests on C types" ON "ENABLE_OS_TESTS" OFF)
diff --git a/cmake/ecbuild_policies.cmake b/cmake/ecbuild_policies.cmake
index df2b40f..e24c435 100644
--- a/cmake/ecbuild_policies.cmake
+++ b/cmake/ecbuild_policies.cmake
@@ -18,9 +18,9 @@
 #
 ##############################################################################
 
-# allow for empty spaces around library names 
+# fail if empty spaces are found around linked library names
 if( POLICY CMP0004 )
-    cmake_policy( SET CMP0004 OLD )
+    cmake_policy( SET CMP0004 NEW )
 endif()
 
 # Allow use of the LOCATION target property.
@@ -65,3 +65,9 @@ endif()
 if( POLICY CMP0054 )
     cmake_policy( SET CMP0054 NEW )
 endif()
+
+# RPATH settings on macOS do not affect "install_name"
+# FTM, keep old behavior -- need to test if new behavior impacts binaries in build directory
+if( POLICY CMP0068 )
+    cmake_policy( SET CMP0068 OLD )
+endif()
diff --git a/magics.sublime-project b/magics.sublime-project
index 30407a8..07b95f2 100644
--- a/magics.sublime-project
+++ b/magics.sublime-project
@@ -7,7 +7,7 @@
     ], 
     "build_systems": [
         {
-            "working_dir": "${project_path}/../../build/magics-develop/debug", 
+            "working_dir": "${project_path}/../../build/magics/debug", 
             "cmd": [
                 "make"
             ], 
diff --git a/notebook/WCS.ipynb b/notebook/WCS.ipynb
deleted file mode 100644
index 6b51541..0000000
--- a/notebook/WCS.ipynb
+++ /dev/null
@@ -1,156 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "# Load required libraries\n",
-    "\n",
-    "import requests\n",
-    "import numpy as np\n",
-    "import os\n",
-    "\n",
-    "from Magics import toolbox as magics\n",
-    "from ipywidgets import interact\n",
-    "import ipywidgets as widgets\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {
-    "collapsed": false,
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd3xb1fk/8HO1tyXvGSeOnUE2YWVAQwhQSkgLHZRSoFAa2nRCx7df+qOL0tIBdJC2hPYb\nWqA0bQOUhA0hIRASMpyYLM94b9mytce99/eHjCxrXklX697P+5U/5KOrc0+sxH50znmeQ7EsSwAA\nAACAP5JsDwAAAABAaBBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAA\nzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYA\nAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAM\nARYA [...]
-      "text/plain": [
-       "<IPython.core.display.Image object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "text/plain": [
-       "<function __main__.graph>"
-      ]
-     },
-     "execution_count": 2,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "\n",
-    "def graph (lat, lon, param, color, style) :\n",
-    "    url_fmt = 'http://earthserver.ecmwf.int/rasdaman/ows?service=WCS&version=2.0.1' \\\n",
-    "          '&request=ProcessCoverages' \\\n",
-    "          '&query=for c in (%s) return encode(c[Lat(%s), Long(%s), ansi(\"%s\":\"%s\")], \"csv\") '\n",
-    "\n",
-    "    url = url_fmt%(param, lat, lon, \"2000-01-01T00:00:00+00:00\",\"2005-12-31T00:00:00+00:00\")\n",
-    "    \n",
-    "    r= requests.get(url,\n",
-    "                    proxies={'http':None}\n",
-    "                    )\n",
-    "\n",
-    "    r.raise_for_status()\n",
-    "\n",
-    "    # Store the requested data in a numpy array\n",
-    "    yy = np.array(eval(r.text.replace('{','[').replace('}',']')))\n",
-    "    xx =  range(len(yy))\n",
-    "   \n",
-    "    \n",
-    "    \n",
-    "    return magics.graph(yy, xx, \n",
-    "            title = \"Time series %s at %d/%d\" % ( param , lat, lon), \n",
-    "            graph = { \"graph_line_colour\" : color, \"graph_line_style\" : style },\n",
-    "           )\n",
-    "    \n",
-    "# , \n",
-    "\n",
-    "interact(graph, lon=widgets.IntSlider(min=-180,max=180,step=1,value=10,continuous_update=False),\n",
-    "         lat=widgets.IntSlider(min=-90,max=90,step=1,value=10,continuous_update=False),\n",
-    "         param = widgets.Dropdown(\n",
-    "            options=['temp2m', 'precipitation', ],\n",
-    "            value='temp2m',\n",
-    "        ),\n",
-    "        color = widgets.Dropdown(\n",
-    "            options=[ \"ecmwf_blue\", 'navy', 'evergreen', ],\n",
-    "            value='ecmwf_blue',),\n",
-    "        style = widgets.Dropdown(\n",
-    "            options=[ \"solid\", 'dash', 'dot', ],\n",
-    "            value='solid',) \n",
-    "         )\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "celltoolbar": "Edit Metadata",
-  "kernelspec": {
-   "display_name": "Python 2",
-   "language": "python",
-   "name": "python2"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.12"
-  },
-  "widgets": {
-   "state": {
-    "e2ad91f584b549f08bcd6ff26212b574": {
-     "views": [
-      {
-       "cell_index": 1
-      }
-     ]
-    }
-   },
-   "version": "1.2.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/notebook/epsgrams.ipynb b/notebook/epsgrams.ipynb
deleted file mode 100644
index 83ac80b..0000000
--- a/notebook/epsgrams.ipynb
+++ /dev/null
@@ -1,304 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "from ecmwfapi import ECMWFService\n",
-    "from Magics import toolbox as magics\n",
-    "import ipywidgets as widgets\n",
-    "from ipywidgets import interact, interactive, fixed\n",
-    "\n",
-    "import random\n",
-    "from datetime import date, timedelta\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "def data(meteogram, parameter):\n",
-    "    yesterday = date.today() - timedelta(1)\n",
-    "    print yesterday.strftime('%Y%m%d')\n",
-    "    print meteogram, parameter\n",
-    "    json = \"%s.json\"\n",
-    "    key = {\n",
-    "            \"url\"   : \"https://api.ecmwf.int/v1\",\n",
-    "            \"key\"   : \"83253855c912864513eb33f5fb1de322\",\n",
-    "            \"email\" : \"Sylvie.Lamy-Thepaut at ecmwf.int\"\n",
-    "          }\n",
-    "\n",
-    "\n",
-    "    lat = random.randrange(-90, 90)\n",
-    "    lon = random.randrange(-180, 180)\n",
-    "\n",
-    "    server = ECMWFService(\"meteogram\", verbose=True, **key)\n",
-    "\n",
-    "    yesterday = date.today() - timedelta(0)\n",
-    "    print yesterday.strftime('%Y%m%d')\n",
-    "\n",
-    "\n",
-    "    request = {\n",
-    "      \"meteogram\": meteogram,\n",
-    "      \"param\": parameter,\n",
-    "      \"location\": \"%f/%f\" % (lat, lon),\n",
-    "      \"date\": yesterday.strftime('%Y%m%d'),\n",
-    "      \"time\": \"0000\"\n",
-    "     }\n",
-    "    \n",
-    "    server.execute( request, json % parameter )\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "20161031\n",
-      "10days 2t\n",
-      "20161101\n",
-      "2016-11-01 15:16:31 ECMWF API python library 1.4.1\n",
-      "2016-11-01 15:16:31 ECMWF API at https://api.ecmwf.int/v1\n",
-      "GET https://api.ecmwf.int/v1/who-am-i\n",
-      "Code 200\n",
-      "Content-Type application/json\n",
-      "Content-Length None\n",
-      "Location None\n",
-      "{\n",
-      "    \"first_name\": \"Sylvie\", \n",
-      "    \"last_name\": \"Lamy-Thepaut\", \n",
-      "    \"uid\": \"cgs\", \n",
-      "    \"code\": 200, \n",
-      "    \"full_name\": \"Sylvie Lamy-Thepaut\", \n",
-      "    \"email\": \"Sylvie.Lamy-Thepaut at ecmwf.int\"\n",
-      "}\n",
-      "Status None\n",
-      "2016-11-01 15:16:31 Welcome Sylvie Lamy-Thepaut\n",
-      "GET https://api.ecmwf.int/v1/services/meteogram/news\n",
-      "Code 200\n",
-      "Content-Type application/json\n",
-      "Content-Length None\n",
-      "Location None\n",
-      "{\n",
-      "    \"news\": \"Welcome to ECMWF Web API Meteogram Service\\r\\n\", \n",
-      "    \"code\": 200\n",
-      "}\n",
-      "Status None\n",
-      "2016-11-01 15:16:31 Welcome to ECMWF Web API Meteogram Service\n",
-      "2016-11-01 15:16:31 \n",
-      "POST https://api.ecmwf.int/v1/services/meteogram/requests\n",
-      "Code 303\n",
-      "Content-Type application/json\n",
-      "Content-Length None\n",
-      "Location http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\n",
-      "{\n",
-      "    \"status\": \"complete\", \n",
-      "    \"code\": 303, \n",
-      "    \"name\": \"e66af64d-b2d0-415c-a28b-18da5ecd466c\", \n",
-      "    \"href\": \"http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\", \n",
-      "    \"type\": \"application/json\", \n",
-      "    \"size\": 11504\n",
-      "}\n",
-      "Status complete\n",
-      "2016-11-01 15:16:33 Request submitted\n",
-      "2016-11-01 15:16:33 Request id: e66af64d-b2d0-415c-a28b-18da5ecd466c\n",
-      "2016-11-01 15:16:33 Request is complete\n",
-      "2016-11-01 15:16:33 Transfering 11.2344 Kbytes into 2t.json\n",
-      "2016-11-01 15:16:33 From http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\n",
-      "2016-11-01 15:16:33 Transfer rate 904.978 Kbytes/s\n",
-      "2016-11-01 15:16:33 Done.\n"
-     ]
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1gUV9cA8LPL0puAiqAICAoCVqqKaERR7EQBC8FObC8aY+wtaoK9V4wiFoxiATsRbFRR\nVCz03ntbFpZt8/0xfhtemoCLu8x7fs8+T9g7d+69M0OW4527Z2gEQQBCCCGEEBIdurgHgBBCCCFE\nNRhgIYQQQgiJGAZYCCGEEEIihgEWQgghhJCIYYCFEEIIISRiGGAhhBBCCIkYBlgIIYQQQiKGARZC\nCCGEkIhhgIUQQgghJGIYYCGEEEIIiRgGWAghhBBCIoYBFkIIIYSQiGGAhRBCCCEkYhhgIYQQQgiJ\nGAZYCCGEEEIihgEWQgghhJCIYYCFEEIIISRiGGAhhBBCCIkYBlgIIYQQQiKGARZCCCGEkIhhgIUQ\nQggh [...]
-      "text/plain": [
-       "<IPython.core.display.Image object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "\n",
-    "\n",
-    "colour = widgets.ColorPicker(\n",
-    "    concise= False,\n",
-    "    description='Pick a color',\n",
-    "    value='blue'\n",
-    ")\n",
-    "colour.layout.width = \"50%\"\n",
-    "meteogram = widgets.Dropdown(\n",
-    "    options=['10days', '15days'],\n",
-    "    value='10days',\n",
-    "    description='meteogran:',\n",
-    "    disabled=False,\n",
-    "    button_style='' # 'success', 'info', 'warning', 'danger' or ''\n",
-    ")\n",
-    "\n",
-    "parameter = widgets.Dropdown(\n",
-    "    options=['2t', \"tcc\", \"10fg6\", \"hcc\", \"lcc\", \"mcc\", \"sf\", \"tp\", \"ws\"],\n",
-    "    value='2t',\n",
-    "    description='Parameter:',\n",
-    "    disabled=False,\n",
-    "    button_style='' # 'success', 'info', 'warning', 'danger' or ''\n",
-    ")\n",
-    "\n",
-    "def epsgram(meteogram, parameter, colour):\n",
-    "    data(meteogram, parameter)\n",
-    "    return  magics.epsgram(parameter, \n",
-    "                           \"%s.json\" % parameter, \n",
-    "                           title = \"My title for %s\" % (parameter), \n",
-    "                           colour = colour)\n",
-    "\n",
-    "from IPython.display import display\n",
-    "\n",
-    "ui = interactive(epsgram, meteogram=meteogram, parameter = parameter, colour=colour)\n",
-    "\n",
-    "box = widgets.VBox(ui.children)\n",
-    "display(box)\n",
-    "\n",
-    "\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 2",
-   "language": "python",
-   "name": "python2"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.12"
-  },
-  "widgets": {
-   "state": {
-    "b4420652ae1447a1bed6f953098f9e77": {
-     "views": [
-      {
-       "cell_index": 4
-      }
-     ]
-    },
-    "c1d9e98c8af74b34b18d52c87bd266c5": {
-     "views": [
-      {
-       "cell_index": 4
-      }
-     ]
-    }
-   },
-   "version": "1.2.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 2d898e7..0abbf8f 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,10 +1,8 @@
+
 if( HAVE_PYTHON )
 
   configure_file( setup.py.in setup.py )
-  configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../src/common/magics_api.h magics_api.h COPYONLY )
-  configure_file( numpy.i numpy.i COPYONLY )
-  configure_file( Magics_interface.cc Magics_interface.cc COPYONLY )
-  configure_file( Magics.i.in Magics/Magics.i )
+  configure_file( Magics.py.in Magics/Magics.py )
 
   # Copy python modules to build area
   # configure_file ensures the copy is triggered if the file changes
@@ -13,12 +11,7 @@ if( HAVE_PYTHON )
   configure_file( Magics/toolbox.py Magics/toolbox.py COPYONLY )
   configure_file( Magics/metgram.py Magics/metgram.py COPYONLY )
 
-  set( _magics_swig "_Magics${CMAKE_SHARED_LIBRARY_SUFFIX}" )
-  # Build the extension module for use in build tree with RPATH pointing to the build tree
-  add_custom_command( OUTPUT ${_magics_swig}
-    COMMAND ${PYTHON_EXECUTABLE} setup.py build_ext --inplace --rpath ${CMAKE_BINARY_DIR}/lib
-    DEPENDS Magics_interface.cc Magics.i.in numpy.i setup.py.in MagPlus )
-  add_custom_target(build_swig_wrapper ALL DEPENDS ${_magics_swig})
+#  ${CMAKE_SHARED_LIBRARY_SUFFIX}   ${CMAKE_BINARY_DIR}/lib
 
   # Build the extension module for use in install tree with RPATH pointing to install tree
   install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py build_ext --rpath ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
diff --git a/python/Magics.i.in b/python/Magics.i.in
deleted file mode 100755
index 3663473..0000000
--- a/python/Magics.i.in
+++ /dev/null
@@ -1,69 +0,0 @@
-%module (docstring="This is a Python interface to Magics++") Magics
-
-%{
-#define SWIG_FILE_WITH_INIT
-/* Includes the header in the wrapper code */
-#include "Magics_interface.cc"
-%}
-
-%constant const char *__version__ ="@MAGICS_VERSION@";
-
-
-// This tells SWIG to treat char ** as a special case
-//
-//  see http://www.swig.org/Doc1.3/Python.html#Python_nn59
-//
-%typemap(in) (const char **data, const int dim)
-{
-  /* Check if is a list */
-  if (PyList_Check($input))
-  {
-    int size = PyList_Size($input);
-    int i = 0;
-    $1 = (char **) malloc((size+1)*sizeof(char *));
-    $2 = size;
-    for (i = 0; i < size; i++) {
-      PyObject *o = PyList_GetItem($input,i);
-      if (PyString_Check(o))
-	$1[i] = PyString_AsString(PyList_GetItem($input,i));
-      else {
-	PyErr_SetString(PyExc_TypeError,"list must contain strings");
-	free($1);
-	return NULL;
-      }
-    }
-    $1[i] = 0;
-  }
-  else
-  {
-    PyErr_SetString(PyExc_TypeError,"not a list");
-    return NULL;
-  }
-}
-
-// This cleans up the char ** array we malloced before the function call
-%typemap(freearg) (const char **data, int dim)
-{
-  free((char *) $1);
-}
-
-
-/* 
-  N U M E R I C A L   A R R A Y S 
-*/
-%include "numpy.i"
-%init %{
-        import_array();
-%}
-
-%apply(double* IN_ARRAY1, int DIM1) {(double *data, int dim)}
-%apply(int* IN_ARRAY1, int DIM1) {(int *data, int dim)}
-
-%apply(int* IN_ARRAY2, int DIM1, int DIM2) {(int *data, const int dim1, const int dim2)}
-%apply(int* IN_ARRAY2, int DIM1, int DIM2, int DIM3) {(int *data, const int dim1, const int dim2, const int dim3)}
-
-%apply(double* IN_ARRAY2, int DIM1, int DIM2) {(double *data, const int dim1, const int dim2)}
-%apply(double* IN_ARRAY2, int DIM1, int DIM2, int DIM3) {(double *data, const int dim1, const int dim2, const int dim3)}
-
-/* Parse the header file to generate wrappers */
-%include "Magics_interface.cc"
diff --git a/python/Magics.py.in b/python/Magics.py.in
new file mode 100644
index 0000000..d8a4567
--- /dev/null
+++ b/python/Magics.py.in
@@ -0,0 +1,500 @@
+# (C) Copyright 2012-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+#
+
+import ctypes
+import ctypes.util
+import sys
+
+import numpy as np
+from numpy.ctypeslib import ndpointer
+from functools import partial
+
+lib = ctypes.util.find_library("MagPlus")
+
+if lib is None:
+    lib = "@CMAKE_INSTALL_PREFIX@/@INSTALL_LIB_DIR@/libMagPlus at CMAKE_SHARED_LIBRARY_SUFFIX@"
+    if lib is None:
+      lib = "@CMAKE_BINARY_DIR@/lib/libMagPlus at CMAKE_SHARED_LIBRARY_SUFFIX@"
+
+dll  = ctypes.CDLL(lib)
+libc = ctypes.CDLL(ctypes.util.find_library("c"))
+
+
+class FILE(ctypes.Structure):
+    pass
+
+
+FILE_p = ctypes.POINTER(FILE)
+
+######################## String conversions ##########################
+
+def _string_to_char(x):
+    return x.encode()
+
+
+def _char_to_string(x):
+    return x.decode()
+
+
+def _convert_strings(fn):
+
+    convert = False
+
+    for a in fn.argtypes:
+        if a is c_char_p:
+            convert = True
+
+    if fn.restype is c_char_p:
+        convert = True
+
+    if not convert:
+        return fn
+
+    def wrapped(*args):
+
+        new_args = []
+        for a, t in zip(args, fn.argtypes):
+            if t is c_char_p:
+                a = string_to_char(a)
+            new_args.append(a)
+
+        r = fn(*new_args)
+        if fn.restype is c_char_p:
+            r = char_to_string(r)
+        return r
+
+    return wrapped
+
+if sys.version_info[0] > 2:
+    convert_strings = _convert_strings
+    char_to_string = _char_to_string
+    string_to_char = _string_to_char
+else:
+    convert_strings = lambda x: x
+    char_to_string = lambda x: x
+    string_to_char = lambda x: x
+
+
+
+
+
+####################################################################
+c_int = ctypes.c_int
+c_int_p = ctypes.POINTER(c_int)
+
+c_double = ctypes.c_double
+c_double_p = ctypes.POINTER(c_double)
+
+c_char = ctypes.c_char
+c_char_p = ctypes.c_char_p
+
+c_void_p = ctypes.c_void_p
+
+
+####################################################################
+def checked_error_in_last_paramater(fn):
+
+    def wrapped(*args):
+        err = c_int(0)
+        err_p = ctypes.cast(ctypes.addressof(err), c_int_p)
+        params = [a for a in args]
+        params.append(err_p)
+
+        result = fn(*params)
+        if err.value:
+            raise MagicsError(err)
+        return result
+
+    return wrapped
+
+
+def checked_return_code(fn):
+
+    def wrapped(*args):
+        err = fn(*args)
+        if err:
+            raise MagicsError(err)
+
+    return wrapped
+
+
+####################################################################
+
+def return_type(fn, ctype):
+
+    def wrapped(*args):
+        result = ctype()
+        result_p = ctypes.cast(ctypes.addressof(result), ctypes.POINTER(ctype))
+        params = [a for a in args]
+        params.append(result_p)
+        fn(*params)
+        return result.value
+
+    return wrapped
+
+####################################################################
+
+init = dll.mag_open
+init.restype = None
+init.argtypes = None
+
+####################################################################
+
+
+ at checked_return_code
+def finalize():
+    return dll.mag_close()
+
+####################################################################
+
+coast = dll.mag_coast
+coast.restype = None
+coast.argtypes = None
+
+####################################################################
+
+grib = dll.mag_grib
+grib.restype = None
+grib.argtypes = None
+
+####################################################################
+
+cont = dll.mag_cont
+cont.restype = None
+cont.argtypes = None
+
+####################################################################
+
+legend = dll.mag_legend
+legend.restype = None
+legend.argtypes = None
+
+####################################################################
+
+odb = dll.mag_odb
+odb.restype = None
+odb.argtypes = None
+
+####################################################################
+
+obs = dll.mag_obs
+obs.restype = None
+obs.argtypes = None
+
+####################################################################
+
+raw = dll.mag_raw
+raw.restype = None
+raw.argtypes = None
+
+####################################################################
+
+netcdf = dll.mag_netcdf
+netcdf.restype = None
+netcdf.argtypes = None
+
+####################################################################
+
+image = dll.mag_image
+image.restype = None
+image.argtypes = None
+
+####################################################################
+
+plot = dll.mag_plot
+plot.restype = None
+plot.argtypes = None
+
+####################################################################
+
+text = dll.mag_text
+text.restype = None
+text.argtypes = None
+
+####################################################################
+
+wind = dll.mag_wind
+wind.restype = None
+wind.argtypes = None
+
+####################################################################
+
+line = dll.mag_line
+line.restype = None
+line.argtypes = None
+
+####################################################################
+
+symb = dll.mag_symb
+symb.restype = None
+symb.argtypes = None
+
+####################################################################
+
+boxplot = dll.mag_boxplot
+boxplot.restype = None
+boxplot.argtypes = None
+
+####################################################################
+
+taylor = dll.mag_taylor
+taylor.restype = None
+taylor.argtypes = None
+
+####################################################################
+
+tephi = dll.mag_tephi
+tephi.restype = None
+tephi.argtypes = None
+
+####################################################################
+
+graph = dll.mag_graph
+graph.restype = None
+graph.argtypes = None
+
+####################################################################
+
+axis = dll.mag_axis
+axis.restype = None
+axis.argtypes = None
+
+####################################################################
+
+geo = dll.mag_geo
+geo.restype = None
+geo.argtypes = None
+
+####################################################################
+
+mimport = dll.mag_import
+mimport.restype = None
+mimport.argtypes = None
+
+####################################################################
+
+info = dll.mag_info
+info.restype = None
+info.argtypes = None
+
+####################################################################
+
+minput = dll.mag_input
+minput.restype = None
+minput.argtypes = None
+
+####################################################################
+
+eps = dll.mag_eps
+eps.restype = None
+eps.argtypes = None
+
+####################################################################
+###
+###  Please note: these two functions changed compared to the previous SWIG based Python interface
+###
+metgraph = dll.mag_metgraph
+metgraph.restype = None
+metgraph.argtypes = None
+
+epsinput = dll.mag_epsinput
+epsinput.restype = None
+epsinput.argtypes = None
+
+####################################################################
+###
+###  Please note: this function was called mmetbufr to the previous SWIG based Python interface
+###
+metbufr = dll.mag_metbufr
+metbufr.restype = None
+metbufr.argtypes = None
+
+####################################################################
+
+epsgraph = dll.mag_epsgraph
+epsgraph.restype = None
+epsgraph.argtypes = None
+
+####################################################################
+
+epscloud = dll.mag_epscloud
+epscloud.restype = None
+epscloud.argtypes = None
+
+####################################################################
+
+epslight = dll.mag_epslight
+epslight.restype = None
+epslight.argtypes = None
+
+####################################################################
+
+epsplumes = dll.mag_epsplumes
+epsplumes.restype = None
+epsplumes.argtypes = None
+
+####################################################################
+
+epswind = dll.mag_epswind
+epswind.restype = None
+epswind.argtypes = None
+
+####################################################################
+
+epswave = dll.mag_epswave
+epswave.restype = None
+epswave.argtypes = None
+
+####################################################################
+
+epsbar = dll.mag_epsbar
+epsbar.restype = None
+epsbar.argtypes = None
+
+####################################################################
+
+epsshading = dll.mag_epsshading
+epsshading.restype = None
+epsshading.argtypes = None
+
+####################################################################
+
+wrepjson = dll.mag_wrepjson
+wrepjson.restype = None
+wrepjson.argtypes = None
+
+####################################################################
+
+geojson = dll.mag_geojson
+geojson.restype = None
+geojson.argtypes = None
+
+####################################################################
+
+mapgen = dll.mag_mapgen
+mapgen.restype = None
+mapgen.argtypes = None
+
+####################################################################
+
+mtable = dll.mag_table
+mtable.restype = None
+mtable.argtypes = None
+
+####################################################################
+
+seti = dll.mag_seti
+seti.restype = None
+seti.argtypes = (c_char_p, c_int)
+seti = convert_strings(seti)
+
+####################################################################
+
+def set1i(name,data):
+#    array = np.empty((size,), dtype=np.float64)
+#    array_p = array.ctypes.data_as(c_double_p)
+#    _set1r(name, array_p, size)
+    size = len(data)
+    name = string_to_char(name)
+    array_p = (ctypes.c_int * size)(*data)
+    dll.mag_set1i(ctypes.c_char_p(name), array_p, size)
+    return None
+
+####################################################################
+
+array_2d_int = ndpointer(dtype=np.int,ndim=2, flags='CONTIGUOUS')
+set2i = dll.mag_set2i
+set2i.restype = None
+set2i.argtypes = (c_char_p, array_2d_int, c_int, c_int)
+set2i = convert_strings(set2i)
+
+####################################################################
+
+setr = dll.mag_setr
+setr.restype = None
+setr.argtypes = (c_char_p, c_double)
+setr = convert_strings(setr)
+
+####################################################################
+
+def set1r(name,data):
+    size = len(data)
+    name = string_to_char(name)
+    array_p = (ctypes.c_double * size)(*data)
+    dll.mag_set1r(ctypes.c_char_p(name), array_p, size)
+    return None
+
+####################################################################
+
+array_2d_double = ndpointer(dtype=np.double,ndim=2, flags='CONTIGUOUS')
+set2r = dll.mag_set2r
+set2r.restype = None
+set2r.argtypes = (c_char_p, array_2d_double, c_int, c_int)
+set2r = convert_strings(set2r)
+
+####################################################################
+
+setc = dll.mag_setc
+setc.restype = None
+setc.argtypes = (c_char_p, c_char_p)
+setc = convert_strings(setc)
+
+####################################################################
+def set1c(name,data):
+    new_data=[]
+    for s in data:
+       new_data.append(string_to_char(s))
+    name = string_to_char(name)
+    data_p = (c_char_p * (len(new_data)))(*new_data)
+    dll.mag_set1c(ctypes.c_char_p(name), data_p, len(new_data))
+
+####################################################################
+
+#enqi = dll.mag_enqi
+#enqi.restype  = c_int
+#enqi.argtypes = (c_char_p,)
+
+####################################################################
+
+#enqr = dll.mag_enqr
+#enqr.restype = c_double
+#enqr.argtypes = (c_char_p,)
+
+####################################################################
+
+#enqc = dll.mag_enqc
+#enqc.restype = c_char_p
+#enqc.argtypes = (c_char_p,)
+
+####################################################################
+
+new_page = dll.mag_new
+new_page.restype = None
+new_page.argtypes = (c_char_p,)
+new_page = convert_strings(new_page)
+
+####################################################################
+
+reset = dll.mag_reset
+reset.restype = None
+reset.argtypes = (c_char_p,)
+reset = convert_strings(reset)
+
+####################################################################
+
+class MagicsError(Exception):
+
+    def __init__(self, err):
+        super(MagicsError, self).__init__("Magics Error - No Plot Produced!!! (%s)" % err)
+
+####################################################################
+
+
+#if __name__ == "__main__":
+#    print "..."
diff --git a/python/Magics/macro.py b/python/Magics/macro.py
index bc72d88..d4ac5fc 100644
--- a/python/Magics/macro.py
+++ b/python/Magics/macro.py
@@ -1,14 +1,15 @@
 # (C) Copyright 1996-2016 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
+import sys
 import os
-import Magics
 import numpy
+from . import Magics
 
 class Context(object):
     def __init__(self):
@@ -58,18 +59,18 @@ class Action(object):
         self.action = action
         self.args = args
         if ( html == "") :
-            self.html = verb 
-        else :          
-            self.html = "<a href=/wiki/display/MAGP/%s target='_blank'>%s</a>" % (html, verb)  
+            self.html = verb
+        else :
+            self.html = "<a href=/wiki/display/MAGP/%s target='_blank'>%s</a>" % (html, verb)
 
     def __repr__(self):
         x = ""
-        for key in self.args.keys():
+        for key in list(self.args.keys()):
             x = x + " %s = '%s'\n" % (key, self.args[key])
         return x
 
     def inspect(self):
-        print self
+        print(self)
 
     def quote(self, v):
         return "\"" + v + "\""
@@ -78,7 +79,7 @@ class Action(object):
         sep=""
         val="%s("%self.html
 
-        for key in self.args.keys():
+        for key in list(self.args.keys()):
             if isinstance(self.args[key], str):
                 if key == 'odb_data':
                     Magics.setc('odb_filename', self.args[key])
@@ -97,7 +98,7 @@ class Action(object):
                             vval += vsep + self.quote(v)
                             vsep = ", "
                    else :
-                        vval = self.quote(self.args[key][0]) + ", " + self.quote(self.args[key][1]) + ",...," + self.quote(self.args[key][-2]) +  ", " + self.quote(self.args[key][-1]) 
+                        vval = self.quote(self.args[key][0]) + ", " + self.quote(self.args[key][1]) + ",...," + self.quote(self.args[key][-2]) +  ", " + self.quote(self.args[key][-1])
                    vval += ""
                    val+= '%s%s = [%s]'%(sep, key, vval)
                 elif isinstance(self.args[key][0], int):
@@ -108,7 +109,7 @@ class Action(object):
                             vval += vsep + ("%df"%v)
                             vsep = ", "
                    else :
-                            vval = ("%d"%self.args[key][0]) + ", " + ("%d"%self.args[key][1]) + ",...," + ("%d"%self.args[key][-2]) +  ", " + ("%d"%self.args[key][-1]) 
+                            vval = ("%d"%self.args[key][0]) + ", " + ("%d"%self.args[key][1]) + ",...," + ("%d"%self.args[key][-2]) +  ", " + ("%d"%self.args[key][-1])
                    vval += ""
                    val+= '%s%s = %s'%(sep, key, vval)
                 elif isinstance(self.args[key][0], float):
@@ -119,8 +120,8 @@ class Action(object):
                             vval += vsep + ("%0.2f"%v)
                             vsep = ", "
                    else :
-                        vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) +  ", " + ("%0.2f"%self.args[key][-1]) 
-                
+                        vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) +  ", " + ("%0.2f"%self.args[key][-1])
+
                    vval += ""
                    val+= '%s%s = [%s]'%(sep, key, vval)
             elif isinstance(self.args[key], numpy.ndarray) :
@@ -128,12 +129,12 @@ class Action(object):
                 dim  = len(self.args[key].shape)
                 if isinstance(self.args[key][0], int):
                     if (dim == 2) :
-                        print "pset2i" 
+                        print("pset2i")
                     else :
-                        print "pset1i" 
+                        print("pset1i")
                 elif ( type == 'float64' or type == 'float32') :
                     if (dim == 2) :
-                        print "pset2r" 
+                        print("pset2r")
                     else :
                         vval = ""
                         vsep = ""
@@ -142,20 +143,20 @@ class Action(object):
                                 vval += vsep + ("%0.2f"%v)
                                 vsep = ", "
                         else :
-                            vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) +  ", " + ("%0.2f"%self.args[key][-1]) 
+                            vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) +  ", " + ("%0.2f"%self.args[key][-1])
                         vval += ""
                         val+= '%s%s = [%s]'%(sep, key, vval)
                 else :
-                    print "type???->", key
+                    print("type???->", key)
             sep=",\n\t"
-                
-        print >>file, val + ")\n"
+
+        print(file, val + ")\n")
 
     def tomv4(self, file):
         sep="\t"
         val="%s,\n"%self.verb.upper()
 
-        for key in self.args.keys():
+        for key in list(self.args.keys()):
             if isinstance(self.args[key], str):
                 if key == 'odb_data':
                     Magics.setc('odb_filename', self.args[key])
@@ -175,20 +176,20 @@ class Action(object):
                    vval += "]"
                    val+= '%s%s = %s'%(sep, key.upper(), vval)
                 elif isinstance(self.args[key][0], int):
-                   print "pset1i"
+                   print("pset1i")
                 elif isinstance(self.args[key][0], float):
-                   print "pset1r" 
+                   print("pset1r")
             elif isinstance(self.args[key], numpy.ndarray) :
                 type = self.args[key].dtype
                 dim  = len(self.args[key].shape)
                 if isinstance(self.args[key][0], int):
                     if (dim == 2) :
-                        print "pset2i" 
+                        print("pset2i")
                     else :
-                        print "pset1i" 
+                        print("pset1i")
                 elif ( type == 'float64' or type == 'float32') :
                     if (dim == 2) :
-                        print "pset2r" 
+                        print("pset2r")
                     else :
                         vval = "["
                         vsep = ""
@@ -197,12 +198,12 @@ class Action(object):
                                 vsep = ", "
                         vval += "]"
                         val+= '%s%s = %s'%(sep, key.upper(), vval)
-                        
+
                 else :
-                    print "type???->", key
+                    print("type???->", key)
             sep=",\n\t"
-                
-        print >> file, val + "\n"
+
+        print(file, val + "\n")
 
 
 
@@ -210,24 +211,24 @@ class Action(object):
 
     def tofortran(self, f):
         if self.action == Magics.new_page :
-            print >> f, '\tcall pnew("page")'
+            print(f, '\tcall pnew("page")')
             return
-        for key in self.args.keys():
+        for key in list(self.args.keys()):
             if isinstance(self.args[key], str):
                 if key == 'odb_data':
                     Magics.setc('odb_filename', self.args[key])
                 else:
-                    print >> f, '\tcall psetc("%s", "%s")'%(key, self.args[key])
+                    print (f, '\tcall psetc("%s", "%s")'%(key, self.args[key]))
             elif isinstance(self.args[key], int):
-                print >>f, '\tcall pseti("%s", %d)'%(key, self.args[key])
+                print (f, '\tcall pseti("%s", %d)'%(key, self.args[key]))
             elif isinstance(self.args[key], float):
-                print >> f, '\tcall psetr("%s", %0.2f)'%(key, self.args[key])
+                print (f, '\tcall psetr("%s", %0.2f)'%(key, self.args[key]))
             elif isinstance(self.args[key], list) :
                 if isinstance (self.args[key][0], str):
                    nb = 0
                    for v in self.args[key]:
                         nb = max(nb, len(v))
-                    
+
                    val = "(/"
                    sep = ""
                    newline = 70
@@ -238,9 +239,9 @@ class Action(object):
                             sep = ",&\n\t\t"
                             newline = newline + 70
                    val += "/)"
-                   print >>f, '\tcall pset1c("%s", %s, %d)'%(key, val, len(self.args[key]))
+                   print (f, '\tcall pset1c("%s", %s, %d)'%(key, val, len(self.args[key])))
                 elif isinstance(self.args[key][0], int):
-                   print "pset1i"
+                   print("pset1i")
                 elif isinstance(self.args[key][0], float):
                     val = "(/"
                     sep = ""
@@ -248,18 +249,18 @@ class Action(object):
                         val += sep + ("%0.2f" % v)
                         sep = ", "
                     val += "/)"
-                    print >>f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key]))
+                    print (f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key])))
             elif isinstance(self.args[key], numpy.ndarray) :
                 type = self.args[key].dtype
                 dim  = len(self.args[key].shape)
                 if isinstance(self.args[key][0], int):
                     if (dim == 2) :
-                        print "pset2i" 
+                        print("pset2i")
                     else :
-                        print "pset1i" 
+                        print("pset1i")
                 elif ( type == 'float64' or type == 'float32') :
                     if (dim == 2) :
-                        print "pset2r" 
+                        print("pset2r")
                     else :
                         val = "(/"
                         sep = ""
@@ -267,49 +268,54 @@ class Action(object):
                             val += sep + ("%0.2f" % v)
                             sep = ", "
                         val += "/)"
-                        print >>f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key]))
+                        print (f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key])))
                 elif isinstance(self.args[key][0], int):
-                        print "pset1r" 
+                        print("pset1r")
                 else :
-                    print "type???->", key
+                    print("type???->", key)
 
         if self.action != None and actions[self.verb] != "" and actions[self.verb] != "pinput":
-            print >>f, "\tcall %s\n"%actions[self.verb] 
-            for key in self.args.keys():
-                print >>f, "\tcall preset('%s')"%key 
-            print >>f, ""
+            print (f, "\tcall %s\n"%actions[self.verb])
+            for key in list(self.args.keys()):
+                print (f, "\tcall preset('%s')"%key)
+            print (f, "")
 
         else:
-            print >>f, ""
+            print (f, "")
 
 
     def clean_object(self, obj):
-
+      if sys.version_info[0] < 3:
         if type(obj) in (int, float, str, bool, numpy.float64):
             return obj
         elif type(obj) == unicode:
             return str(obj)
-        elif type(obj) in (list, tuple, set, numpy.ndarray):
+        elif type(obj) in (list, tuple, set, numpy.ndarray) and len(obj):
             if type(obj[0]) != unicode:
                 return obj
             obj = list(obj)
             for i,v in enumerate(obj):
                 obj[i] = self.clean_object(v)
         elif type(obj) == dict:
-            for i,v in obj.iteritems():
+            for i,v in list(obj.items()):
                 obj[i] = self.clean_object(v)
         else:
-            print "Invalid object in data, converting to string: " 
-            print  type(obj)
-            obj = str(obj) 
-        return obj
+            print("Invalid object in data, converting to string: ")
+            print(type(obj))
+            obj = str(obj)
+      return obj
 
+    def find_type(self, data):
+        for v in data:
+            if isinstance(v, float):
+                return "float"
+        return "int"
 
     def execute(self):
 
         if ( self.action != Magics.odb) :
             self.args = self.clean_object(self.args)
-        for key in self.args.keys():
+        for key in list(self.args.keys()):
             if isinstance(self.args[key], str):
                 if key == 'odb_data':
                     Magics.setc('odb_filename', self.args[key])
@@ -319,29 +325,33 @@ class Action(object):
                 Magics.seti(key, self.args[key])
             elif isinstance(self.args[key], float):
                 Magics.setr(key, self.args[key])
-            elif isinstance(self.args[key], list) :
+            elif isinstance(self.args[key], list) and len(self.args[key]):
                 if isinstance(self.args[key][0], str):
                    Magics.set1c(key, self.args[key])
-                elif isinstance(self.args[key][0], int):
-                   Magics.set1i(key, numpy.array(self.args[key], dtype='i'))
-                elif isinstance(self.args[key][0], float):
-                   Magics.set1r(key, numpy.array(self.args[key]))
+                else:
+                    type = self.find_type(self.args[key])
+                    if type == "int":
+                        Magics.set1i(key, numpy.array(self.args[key], dtype='i'))
+                    else :
+                        Magics.set1r(key, numpy.array(self.args[key]))
             elif isinstance(self.args[key], numpy.ndarray) :
                 type = self.args[key].dtype
-                dim  = len(self.args[key].shape)
-                if isinstance(self.args[key][0], int):
+                data = self.args[key].copy() 
+                size = data.shape
+                dim  = len(size)
+                type = self.find_type(self.args[key])
+                if type == "int":
                     if (dim == 2) :
-                        Magics.set2i(key, self.args[key].copy())
+                        Magics.set2i(key, data, size[0], size[1])
                     else :
-                        Magics.set1i(key, self.args[key].copy())
-                elif ( type == 'float64' or type == 'float32') :
-                    if (dim == 2) :
-                        Magics.set2r(key, self.args[key].copy())
+                        Magics.set1i(key, data, size[0])
+                elif type == "float": 
+                    if (dim == 2) :                      
+                        Magics.set2r(key, data, size[1], size[0])
                     else :
-                        Magics.set1r(key, self.args[key].copy())
+                        Magics.set1r(key, data)
                 else :
-                    print "type???->", key
-
+                    print("type???->", key)
             else:
                 self.args[key].execute(key)
 
@@ -351,7 +361,7 @@ class Action(object):
                     Magics.setc("legend", "on")
                 self.action()
                 if self.action != Magics.obs and self.action != Magics.minput:
-                    for key in self.args.keys():
+                    for key in list(self.args.keys()):
                         Magics.reset(key)
             else:
                 self.action("page")
@@ -359,7 +369,7 @@ class Action(object):
 def make_action(verb, action, html=""):
     def f(_m = None,**kw):
         args = {}
-        if _m is not None: 
+        if _m is not None:
             args.update(_m)
         args.update(kw)
         return Action(verb, action, html, args)
@@ -424,8 +434,8 @@ mepsgraph = make_action("mepsgraph", Magics.epsgraph)
 mepsplumes = make_action("mepsplumes", Magics.epsplumes)
 mtephi = make_action("mtephi", Magics.tephi)
 
-mmetgraph = make_action("mmetgraph", Magics.mmetgraph)
-mmetbufr = make_action("mmetbufr", Magics.mmetbufr)
+mmetgraph = make_action("mmetgraph", Magics.metgraph)
+mmetbufr = make_action("mmetbufr", Magics.metbufr)
 
 def examine(*args):
     for n in args:
@@ -440,14 +450,14 @@ def _execute(o):
 			_execute(x)
 
 	else:
-		
+
 		o.execute()
 
 def _plot(*args):
     Magics.init()
     for n in args:
         _execute(n)
-    
+
     #Collect the drivers!
     Magics.finalize()
     for f in context.tmp:
@@ -458,23 +468,26 @@ def _plot(*args):
 
 
 def tofortran(file, *args):
+    return
     f = open(file+".f90",'w')
-    print >>f, "\tprogram magics\n"
-    print >>f, "\tcall popen\n"
+    print(f, "\tprogram magics\n")
+    print(f, "\tcall popen\n")
     for n in args:
         n.tofortran(f)
-    print >>f, "\tcall pclose\n"
-    print >>f, "\tend"
+    print(f, "\tcall pclose\n")
+    print(f, "\tend")
 
 
 def tohtml(file, *args):
+    return
     f = open(file+".html",'w')
-    print >>f, "<html>"
+    print (f, "<html>")
     for n in args:
         n.tohtml(f)
-    print >>f, "</html>"
+    print (f, "</html>")
 
 def tomv4(file, *args):
+    return
     f = open(file+".mv4",'w')
     for n in args:
         n.tomv4(f)
@@ -488,22 +501,22 @@ class  odb_filter(object):
         self.args = args
     def execute(self, key):
         file = "data%d" % numpy.random.randint(1,1000)
-        odb = "%s.odb" % file 
+        odb = "%s.odb" % file
         context.tmp.append(odb)
-        cmd = "odb sql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -f newodb -o " + odb
-        print cmd 
+        cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -f newodb -o " + odb
+        print(cmd)
         if (os.system(cmd)) :
-            print "Error in filtering ODB data... Aborting"
+            print("Error in filtering ODB data... Aborting")
             os.abort();
         Magics.setc('odb_filename', odb)
     def inspect(self):
-        cmd = "odb sql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -o data.ascii"
+        cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -o data.ascii"
         if (os.system(cmd)) :
-            print "Error in filtering ODB data... Aborting"
+            print("Error in filtering ODB data... Aborting")
             os.abort();
         cmd =  os.environ['ODB_REPORTER'] + " %s" % "data.ascii"
         if (os.system(cmd)) :
-            print "Error in viewing ODB data... Aborting"
+            print("Error in viewing ODB data... Aborting")
             os.abort();
 
 
@@ -516,24 +529,23 @@ try:
     LOCK = threading.Lock()
 
     def plot(*args):
-        
-        with LOCK:       
+
+        with LOCK:
             f, tmp = tempfile.mkstemp(".png")
             os.close(f)
-            
+
             base, ext = os.path.splitext(tmp)
 
-            
-            
             img = output(output_formats=["png"],
                               output_name_first_page_number='off',
                               output_name=base)
+            
             all = []
             all.append(img)
             for i in args :
               all.append(i)
             _plot(all)
-            
+
             image = Image(tmp)
             os.unlink(tmp)
             return image
diff --git a/python/Magics/metgram.py b/python/Magics/metgram.py
index ab87ef2..fd7bda3 100644
--- a/python/Magics/metgram.py
+++ b/python/Magics/metgram.py
@@ -1,8 +1,8 @@
 # (C) Copyright 1996-2016 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
@@ -66,8 +66,8 @@ definition.append({
 definition.append({
 	"class": "vertical_axis",
 	"id" : "vaxis",
-	"axis_line":"on", 
-    "axis_grid":"on", 
+	"axis_line":"on",
+    "axis_grid":"on",
     "axis_line_colour":"kelly_green" ,
     "axis_tick_label_colour":"kelly_green",
     "axis_label_font":"sansserif",
@@ -101,14 +101,14 @@ def page():
 		"horizontal_axis": { "use_id" : "haxis" },
 		"vertical_axis": { "use_id" : "vaxis" }
 
-		
+
 	}
 
 	}
 	return page
 
 class humidity(object):
-	
+
 	def execute(self):
 		humi =  {
             "epsbufr":
@@ -132,7 +132,7 @@ class humidity(object):
 		return map
 
 class msl(object):
-	
+
 	def execute(self):
 		msl =  {
             "epsbufr":
@@ -154,7 +154,7 @@ class msl(object):
 
 
 class cloud(object):
-	
+
 	def execute(self):
 		cloud =  {
             "epsbufr":
@@ -178,7 +178,7 @@ class cloud(object):
 		return map
 
 class precip(object):
-	
+
 	def execute(self):
 		precip =  {
             "epsbufr":
@@ -198,7 +198,7 @@ class precip(object):
 		return map
 
 class wind(object):
-	
+
 	def execute(self):
 		wind =  {
             "epsbufr":
@@ -228,7 +228,7 @@ class wind(object):
 		return map
 
 class tempe(object):
-	
+
 	def execute(self):
 		t850 =  {
             "epsbufr":
@@ -238,7 +238,7 @@ class tempe(object):
 				"epsbufr_parameter_offset_factor": "-273.15",
                 "use_id":"station"
             },
-            "metgraph": { 
+            "metgraph": {
 				"metgram_plot_style":"curve",
 				"metgram_curve_colour":"blue"
 				}
@@ -253,7 +253,7 @@ class tempe(object):
 				"epsbufr_parameter_offset_factor": "-273.15",
                 "use_id":"station"
             },
-            "metgraph": { 
+            "metgraph": {
 				"metgram_plot_style":"curve",
 				"metgram_curve_colour":"red"
 				}
@@ -266,11 +266,8 @@ class tempe(object):
 		return map
 
 
-
-
-
 class station(object):
-	def __init__(self, args):	
+	def __init__(self, args):
 		self.definition = args
 		self.definition["id"]= "station"
 		self.definition["class"]= "epsbufr"
@@ -278,9 +275,8 @@ class station(object):
 		magics["definition"].append(self.definition)
 		return page()
 
-	
 class ps(object):
-	def __init__(self, args):	
+	def __init__(self, args):
 		self.definition = args
 		self.definition["format"]= "ps"
 	def execute(self):
@@ -289,8 +285,6 @@ class ps(object):
 		magics["drivers"].append(self.definition)
 		return page()
 
-	
-
 
 
 
@@ -306,8 +300,8 @@ def metgram(*args):
 		if (i == nb) :
 			haxis="haxis_last"
 		map["map"]["horizontal_axis"]["use_id"] = haxis
-		
-			
+
+
 	s = simplejson.dumps(magics, indent=4 * ' ')
 	f = tempfile.NamedTemporaryFile()
 	f.write(s)
@@ -317,9 +311,9 @@ def metgram(*args):
 
 	error = os.system(cmd)
 	if (error != 0):
-		print "Error found"
+		print("Error found - unix error: ", os.WEXITSTATUS(error) )
 	f.close
-	
+
 
 cloud = cloud()
 humidity = humidity()
@@ -327,4 +321,3 @@ precip = precip()
 tempe = tempe()
 msl = msl()
 wind = wind()
-
diff --git a/python/Magics/toolbox.py b/python/Magics/toolbox.py
index e1029f0..945d9de 100644
--- a/python/Magics/toolbox.py
+++ b/python/Magics/toolbox.py
@@ -1,24 +1,25 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
 
-import macro
+from . import macro
 
 def substitute(default, user):
     out = default
     if user != None:
         for key in user:
             out[key] = user[key]
-    
-  
-
     return out
 
 
-
-def geoplot(data, contour=None, output=None, background=None, foreground=None, area=None, legend = None, title = []):
-
+def geoplot(data, contour=None, output=None, background=None, foreground=None, area=None, title=[]):
 
     default = {
        "area" : {},
-       "legend" : {},
        "contour" : {},
        "background" : { "map_coastline_sea_shade"         : 'on',
                         "map_coastline_sea_shade_colour"  : 'rgb(81,81,81)',
@@ -35,23 +36,26 @@ def geoplot(data, contour=None, output=None, background=None, foreground=None, a
 
     }
 
-    background= macro.mcoast( substitute(default["background"], background) )
-    foreground= macro.mcoast( substitute(default["foreground"], foreground) ) 
+    background = macro.mcoast( substitute(default["background"], background) )
+    foreground = macro.mcoast( substitute(default["foreground"], foreground) )
+    projection = macro.mmap(   substitute(default["area"], area) )
+    contour    = macro.mcont(  substitute(default["contour"], contour) )
 
-    projection = macro.mmap( substitute(default["area"], area)
-                     )
-
-    contour = macro.mcont( substitute(default["contour"], contour) )
-   
-    legend = macro.mlegend(substitute(default["legend"], legend))
+    #Define the title
+    title = macro.mtext(
+                  text_lines = title,
+                  text_font_size = 0.8,
+                  text_justification = "left"
+                )
+    if output == None :
+      return macro.plot(projection, background, data, contour, foreground, title)
 
-    return macro.plot(output, projection, background, data, contour, foreground, title, legend)
+    return macro.plot(output, projection, background, data, contour, foreground, title)
 
 def xyplot(data, contour=None, output=None):
 
-
     default = {
-       "contour" : { } 
+       "contour" : {}
     }
 
     #Setting the cartesian view
@@ -74,29 +78,29 @@ def xyplot(data, contour=None, output=None):
                      axis_grid_line_style = "dot")
 
 
-    #Define the graph 
-    contour = macro.mcont( substitute(default["contour"], contour)
-                )
+    #Define the graph
+    contour = macro.mcont( substitute(default["contour"], contour))
+
     #Define the title
     title = macro.mtext(
                   text_font_size = 0.8,
                   text_justification = "left"
                 )
+    if output == None:
+      return macro.plot(output, projection, vertical, horizontal, data, contour, title)
 
     return macro.plot(output, projection, vertical, horizontal, data, contour, title)
 
-def graph(x,y, title="", graph = None) :
+def graph(x,y, title="", graph = None, colour = "ecmwf_blue") :
 
     default = {
-	   "graph" : { "graph_line_colour"  : "ecmwf_blue",
+     "graph" : { "graph_line_colour"  : "ecmwf_blue",
                     "graph_line_thickness" : 2,
-	   } 
+     }
     }
 
-    
     x[0] = x[0]*1.
     y[0] = y[0]*1.
-   
 
     #Setting the cartesian view
     projection = macro.mmap(subpage_map_projection = 'cartesian',
@@ -121,7 +125,7 @@ def graph(x,y, title="", graph = None) :
     input = macro.minput(input_x_values =  x,
                 input_y_values =  y)
 
-    #Define the graph 
+    #Define the graph
     graph = macro.mgraph( substitute(default["graph"], graph)
                 )
     #Define the title
@@ -140,12 +144,12 @@ defaults = {
             "subpage_map_projection" : 'cartesian',
             "subpage_x_axis_type" : 'date',
             "subpage_x_automatic" : 'on',
-            "subpage_y_axis_type" : 'regular', 
+            "subpage_y_axis_type" : 'regular',
             "subpage_y_automatic" : 'off',
             "subpage_y_max" : 43200.,
             "subpage_y_min" : -43200.,
        },
-         "vertical_axis" :  { 
+         "vertical_axis" :  {
               "axis_orientation" : "vertical",
               "axis_grid" : "on",
               "axis_grid_colour" : "navy",
@@ -169,12 +173,12 @@ defaults = {
             "subpage_map_projection" : 'cartesian',
             "subpage_x_axis_type" : 'date',
             "subpage_x_automatic" : 'on',
-            "subpage_y_axis_type" : 'regular', 
+            "subpage_y_axis_type" : 'regular',
             "subpage_y_automatic" : 'off',
             "subpage_y_max" : 43200.,
             "subpage_y_min" : -43200.,
        },
-         "vertical_axis" :  { 
+         "vertical_axis" :  {
               "axis_orientation" : "vertical",
               "axis_grid" : "on",
               "axis_grid_colour" : "navy",
@@ -187,7 +191,7 @@ defaults = {
               "axis_tick_label": "off"
 
               },
-      
+
          "epswave": {
                         "eps_rose_wind_border_colour": "Rgb(0.5000, 0.5000, 0.5000)",
                         "eps_rose_wind_colour": "RGB(0.925,0.609,0.953)",
@@ -195,71 +199,71 @@ defaults = {
                       },
   },
   "eps" :  {
-		   "projection" : {
-	        	"subpage_map_projection" : 'cartesian',
-	        	"subpage_x_axis_type" : 'date',
-	        	"subpage_x_automatic" : 'on',
-	        	"subpage_y_axis_type" : 'regular',
-	            "subpage_y_automatic" : 'on',
-		   },
-	       "vertical_axis" :  { 
-	            "axis_orientation" : "vertical",
-	            "axis_grid" : "on",
-	            "axis_grid_colour" : "navy",
-	            "axis_grid_line_style" :"dash",
-	            "axis_grid_reference_level" :  0.,
-	            "axis_grid_reference_thickness" : 1,
-	            "axis_line" :  "on",
-	            "axis_line_colour" : "navy",
-	            "axis_tick_colour" : "navy",
-	            "axis_tick_label_colour" : "navy",
-	            "axis_tick_label_height":  font_size
-	            },
-	        "horizontal_axis" :  { 
-	            "axis_orientation" : "horizontal",
-	            "axis_date_type" : "days",
-	            "axis_days_label" : "both",
-	            "axis_days_label_colour" :  "navy",
-	            "axis_days_label_height" : font_size,
-	            "axis_grid" :  "on",
-	            "axis_grid_colour" : "navy",
-	            "axis_grid_line_style" : "dash",
-	            "axis_line_colour" : "navy",
-	            "axis_minor_tick" : "off",
-	            "axis_minor_tick_colour" : "navy",
-	            "axis_months_label" : "off",
-	            "axis_tick_colour" : "navy",
-	            "axis_type" :  "date",
-	            "axis_years_label" : "off"
-	            },
-	        "epsgraph" : {
-	            "eps_box_border_thickness" : 2,
-	            "eps_box_width" : 1.5,
-	            "eps_box_colour" : colour,
-	            "eps_font_colour" :"navy",
-	            "eps_legend_font_size" :  font_size,
-	            "eps_grey_legend" : "off",
-	            "legend" :'off'
-	        },
-         
-	        "epsclim" : {
-	           "eps_shade_colour": colour,
-	           "eps_shade_line_thickness": 4,
-	        }
-    	}
+       "projection" : {
+            "subpage_map_projection" : 'cartesian',
+            "subpage_x_axis_type" : 'date',
+            "subpage_x_automatic" : 'on',
+            "subpage_y_axis_type" : 'regular',
+              "subpage_y_automatic" : 'on',
+       },
+         "vertical_axis" :  {
+              "axis_orientation" : "vertical",
+              "axis_grid" : "on",
+              "axis_grid_colour" : "navy",
+              "axis_grid_line_style" :"dash",
+              "axis_grid_reference_level" :  0.,
+              "axis_grid_reference_thickness" : 1,
+              "axis_line" :  "on",
+              "axis_line_colour" : "navy",
+              "axis_tick_colour" : "navy",
+              "axis_tick_label_colour" : "navy",
+              "axis_tick_label_height":  font_size
+              },
+          "horizontal_axis" :  {
+              "axis_orientation" : "horizontal",
+              "axis_date_type" : "days",
+              "axis_days_label" : "both",
+              "axis_days_label_colour" :  "navy",
+              "axis_days_label_height" : font_size,
+              "axis_grid" :  "on",
+              "axis_grid_colour" : "navy",
+              "axis_grid_line_style" : "dash",
+              "axis_line_colour" : "navy",
+              "axis_minor_tick" : "off",
+              "axis_minor_tick_colour" : "navy",
+              "axis_months_label" : "off",
+              "axis_tick_colour" : "navy",
+              "axis_type" :  "date",
+              "axis_years_label" : "off"
+              },
+          "epsgraph" : {
+              "eps_box_border_thickness" : 2,
+              "eps_box_width" : 1.5,
+              "eps_box_colour" : colour,
+              "eps_font_colour" :"navy",
+              "eps_legend_font_size" :  font_size,
+              "eps_grey_legend" : "off",
+              "legend" :'off'
+          },
+
+          "epsclim" : {
+             "eps_shade_colour": colour,
+             "eps_shade_line_thickness": 4,
+          }
+      }
     }
 
 
 def epswave(parameter, input, **args):
     actions = []
-   
+
     projection = macro.mmap( substitute(defaults["epswave"]["projection"], args.get("projection", None)) )
 
     # define horizontal axis
-    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))  
+    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))
     vertical = macro.maxis(substitute(defaults["epswave"]["vertical_axis"], args.get("vertical_axis", None)))
-   
-    
+
+
     data = macro.mwrepjson(
                             wrepjson_family =  "eps",
                             wrepjson_keyword =  "eps",
@@ -270,14 +274,14 @@ def epswave(parameter, input, **args):
                         )
 
     wave = macro.mepswave(substitute(defaults["epswave"]["epswave"], args.get("epswave", None)) )
-   
-    
+
+
     actions.append(projection)
     actions.append(vertical)
     actions.append(horizontal)
 
     actions.append(data)
-    actions.append(wave)           
+    actions.append(wave)
 
 
     text = macro.mtext(
@@ -293,20 +297,20 @@ def epswave(parameter, input, **args):
                 )
 
     actions.append(text)
-    
+
     if "output" in args != "" :
       #Setting of the output file name
-      png = macro.output(output_formats = ['png'], 
+      png = macro.output(output_formats = ['png'],
       output_name_first_page_number = "off",
-      output_name = args["output"], 
+      output_name = args["output"],
       super_page_y_length = 10.,
       subpage_y_length = 5.,
       subpage_y_position = 1.5)
 
-    return macro._plot(
-      png,
+      return macro._plot(
+        png,
             actions
-      ) 
+      )
 
     return macro.plot(
             actions
@@ -314,14 +318,14 @@ def epswave(parameter, input, **args):
 
 def epswind(parameter, input, **args):
     actions = []
-   
+
     projection = macro.mmap( substitute(defaults["epswind"]["projection"], args.get("projection", None)) )
 
     # define horizontal axis
-    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))  
+    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))
     vertical = macro.maxis(substitute(defaults["epswind"]["vertical_axis"], args.get("vertical_axis", None)))
-   
-    
+
+
     data = macro.mwrepjson(
                             wrepjson_family =  "eps",
                             wrepjson_keyword =  "eps",
@@ -332,14 +336,14 @@ def epswind(parameter, input, **args):
                         )
 
     wave = macro.mepswind(substitute(defaults["epswind"]["epswind"], args.get("epswind", None)) )
-   
-    
+
+
     actions.append(projection)
     actions.append(vertical)
     actions.append(horizontal)
 
     actions.append(data)
-    actions.append(wave)           
+    actions.append(wave)
 
 
     text = macro.mtext(
@@ -355,40 +359,39 @@ def epswind(parameter, input, **args):
                 )
 
     actions.append(text)
-    
+
     if "output" in args != "" :
       #Setting of the output file name
-      png = macro.output(output_formats = ['png'], 
+      png = macro.output(output_formats = ['png'],
       output_name_first_page_number = "off",
-      output_name = args["output"], 
+      output_name = args["output"],
       super_page_y_length = 10.,
       subpage_y_length = 5.,
       subpage_y_position = 1.5)
 
 
 
-    return macro._plot(
-      png,
-            actions
-      ) 
+      return macro._plot(
+        png,
+              actions
+        )
+
 
     return macro.plot(
             actions
     )
 
 def epsgraph(parameter, input, **args):
-    
-  
-    
+
     actions = []
-   
+
     projection = macro.mmap( substitute(defaults["eps"]["projection"], args.get("projection", None)) )
 
     # define horizontal axis
-    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))  
+    horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))
     vertical = macro.maxis(substitute(defaults["eps"]["vertical_axis"], args.get("vertical_axis", None)))
-   
-    
+
+
     data = macro.mwrepjson(
                             wrepjson_family =  "eps",
                             wrepjson_keyword =  "eps",
@@ -401,35 +404,31 @@ def epsgraph(parameter, input, **args):
                         )
 
     graph = macro.mepsgraph(substitute(defaults["eps"]["epsgraph"], args.get("epsgraph", None)) )
-   
-    
     actions.append(projection)
     actions.append(vertical)
     actions.append(horizontal)
+
     
-   
-    if "climate" in args  : 
-    	
-    	clim = macro.mwrepjson(
+
+    if "climate" in args  :
+      clim = macro.mwrepjson(
                             wrepjson_family =  "eps",
                             wrepjson_keyword =  "clim",
                             wrepjson_input_filename = input,
-                            wrepjson_parameter = parameter,         
+                            wrepjson_parameter = parameter,
                             wrepjson_parameter_scaling_factor = args.get("scaling", 1.),
                             wrepjson_parameter_offset_factor = args.get("offset", 0.),
                             wrepjson_ignore_keys = ["100"],
                             wrepjson_missing_value = args.get("missing", 9999.),
                             wrepjson_parameter_information = "none",
                             wrepjson_position_information = "off"
-
                         )
-        shade = macro.mepsshading(substitute(defaults["eps"]["epsclim"], args.get("epsclim", None)) )
-        actions.append(clim)
-        actions.append(shade)
-    
-    actions.append(data)
-    actions.append(graph)           
+      shade = macro.mepsshading(substitute(defaults["eps"]["epsclim"], args.get("epsclim", None)) )
+      actions.append(clim)
+      actions.append(shade)
 
+    actions.append(data)
+    actions.append(graph)
 
     text = macro.mtext(
                     text_colour =  "navy",
@@ -440,157 +439,162 @@ def epsgraph(parameter, input, **args):
                     "<json_info key='product_info'/><json_info key='date'/>",
                     "<font size='0.5' colour='white'>.</font>",
                     "<json_info key='parameter_info'/>",]
-
-                )
+                  )
 
     actions.append(text)
+
+   
     
     if "output" in args != "" :
-    	#Setting of the output file name
-		png = macro.output(output_formats = ['png'], 
-			output_name_first_page_number = "off",
-			output_name = args["output"], 
-      super_page_y_length = 10.,
-      subpage_y_length = 5.,
-      subpage_y_position = 1.,
+      #Setting of the output file name
+      png = macro.output(output_formats = ['png'],
+        output_name_first_page_number = "off",
+        output_name = args["output"],
+        super_page_y_length = 10.,
+        subpage_y_length = 5.,
+        subpage_y_position = 1.,
       )
-
-		return macro._plot(
-			png,
+      
+      return macro._plot(
+            png,
             actions
-    	)	
-
+      )
+    
+    
+    
     return macro.plot(
             actions
-    )
+      )
+
+
 
 
 def epsclimgram(**kw):
 
-	args = {"clim" :True }
-	args.update(kw)
+  args = {"clim" :True }
+  args.update(kw)
 
-	return epsgraph(**args)
+  return epsgraph(**args)
 
 params = {
     "2t": {
-        "scaling": 1.0, 
-        "offset": -273.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": -273.0,
+        "method": epsgraph,
         "title": "2-metre temperature"
-    }, 
+    },
     "mcc": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Medium cloud cover"
-    },   
+    },
      "light-index": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Light index"
-    }, 
+    },
     "10fg6": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "10 metre wind gust in the last 6 hours"
-    }, 
+    },
     "tp": {
-        "scaling": 1000., 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1000.,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Total precipitation (last 6 hours) (m)"
-    }, 
+    },
     "tcc": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Total cloud cover"
-    }, 
+    },
     "hcc": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "High cloud cover"
-    }, 
+    },
     "ws": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Wind speed (m/s)"
-    }, 
+    },
     "lcc": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Low cloud cover"
-    }, 
+    },
     "sf": {
-        "scaling": 1000.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1000.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Snowfall (last 6 hours)"
     },
     "swh": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Significant wave height"
-    }, 
+    },
     "mwp": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Mean wave period"
-    }, 
+    },
     "dwi": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epswind, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epswind,
         "title": "10 metre wind direction"
-    }, 
+    },
     "mwd": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epswave, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epswave,
         "title": "Mean wave direction"
     },
     "ws24": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Daily mean of 10m wind speed (m/s)"
-    }, 
+    },
     "tcc24": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Daily mean of total cloud cover"
-    }, 
+    },
     "mn2t24": {
-        "scaling": 1.0, 
-        "offset": -273.15, 
-        "method": epsgraph, 
+        "scaling": 1.0,
+        "offset": -273.15,
+        "method": epsgraph,
         "title": "2 metre min temperature (Daily)"
-    }, 
+    },
     "tp24": {
-        "scaling": 1000.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+        "scaling": 1000.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": "Total precipitation (mm/24hr)"
-    }, 
+    },
     "mx2t24": {
-        "scaling": 1., 
-        "offset": -273.15, 
-        "method": epsgraph, 
+        "scaling": 1.,
+        "offset": -273.15,
+        "method": epsgraph,
         "title": "2 metre max. temperature (Daily)"
-    }, 
+    },
     "dwi24": {
-        "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epswind, 
+        "scaling": 1.0,
+        "offset": 0.0,
+        "method": epswind,
         "title": "Daily distribution of 10m Wind Direction"
     }
 
@@ -609,18 +613,13 @@ params_15days = {   "mx2t24":"2 metre max. temperature (Daily)",
 
 
 def epsgram(parameter, input, **args):
-  eps = params.get(parameter, { "scaling": 1.0, 
-        "offset": 0.0, 
-        "method": epsgraph, 
+  eps = params.get(parameter, { "scaling": 1.0,
+        "offset": 0.0,
+        "method": epsgraph,
         "title": parameter} )
 
   args["scaling"] = eps["scaling"]
-  args["offset"] = eps["offset"]  
+  args["offset"] = eps["offset"]
   args["title"] = eps["title"]
-   
-  eps["method"](parameter, input, **args)
-
-
-
-
 
+  return eps["method"](parameter, input, **args)
diff --git a/python/Magics_interface.cc b/python/Magics_interface.cc
deleted file mode 100755
index 0728bd5..0000000
--- a/python/Magics_interface.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * (C) Copyright 1996-2016 ECMWF.
- * 
- * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
- * granted to it by virtue of its status as an intergovernmental organisation nor
- * does it submit to any jurisdiction.
- */
-
-#include <magics_api.h>
-
-void init() {
-  mag_open ();
-}
-
-void finalize() {
-  mag_close();
-}
-
-void coast() {
-  mag_coast();
-} 
-
-void grib() {
-  mag_grib();
-}
-
-void test() {
-  mag_test();
-}
-void legend() {
-  mag_legend();
-}
-
-void odb() {
-  mag_odb();
-}
-
-void netcdf() {
-  mag_netcdf();
-}
-
-void cont() {
-  mag_cont();
-}
-void minput() {
-  mag_input();
-}
-void mtable() {
-  mag_table();
-}
-void obs() {
-  mag_obs();
-}
-
-void raw() {
-  mag_raw();
-}
-
-void image() {
-  mag_image();
-}
-
-void plot() {
-  mag_plot();
-}
-
-void text() {
-  mag_text();
-}
-
-void wind() {
-  mag_wind();
-}
-void line() {
-  mag_line();
-}
-
-void symb() {
-  mag_symb();
-}
-
-void boxplot() {
-  mag_boxplot();
-} 
-void taylor() {
-  mag_taylor();
-} 
-void tephi() {
-  mag_tephi();
-} 
-
-void mimport() {
-  mag_import();
-}
-void mmetgraph() {
-  mag_metgraph();
-}
-void mmetbufr() {
-	mag_metbufr();
-}
-void wrepjson() {
-  mag_wrepjson();
-}
-
-void geojson() {
-  mag_geojson();
-}
-
-void metgraph() {
-  mag_epsinput();
-}
-
-void epsinput() {
-  mag_epsinput();
-}
-void epsgraph() {
-  mag_epsgraph();
-}
-
-void epscloud() {
-  mag_epscloud();
-}
-void epslight() {
-  mag_epslight();
-}
-void epsplumes() {
-  mag_epsplumes();
-}
- 
-void epswind() {
-  mag_epswind();
-}
-void epswave() {
-  mag_epswave();
-}
-
-void epsbar() {
-  mag_epsbar();
-}
-void epsshading() {
-  mag_epsshading();
- }
-
-void mapgen() {
-  mag_mapgen();
-}
-
-void new_page(const char* page)
-{
-  mag_new(page);
-}
-
-void reset(const char* name)
-{
-  mag_reset(name);
-}
-
-void setc(const char* name, const char* value)
-{
-  mag_setc(name, value);
-}
-
-void setr(const char* name, const double value)
-{
-  // std::cout << "setr "<<name<<" = "<<value<< std::endl;
-  mag_setr(name, value);
-}
-
-void seti(const char* name, const int value)
-{
-  mag_seti(name, value);
-}
-
-double enqr(const char* name)
-{
-  double value = 0.;
-  mag_enqr (name, &value);
-  return value;
-}
-
-int enqi(const char* name)
-{
-  int value = 0;
-  mag_enqi ( name, &value);
-  return value;
-}
-
-char* enqc (const char* name)
-{
-  char *value = 0;
-  mag_enqc (name, value);
-  // std::cout << "nnn" << name<< "  "<< value << std::endl;
-  return value;
-}
-
-void set1r(const char* name,double *data, const int dim)
-{
-  mag_set1r(name, data, dim);
-}
-
-void set2r(const char* name, double *data, const int dim1, const int dim2)
-{
- mag_set2r(name, data, dim2, dim1);
-}
-
-void set3r(const char* name, double *data, const int dim1, const int dim2, const int dim3)
-{
- mag_set3r(name, data, dim1, dim2, dim3);
-}
-
-void set1i(const char* name, int* data, const int dim)
-{
- mag_set1i(name, data, dim);
-}
-
-void set2i(const char* name, int *data, const int dim1, const int dim2)
-{
- mag_set2i(name, data, dim1, dim2);
-}
-
-void set3i(const char* name, int *data, const int dim1, const int dim2, const int dim3)
-{
- mag_set3i(name, data, dim1, dim2, dim3);
-}
-
-void set1c(const char* name, const char** data, const int dim)
-{
- mag_set1c(name, data, dim);
-}
-
-void pie() {
- mag_pie();
-}
-
-void graph() {
-  mag_graph();
-}
-
-void axis() {
-  mag_axis();
-}
-
-void geo() {
-  mag_geo();
-}
-
-void eps() {
-  mag_eps();
-}
-
-void info() {
-  mag_info();
-}
diff --git a/python/numpy.i b/python/numpy.i
deleted file mode 100644
index 644e968..0000000
--- a/python/numpy.i
+++ /dev/null
@@ -1,1634 +0,0 @@
-/* -*- C -*-  (not really, but good for syntax highlighting) */
-#ifdef SWIGPYTHON
-
-%{
-#ifndef SWIG_FILE_WITH_INIT
-#  define NO_IMPORT_ARRAY
-#endif
-#include "stdio.h"
-#include <numpy/arrayobject.h>
-%}
-
-/**********************************************************************/
-
-%fragment("NumPy_Backward_Compatibility", "header")
-{
-/* Support older NumPy data type names
-*/
-%#if NDARRAY_VERSION < 0x01000000
-%#define NPY_BOOL          PyArray_BOOL
-%#define NPY_BYTE          PyArray_BYTE
-%#define NPY_UBYTE         PyArray_UBYTE
-%#define NPY_SHORT         PyArray_SHORT
-%#define NPY_USHORT        PyArray_USHORT
-%#define NPY_INT           PyArray_INT
-%#define NPY_UINT          PyArray_UINT
-%#define NPY_LONG          PyArray_LONG
-%#define NPY_ULONG         PyArray_ULONG
-%#define NPY_LONGLONG      PyArray_LONGLONG
-%#define NPY_ULONGLONG     PyArray_ULONGLONG
-%#define NPY_FLOAT         PyArray_FLOAT
-%#define NPY_DOUBLE        PyArray_DOUBLE
-%#define NPY_LONGDOUBLE    PyArray_LONGDOUBLE
-%#define NPY_CFLOAT        PyArray_CFLOAT
-%#define NPY_CDOUBLE       PyArray_CDOUBLE
-%#define NPY_CLONGDOUBLE   PyArray_CLONGDOUBLE
-%#define NPY_OBJECT        PyArray_OBJECT
-%#define NPY_STRING        PyArray_STRING
-%#define NPY_UNICODE       PyArray_UNICODE
-%#define NPY_VOID          PyArray_VOID
-%#define NPY_NTYPES        PyArray_NTYPES
-%#define NPY_NOTYPE        PyArray_NOTYPE
-%#define NPY_CHAR          PyArray_CHAR
-%#define NPY_USERDEF       PyArray_USERDEF
-%#define npy_intp          intp
-
-%#define NPY_MAX_BYTE      MAX_BYTE
-%#define NPY_MIN_BYTE      MIN_BYTE
-%#define NPY_MAX_UBYTE     MAX_UBYTE
-%#define NPY_MAX_SHORT     MAX_SHORT
-%#define NPY_MIN_SHORT     MIN_SHORT
-%#define NPY_MAX_USHORT    MAX_USHORT
-%#define NPY_MAX_INT       MAX_INT
-%#define NPY_MIN_INT       MIN_INT
-%#define NPY_MAX_UINT      MAX_UINT
-%#define NPY_MAX_LONG      MAX_LONG
-%#define NPY_MIN_LONG      MIN_LONG
-%#define NPY_MAX_ULONG     MAX_ULONG
-%#define NPY_MAX_LONGLONG  MAX_LONGLONG
-%#define NPY_MIN_LONGLONG  MIN_LONGLONG
-%#define NPY_MAX_ULONGLONG MAX_ULONGLONG
-%#define NPY_MAX_INTP      MAX_INTP
-%#define NPY_MIN_INTP      MIN_INTP
-
-%#define NPY_FARRAY        FARRAY
-%#define NPY_F_CONTIGUOUS  F_CONTIGUOUS
-%#endif
-}
-
-/**********************************************************************/
-
-/* The following code originally appeared in
- * enthought/kiva/agg/src/numeric.i written by Eric Jones.  It was
- * translated from C++ to C by John Hunter.  Bill Spotz has modified
- * it to fix some minor bugs, upgrade from Numeric to numpy (all
- * versions), add some comments and functionality, and convert from
- * direct code insertion to SWIG fragments.
- */
-
-%fragment("NumPy_Macros", "header")
-{
-/* Macros to extract array attributes.
- */
-%#define is_array(a)            ((a) && PyArray_Check((PyArrayObject *)a))
-%#define array_type(a)          (int)(PyArray_TYPE(a))
-%#define array_numdims(a)       (((PyArrayObject *)a)->nd)
-%#define array_dimensions(a)    (((PyArrayObject *)a)->dimensions)
-%#define array_size(a,i)        (((PyArrayObject *)a)->dimensions[i])
-%#define array_data(a)          (((PyArrayObject *)a)->data)
-%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
-%#define array_is_native(a)     (PyArray_ISNOTSWAPPED(a))
-%#define array_is_fortran(a)    (PyArray_ISFORTRAN(a))
-}
-
-/**********************************************************************/
-
-%fragment("NumPy_Utilities", "header")
-{
-  /* Given a PyObject, return a string describing its type.
-   */
-  const char* pytype_string(PyObject* py_obj) {
-    if (py_obj == NULL          ) return "C NULL value";
-    if (py_obj == Py_None       ) return "Python None" ;
-    if (PyCallable_Check(py_obj)) return "callable"    ;
-    if (PyString_Check(  py_obj)) return "string"      ;
-    if (PyInt_Check(     py_obj)) return "int"         ;
-    if (PyFloat_Check(   py_obj)) return "float"       ;
-    if (PyDict_Check(    py_obj)) return "dict"        ;
-    if (PyList_Check(    py_obj)) return "list"        ;
-    if (PyTuple_Check(   py_obj)) return "tuple"       ;
-    if (PyFile_Check(    py_obj)) return "file"        ;
-    if (PyModule_Check(  py_obj)) return "module"      ;
-    if (PyInstance_Check(py_obj)) return "instance"    ;
-
-    return "unknown type";
-  }
-
-  /* Given a NumPy typecode, return a string describing the type.
-   */
-  const char* typecode_string(int typecode) {
-    static const char* type_names[25] = {"bool", "byte", "unsigned byte",
-                                   "short", "unsigned short", "int",
-                                   "unsigned int", "long", "unsigned long",
-                                   "long long", "unsigned long long",
-                                   "float", "double", "long double",
-                                   "complex float", "complex double",
-                                   "complex long double", "object",
-                                   "string", "unicode", "void", "ntypes",
-                                   "notype", "char", "unknown"};
-    return typecode < 24 ? type_names[typecode] : type_names[24];
-  }
-
-  /* Make sure input has correct numpy type.  Allow character and byte
-   * to match.  Also allow int and long to match.  This is deprecated.
-   * You should use PyArray_EquivTypenums() instead.
-   */
-  int type_match(int actual_type, int desired_type) {
-    return PyArray_EquivTypenums(actual_type, desired_type);
-  }
-}
-
-/**********************************************************************/
-
-%fragment("NumPy_Object_to_Array", "header",
-          fragment="NumPy_Backward_Compatibility",
-          fragment="NumPy_Macros",
-          fragment="NumPy_Utilities")
-{
-  /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
-   * legal.  If not, set the python error string appropriately and
-   * return NULL.
-   */
-  PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
-  {
-    PyArrayObject* ary = NULL;
-    if (is_array(input) && (typecode == NPY_NOTYPE ||
-                            PyArray_EquivTypenums(array_type(input), typecode)))
-    {
-      ary = (PyArrayObject*) input;
-    }
-    else if is_array(input)
-    {
-      const char* desired_type = typecode_string(typecode);
-      const char* actual_type  = typecode_string(array_type(input));
-      PyErr_Format(PyExc_TypeError,
-                   "Array of type '%s' required.  Array of type '%s' given",
-                   desired_type, actual_type);
-      ary = NULL;
-    }
-    else
-    {
-      const char * desired_type = typecode_string(typecode);
-      const char * actual_type  = pytype_string(input);
-      PyErr_Format(PyExc_TypeError,
-                   "Array of type '%s' required.  A '%s' was given",
-                   desired_type, actual_type);
-      ary = NULL;
-    }
-    return ary;
-  }
-
-  /* Convert the given PyObject to a NumPy array with the given
-   * typecode.  On success, return a valid PyArrayObject* with the
-   * correct type.  On failure, the python error string will be set and
-   * the routine returns NULL.
-   */
-  PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
-                                               int* is_new_object)
-  {
-    PyArrayObject* ary = NULL;
-    PyObject* py_obj;
-    if (is_array(input) && (typecode == NPY_NOTYPE ||
-                            PyArray_EquivTypenums(array_type(input),typecode)))
-    {
-      ary = (PyArrayObject*) input;
-      *is_new_object = 0;
-    }
-    else
-    {
-      py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_DEFAULT);
-      /* If NULL, PyArray_FromObject will have set python error value.*/
-      ary = (PyArrayObject*) py_obj;
-      *is_new_object = 1;
-    }
-    return ary;
-  }
-
-  /* Given a PyArrayObject, check to see if it is contiguous.  If so,
-   * return the input pointer and flag it as not a new object.  If it is
-   * not contiguous, create a new PyArrayObject using the original data,
-   * flag it as a new object and return the pointer.
-   */
-  PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
-                                 int min_dims, int max_dims)
-  {
-    PyArrayObject* result;
-    if (array_is_contiguous(ary))
-    {
-      result = ary;
-      *is_new_object = 0;
-    }
-    else
-    {
-      result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
-                                                             array_type(ary),
-                                                             min_dims,
-                                                             max_dims);
-      *is_new_object = 1;
-    }
-    return result;
-  }
-
-  /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
-   * If so, return the input pointer, but do not flag it as not a new
-   * object.  If it is not Fortran-contiguous, create a new
-   * PyArrayObject using the original data, flag it as a new object
-   * and return the pointer.
-   */
-  PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object,
-                              int min_dims, int max_dims)
-  {
-    PyArrayObject* result;
-    if (array_is_fortran(ary))
-    {
-      result = ary;
-      *is_new_object = 0;
-    }
-    else
-    {
-      Py_INCREF(ary->descr);
-      result = (PyArrayObject*) PyArray_FromArray(ary, ary->descr, NPY_FORTRAN);
-      *is_new_object = 1;
-    }
-    return result;
-  }
-
-  /* Convert a given PyObject to a contiguous PyArrayObject of the
-   * specified type.  If the input object is not a contiguous
-   * PyArrayObject, a new one will be created and the new object flag
-   * will be set.
-   */
-  PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
-                                                          int typecode,
-                                                          int* is_new_object)
-  {
-    int is_new1 = 0;
-    int is_new2 = 0;
-    PyArrayObject* ary2;
-    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
-                                                        &is_new1);
-    if (ary1)
-    {
-      ary2 = make_contiguous(ary1, &is_new2, 0, 0);
-      if ( is_new1 && is_new2)
-      {
-        Py_DECREF(ary1);
-      }
-      ary1 = ary2;
-    }
-    *is_new_object = is_new1 || is_new2;
-    return ary1;
-  }
-
-  /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
-   * specified type.  If the input object is not a Fortran-ordered
-   * PyArrayObject, a new one will be created and the new object flag
-   * will be set.
-   */
-  PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
-                                                       int typecode,
-                                                       int* is_new_object)
-  {
-    int is_new1 = 0;
-    int is_new2 = 0;
-    PyArrayObject* ary2;
-    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
-                                                        &is_new1);
-    if (ary1)
-    {
-      ary2 = make_fortran(ary1, &is_new2, 0, 0);
-      if (is_new1 && is_new2)
-      {
-        Py_DECREF(ary1);
-      }
-      ary1 = ary2;
-    }
-    *is_new_object = is_new1 || is_new2;
-    return ary1;
-  }
-
-} /* end fragment */
-
-
-/**********************************************************************/
-
-%fragment("NumPy_Array_Requirements", "header",
-          fragment="NumPy_Backward_Compatibility",
-          fragment="NumPy_Macros")
-{
-  /* Test whether a python object is contiguous.  If array is
-   * contiguous, return 1.  Otherwise, set the python error string and
-   * return 0.
-   */
-  int require_contiguous(PyArrayObject* ary)
-  {
-    int contiguous = 1;
-    if (!array_is_contiguous(ary))
-    {
-      PyErr_SetString(PyExc_TypeError,
-                      "Array must be contiguous.  A non-contiguous array was given");
-      contiguous = 0;
-    }
-    return contiguous;
-  }
-
-  /* Require that a numpy array is not byte-swapped.  If the array is
-   * not byte-swapped, return 1.  Otherwise, set the python error string
-   * and return 0.
-   */
-  int require_native(PyArrayObject* ary)
-  {
-    int native = 1;
-    if (!array_is_native(ary))
-    {
-      PyErr_SetString(PyExc_TypeError,
-                      "Array must have native byteorder.  "
-                      "A byte-swapped array was given");
-      native = 0;
-    }
-    return native;
-  }
-
-  /* Require the given PyArrayObject to have a specified number of
-   * dimensions.  If the array has the specified number of dimensions,
-   * return 1.  Otherwise, set the python error string and return 0.
-   */
-  int require_dimensions(PyArrayObject* ary, int exact_dimensions)
-  {
-    int success = 1;
-    if (array_numdims(ary) != exact_dimensions)
-    {
-      PyErr_Format(PyExc_TypeError,
-                   "Array must have %d dimensions.  Given array has %d dimensions",
-                   exact_dimensions, array_numdims(ary));
-      success = 0;
-    }
-    return success;
-  }
-
-  /* Require the given PyArrayObject to have one of a list of specified
-   * number of dimensions.  If the array has one of the specified number
-   * of dimensions, return 1.  Otherwise, set the python error string
-   * and return 0.
-   */
-  int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
-  {
-    int success = 0;
-    int i;
-    char dims_str[255] = "";
-    char s[255];
-    for (i = 0; i < n && !success; i++)
-    {
-      if (array_numdims(ary) == exact_dimensions[i])
-      {
-        success = 1;
-      }
-    }
-    if (!success)
-    {
-      for (i = 0; i < n-1; i++)
-      {
-        sprintf(s, "%d, ", exact_dimensions[i]);
-        strcat(dims_str,s);
-      }
-      sprintf(s, " or %d", exact_dimensions[n-1]);
-      strcat(dims_str,s);
-      PyErr_Format(PyExc_TypeError,
-                   "Array must have %s dimensions.  Given array has %d dimensions",
-                   dims_str, array_numdims(ary));
-    }
-    return success;
-  }
-
-  /* Require the given PyArrayObject to have a specified shape.  If the
-   * array has the specified shape, return 1.  Otherwise, set the python
-   * error string and return 0.
-   */
-  int require_size(PyArrayObject* ary, npy_intp* size, int n)
-  {
-    int i;
-    int success = 1;
-    int len;
-    char desired_dims[255] = "[";
-    char s[255];
-    char actual_dims[255] = "[";
-    for(i=0; i < n;i++)
-    {
-      if (size[i] != -1 &&  size[i] != array_size(ary,i))
-      {
-        success = 0;
-      }
-    }
-    if (!success)
-    {
-      for (i = 0; i < n; i++)
-      {
-        if (size[i] == -1)
-        {
-          sprintf(s, "*,");
-        }
-        else
-        {
-          sprintf(s, "%ld,", (long int)size[i]);
-        }
-        strcat(desired_dims,s);
-      }
-      len = strlen(desired_dims);
-      desired_dims[len-1] = ']';
-      for (i = 0; i < n; i++)
-      {
-        sprintf(s, "%ld,", (long int)array_size(ary,i));
-        strcat(actual_dims,s);
-      }
-      len = strlen(actual_dims);
-      actual_dims[len-1] = ']';
-      PyErr_Format(PyExc_TypeError,
-                   "Array must have shape of %s.  Given array has shape of %s",
-                   desired_dims, actual_dims);
-    }
-    return success;
-  }
-
-  /* Require the given PyArrayObject to to be FORTRAN ordered.  If the
-   * the PyArrayObject is already FORTRAN ordered, do nothing.  Else,
-   * set the FORTRAN ordering flag and recompute the strides.
-   */
-  int require_fortran(PyArrayObject* ary)
-  {
-    int success = 1;
-    int nd = array_numdims(ary);
-    int i;
-    if (array_is_fortran(ary)) return success;
-    /* Set the FORTRAN ordered flag */
-    ary->flags = NPY_FARRAY;
-    /* Recompute the strides */
-    ary->strides[0] = ary->strides[nd-1];
-    for (i=1; i < nd; ++i)
-      ary->strides[i] = ary->strides[i-1] * array_size(ary,i-1);
-    return success;
-  }
-}
-
-/* Combine all NumPy fragments into one for convenience */
-%fragment("NumPy_Fragments", "header",
-          fragment="NumPy_Backward_Compatibility",
-          fragment="NumPy_Macros",
-          fragment="NumPy_Utilities",
-          fragment="NumPy_Object_to_Array",
-          fragment="NumPy_Array_Requirements") { }
-
-/* End John Hunter translation (with modifications by Bill Spotz)
- */
-
-/* %numpy_typemaps() macro
- *
- * This macro defines a family of 41 typemaps that allow C arguments
- * of the form
- *
- *     (DATA_TYPE IN_ARRAY1[ANY])
- *     (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
- *
- *     (DATA_TYPE IN_ARRAY2[ANY][ANY])
- *     (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
- *     (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
- *
- *     (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
- *     (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
- *     (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
- *
- *     (DATA_TYPE INPLACE_ARRAY1[ANY])
- *     (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
- *
- *     (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
- *     (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
- *     (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
- *
- *     (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
- *     (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
- *     (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
- *
- *     (DATA_TYPE ARGOUT_ARRAY1[ANY])
- *     (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
- *
- *     (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
- *
- *     (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
- *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
- *     (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
- *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
- *     (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
- *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
- *     (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
- *
- * where "DATA_TYPE" is any type supported by the NumPy module, and
- * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
- * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
- * that the "FARRAY" typemaps expect FORTRAN ordering of
- * multidimensional arrays.  In python, the dimensions will not need
- * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
- * typemaps).  The IN_ARRAYs can be a numpy array or any sequence that
- * can be converted to a numpy array of the specified type.  The
- * INPLACE_ARRAYs must be numpy arrays of the appropriate type.  The
- * ARGOUT_ARRAYs will be returned as new numpy arrays of the
- * appropriate type.
- *
- * These typemaps can be applied to existing functions using the
- * %apply directive.  For example:
- *
- *     %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
- *     double prod(double* series, int length);
- *
- *     %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
- *           {(int rows, int cols, double* matrix        )};
- *     void floor(int rows, int cols, double* matrix, double f);
- *
- *     %apply (double IN_ARRAY3[ANY][ANY][ANY])
- *           {(double tensor[2][2][2]         )};
- *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
- *           {(double low[2][2][2]                )};
- *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
- *           {(double upp[2][2][2]                )};
- *     void luSplit(double tensor[2][2][2],
- *                  double low[2][2][2],
- *                  double upp[2][2][2]    );
- *
- * or directly with
- *
- *     double prod(double* IN_ARRAY1, int DIM1);
- *
- *     void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
- *
- *     void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
- *                  double ARGOUT_ARRAY3[ANY][ANY][ANY],
- *                  double ARGOUT_ARRAY3[ANY][ANY][ANY]);
- */
-
-%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
-
-/************************/
-/* Input Array Typemaps */
-/************************/
-
-/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE IN_ARRAY1[ANY])
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE IN_ARRAY1[ANY])
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[1] = { $1_dim0 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 1) ||
-      !require_size(array, size, 1)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(freearg)
-  (DATA_TYPE IN_ARRAY1[ANY])
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[1] = { -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 1) ||
-      !require_size(array, size, 1)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-}
-%typemap(freearg)
-  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[1] = {-1};
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 1) ||
-      !require_size(array, size, 1)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DATA_TYPE*) array_data(array);
-}
-%typemap(freearg)
-  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE IN_ARRAY2[ANY][ANY])
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE IN_ARRAY2[ANY][ANY])
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[2] = { $1_dim0, $1_dim1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 2) ||
-      !require_size(array, size, 2)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(freearg)
-  (DATA_TYPE IN_ARRAY2[ANY][ANY])
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 2) ||
-      !require_size(array, size, 2)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-}
-%typemap(freearg)
-  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 2) ||
-      !require_size(array, size, 2)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DATA_TYPE*) array_data(array);
-}
-%typemap(freearg)
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
-                                                &is_new_object);
-  if (!array || !require_dimensions(array, 2) ||
-      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-}
-%typemap(freearg)
-  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 2) ||
-      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DATA_TYPE*) array_data(array);
-}
-%typemap(freearg)
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 3) ||
-      !require_size(array, size, 3)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(freearg)
-  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
- *                    DIM_TYPE DIM3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[3] = { -1, -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 3) ||
-      !require_size(array, size, 3)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-  $4 = (DIM_TYPE) array_size(array,2);
-}
-%typemap(freearg)
-  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
- *                    DATA_TYPE* IN_ARRAY3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[3] = { -1, -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 3) ||
-      !require_size(array, size, 3)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DIM_TYPE) array_size(array,2);
-  $4 = (DATA_TYPE*) array_data(array);
-}
-%typemap(freearg)
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
- *                    DIM_TYPE DIM3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[3] = { -1, -1, -1 };
-  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
-                                                &is_new_object);
-  if (!array || !require_dimensions(array, 3) ||
-      !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-  $4 = (DIM_TYPE) array_size(array,2);
-}
-%typemap(freearg)
-  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
- *                    DATA_TYPE* IN_FARRAY3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
-{
-  $1 = is_array($input) || PySequence_Check($input);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
-  (PyArrayObject* array=NULL, int is_new_object=0)
-{
-  npy_intp size[3] = { -1, -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
-                                                   &is_new_object);
-  if (!array || !require_dimensions(array, 3) ||
-      !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DIM_TYPE) array_size(array,2);
-  $4 = (DATA_TYPE*) array_data(array);
-}
-%typemap(freearg)
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
-{
-  if (is_new_object$argnum && array$argnum)
-    { Py_DECREF(array$argnum); }
-}
-
-/***************************/
-/* In-Place Array Typemaps */
-/***************************/
-
-/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE INPLACE_ARRAY1[ANY])
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE INPLACE_ARRAY1[ANY])
-  (PyArrayObject* array=NULL)
-{
-  npy_intp size[1] = { $1_dim0 };
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
-      !require_contiguous(array) || !require_native(array)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
-  (PyArrayObject* array=NULL, int i=1)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
-      || !require_native(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = 1;
-  for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
-  (PyArrayObject* array=NULL, int i=0)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
-      || !require_native(array)) SWIG_fail;
-  $1 = 1;
-  for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
-  $2 = (DATA_TYPE*) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
-  (PyArrayObject* array=NULL)
-{
-  npy_intp size[2] = { $1_dim0, $1_dim1 };
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
-      !require_contiguous(array) || !require_native(array)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
-      || !require_native(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
-      !require_native(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DATA_TYPE*) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
-      || !require_native(array) || !require_fortran(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
-      !require_native(array) || !require_fortran(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DATA_TYPE*) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
-  (PyArrayObject* array=NULL)
-{
-  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
-      !require_contiguous(array) || !require_native(array)) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
- *                    DIM_TYPE DIM3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
-      !require_native(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-  $4 = (DIM_TYPE) array_size(array,2);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
- *                    DATA_TYPE* INPLACE_ARRAY3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
-      || !require_native(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DIM_TYPE) array_size(array,2);
-  $4 = (DATA_TYPE*) array_data(array);
-}
-
-/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
- *                    DIM_TYPE DIM3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
-      !require_native(array) || !require_fortran(array)) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-  $2 = (DIM_TYPE) array_size(array,0);
-  $3 = (DIM_TYPE) array_size(array,1);
-  $4 = (DIM_TYPE) array_size(array,2);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
- *                    DATA_TYPE* INPLACE_FARRAY3)
- */
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
-           fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
-{
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
-}
-%typemap(in,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
-  (PyArrayObject* array=NULL)
-{
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
-      || !require_native(array) || !require_fortran(array)) SWIG_fail;
-  $1 = (DIM_TYPE) array_size(array,0);
-  $2 = (DIM_TYPE) array_size(array,1);
-  $3 = (DIM_TYPE) array_size(array,2);
-  $4 = (DATA_TYPE*) array_data(array);
-}
-
-/*************************/
-/* Argout Array Typemaps */
-/*************************/
-
-/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
- */
-%typemap(in,numinputs=0,
-         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
-  (DATA_TYPE ARGOUT_ARRAY1[ANY])
-  (PyObject * array = NULL)
-{
-  npy_intp dims[1] = { $1_dim0 };
-  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
-  if (!array) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(argout)
-  (DATA_TYPE ARGOUT_ARRAY1[ANY])
-{
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
-}
-
-/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
- */
-%typemap(in,numinputs=1,
-         fragment="NumPy_Fragments")
-  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
-  (PyObject * array = NULL)
-{
-  npy_intp dims[1];
-  if (!PyInt_Check($input))
-  {
-    const char* typestring = pytype_string($input);
-    PyErr_Format(PyExc_TypeError,
-                 "Int dimension expected.  '%s' given.",
-                 typestring);
-    SWIG_fail;
-  }
-  $2 = (DIM_TYPE) PyInt_AsLong($input);
-  dims[0] = (npy_intp) $2;
-  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
-  if (!array) SWIG_fail;
-  $1 = (DATA_TYPE*) array_data(array);
-}
-%typemap(argout)
-  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
-{
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
-}
-
-/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
- */
-%typemap(in,numinputs=1,
-         fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
-  (PyObject * array = NULL)
-{
-  npy_intp dims[1];
-  if (!PyInt_Check($input))
-  {
-    const char* typestring = pytype_string($input);
-    PyErr_Format(PyExc_TypeError,
-                 "Int dimension expected.  '%s' given.",
-                 typestring);
-    SWIG_fail;
-  }
-  $1 = (DIM_TYPE) PyInt_AsLong($input);
-  dims[0] = (npy_intp) $1;
-  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
-  if (!array) SWIG_fail;
-  $2 = (DATA_TYPE*) array_data(array);
-}
-%typemap(argout)
-  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
-{
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
-}
-
-/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
- */
-%typemap(in,numinputs=0,
-         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
-  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
-  (PyObject * array = NULL)
-{
-  npy_intp dims[2] = { $1_dim0, $1_dim1 };
-  array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
-  if (!array) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(argout)
-  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
-{
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
-}
-
-/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
- */
-%typemap(in,numinputs=0,
-         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
-  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
-  (PyObject * array = NULL)
-{
-  npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
-  array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
-  if (!array) SWIG_fail;
-  $1 = ($1_ltype) array_data(array);
-}
-%typemap(argout)
-  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
-{
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
-}
-
-/*****************************/
-/* Argoutview Array Typemaps */
-/*****************************/
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
- */
-%typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1    )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim_temp)
-{
-  $1 = &data_temp;
-  $2 = &dim_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
-{
-  npy_intp dims[1] = { *$2 };
-  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
- */
-%typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEW_ARRAY1)
-  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp        )
-{
-  $1 = &dim_temp;
-  $2 = &data_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
-{
-  npy_intp dims[1] = { *$1 };
-  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- */
-%typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
-{
-  $1 = &data_temp;
-  $2 = &dim1_temp;
-  $3 = &dim2_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
-{
-  npy_intp dims[2] = { *$2, *$3 };
-  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
- */
-%typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_ARRAY2)
-  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
-{
-  $1 = &dim1_temp;
-  $2 = &dim2_temp;
-  $3 = &data_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
-{
-  npy_intp dims[2] = { *$1, *$2 };
-  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- */
-%typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
-{
-  $1 = &data_temp;
-  $2 = &dim1_temp;
-  $3 = &dim2_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
-  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
-{
-  npy_intp dims[2] = { *$2, *$3 };
-  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || !require_fortran(array)) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
- */
-%typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_FARRAY2)
-  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
-{
-  $1 = &dim1_temp;
-  $2 = &dim2_temp;
-  $3 = &data_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
-{
-  npy_intp dims[2] = { *$1, *$2 };
-  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || !require_fortran(array)) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
-                      DIM_TYPE* DIM3)
- */
-%typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
-{
-  $1 = &data_temp;
-  $2 = &dim1_temp;
-  $3 = &dim2_temp;
-  $4 = &dim3_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-{
-  npy_intp dims[3] = { *$2, *$3, *$4 };
-  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
-                      DATA_TYPE** ARGOUTVIEW_ARRAY3)
- */
-%typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
-  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
-{
-  $1 = &dim1_temp;
-  $2 = &dim2_temp;
-  $3 = &dim3_temp;
-  $4 = &data_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility")
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
-{
-  npy_intp dims[3] = { *$1, *$2, *$3 };
-  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
-  if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
-                      DIM_TYPE* DIM3)
- */
-%typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
-{
-  $1 = &data_temp;
-  $2 = &dim1_temp;
-  $3 = &dim2_temp;
-  $4 = &dim3_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
-  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-{
-  npy_intp dims[3] = { *$2, *$3, *$4 };
-  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || require_fortran(array)) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
-                      DATA_TYPE** ARGOUTVIEW_FARRAY3)
- */
-%typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
-  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
-{
-  $1 = &dim1_temp;
-  $2 = &dim2_temp;
-  $3 = &dim3_temp;
-  $4 = &data_temp;
-}
-%typemap(argout,
-         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
-{
-  npy_intp dims[3] = { *$1, *$2, *$3 };
-  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || require_fortran(array)) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-%enddef    /* %numpy_typemaps() macro */
-/* *************************************************************** */
-
-/* Concrete instances of the %numpy_typemaps() macro: Each invocation
- * below applies all of the typemaps above to the specified data type.
- */
-%numpy_typemaps(signed char       , NPY_BYTE     , int)
-%numpy_typemaps(unsigned char     , NPY_UBYTE    , int)
-%numpy_typemaps(short             , NPY_SHORT    , int)
-%numpy_typemaps(unsigned short    , NPY_USHORT   , int)
-%numpy_typemaps(int               , NPY_INT      , int)
-%numpy_typemaps(unsigned int      , NPY_UINT     , int)
-%numpy_typemaps(long              , NPY_LONG     , int)
-%numpy_typemaps(unsigned long     , NPY_ULONG    , int)
-%numpy_typemaps(long long         , NPY_LONGLONG , int)
-%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
-%numpy_typemaps(float             , NPY_FLOAT    , int)
-%numpy_typemaps(double            , NPY_DOUBLE   , int)
-
-/* ***************************************************************
- * The follow macro expansion does not work, because C++ bool is 4
- * bytes and NPY_BOOL is 1 byte
- *
- *    %numpy_typemaps(bool, NPY_BOOL, int)
- */
-
-/* ***************************************************************
- * On my Mac, I get the following warning for this macro expansion:
- * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
- *
- *    %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
- */
-
-/* ***************************************************************
- * Swig complains about a syntax error for the following macro
- * expansions:
- *
- *    %numpy_typemaps(complex float,  NPY_CFLOAT , int)
- *
- *    %numpy_typemaps(complex double, NPY_CDOUBLE, int)
- *
- *    %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
- */
-
-#endif /* SWIGPYTHON */
diff --git a/python/setup.py.in b/python/setup.py.in
index b83225c..54e76c6 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -4,23 +4,6 @@ from distutils.core import setup, Extension
 import os
 import sys
 
-import numpy
-# Obtain the numpy include directory.  This logic works across numpy versions.
-try:
-    numpy_include = numpy.get_include()
-except AttributeError:
-    numpy_include = numpy.get_numpy_include()
-
-
-attdict = dict(
-   sources               = ['Magics/Magics.i'],
-   swig_opts             = ['-c++'],
-   include_dirs          = ['.', '@CMAKE_CURRENT_SOURCE_DIR@/../src/common',numpy_include],
-   library_dirs          = ["@CMAKE_BINARY_DIR@/lib"],
-   libraries             = ["MagPlus","m"],
-   extra_objects         = [],
-)
-
 setup (name         = 'Magics',
        version      = '@MAGICS_VERSION_STR@',
        author       = 'ECMWF',
@@ -28,6 +11,5 @@ setup (name         = 'Magics',
        description  = """Magics Python interface""",
        license      = 'Apache License, Version 2.0',
        url          = 'https://software.ecmwf.int/Magics',
-       ext_modules  = [Extension('Magics._Magics',**attdict)],
        packages     = ['Magics'],
       )
diff --git a/python/test_for_ctypes/array.py b/python/test_for_ctypes/array.py
new file mode 100755
index 0000000..3a13b9b
--- /dev/null
+++ b/python/test_for_ctypes/array.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+
+import Magics as Magics
+import numpy
+import math
+
+def f(x,y):
+#	return ((math.sin((x-180.)/(2.*math.pi)))-(math.cos((y-90.)/(2.*math.pi))))
+#	return ( (x-180.) + (y-90.)*3 )
+	return (y-90.)
+
+
+Magics.init ()
+Magics.setc("output_format","ps")
+Magics.setc("output_name",  "py_arrays")
+
+Magics.setr("INPUT_FIELD_INITIAL_LATITUDE",90.0)
+Magics.setr("INPUT_FIELD_INITIAL_LONGITUDE",0.0)
+Magics.setr("INPUT_FIELD_LATITUDE_STEP",-1.5)
+Magics.setr("INPUT_FIELD_LONGITUDE_STEP",1.5)
+
+NLON =360
+NLAT =180
+
+FIELD = numpy.fromfunction(f,(NLAT,NLON),dtype=numpy.float64)
+
+Magics.set2r("INPUT_FIELD",FIELD,360,180)
+Magics.setr("INPUT_FIELD_INITIAL_LONGITUDE",-180.)
+Magics.setr("INPUT_FIELD_INITIAL_LATITUDE",90.)
+Magics.setr("INPUT_FIELD_LONGITUDE_STEP",1.)
+Magics.setr("INPUT_FIELD_LATITUDE_STEP",-1.)
+
+
+Magics.setc("map_coastline_colour", "khaki")
+Magics.setc("map_grid_colour",      "grey")
+
+Magics.setc("contour",  		"on")
+Magics.setc("contour_line_colour",	"sky")
+Magics.setc("CONTOUR_HIGHLIGHT_COLOUR", "GREEN")
+Magics.setc("contour_label",		"on")
+Magics.cont()
+
+Magics.text()
+Magics.coast()
+
+Magics.new_page ("SUPER_PAGE")
+
+Magics.setr("SUBPAGE_LOWER_LEFT_LATITUDE",    30.0)
+Magics.setr("SUBPAGE_LOWER_LEFT_LONGITUDE",  -30.0)
+Magics.setr("SUBPAGE_UPPER_RIGHT_LATITUDE",   65.0)
+Magics.setr("SUBPAGE_UPPER_RIGHT_LONGITUDE",  70.0)
+
+Magics.cont()
+Magics.text()
+Magics.coast()
+
+Magics.finalize()
diff --git a/python/test_for_ctypes/test_ctypes.py b/python/test_for_ctypes/test_ctypes.py
new file mode 100644
index 0000000..9c6561a
--- /dev/null
+++ b/python/test_for_ctypes/test_ctypes.py
@@ -0,0 +1,28 @@
+import Magics as ma
+
+ma.init()
+ma.setr("subpage_lower_left_latitude",   40.)
+ma.setr("subpage_lower_left_longitude", -20.)
+ma.setr("subpage_upper_right_latitude",  65.)
+ma.setr("subpage_upper_right_longitude", 10.)
+
+ma.setc("grib_input_file_name", "../test/data.grib")
+ma.grib()
+
+ma.cont()
+
+ma.coast()
+
+#print ma.enqr("subpage_lower_left_latitude")
+
+ma.new_page("page")
+
+ma.reset("subpage_lower_left_latitude")
+ma.reset("subpage_lower_left_longitude")
+
+ma.coast()
+#print ma.enqr("subpage_lower_left_latitude")
+
+ma.info()
+
+ma.finalize()
diff --git a/python/test_for_ctypes/test_ctypes_graph.py b/python/test_for_ctypes/test_ctypes_graph.py
new file mode 100644
index 0000000..6b6aafc
--- /dev/null
+++ b/python/test_for_ctypes/test_ctypes_graph.py
@@ -0,0 +1,58 @@
+import Magics as ma
+import numpy as np
+
+ma.init()
+
+ma.setr("subpage_y_position", 2.)
+ma.setc("subpage_map_projection",'cartesian')
+ma.setc("subpage_x_axis_type",'date')
+ma.setc("subpage_y_axis_type",'regular')
+ma.setc("subpage_x_date_min","2012-03-01 12:00:00")
+ma.setc("subpage_x_date_max","2012-03-03 12:00:00")
+ma.setr("subpage_x_min",25.)
+ma.setr("subpage_x_max",75.)
+ma.setr("subpage_y_min",25.)
+ma.setr("subpage_y_max",75.)
+
+ma.setc("axis_orientation","vertical")
+ma.setc("axis_type","regular")
+ma.setc("axis_tick_label_colour",'navy')
+ma.setc("axis_grid","on")
+ma.setc("axis_grid_colour","grey")
+ma.setc("axis_grid_line_style","dot")
+ma.setr("axis_tick_label_height",0.4)
+ma.seti("axis_grid_thickness",1)
+ma.axis()
+
+ma.setc("axis_orientation","horizontal")
+ma.setc("axis_type","date")
+ma.setc("axis_grid","on")
+ma.setr("axis_days_label_height",0.40)
+ma.setr("axis_months_label_height",0.40)
+ma.setr("axis_years_label_height",0.50)
+ma.setc("axis_grid_colour","grey")
+ma.seti("axis_grid_thickness",1)
+ma.setc("axis_grid_line_style","dot")
+ma.axis()
+
+
+x = ["2012-03-02 00:00:00","2012-03-02 12:00:00","2012-03-03 00:00:00"]
+y = np.array([50.,30.,40.])
+ma.set1c("input_date_x_values",x,3)
+ma.set1r("input_y_values",y,3)
+ma.minput()
+
+ma.setc("graph_type","bar")
+ma.setc("graph_bar_colour",'evergreen')
+ma.setr("graph_bar_width",7200.)
+
+ma.graph()
+
+ma.set1c("text_lines",["Simple Bar","Second line"],2)
+ma.setc("text_justification","left")
+ma.setr("text_font_size",1.)
+ma.setc("text_colour", "charcoal")
+
+ma.text();
+
+ma.finalize()
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
index be3ed8f..8ad7ac8 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
@@ -3,6 +3,11 @@
 ####################################################################
 
 set( EC_HAVE_C_INLINE 1 )
+set( EC_HAVE_FUNCTION_DEF 1 )
+set( EC_HAVE_CXXABI_H 1 )
+set( EC_HAVE_CXX_BOOL 1 )
+set( EC_HAVE_CXX_SSTREAM 1 )
+set( EC_HAVE_CXX_INT_128 0 )
 set( CMAKE_SIZEOF_VOID_P 8 )
 set( EC_SIZEOF_PTR 8 )
 set( EC_SIZEOF_CHAR 1 )
@@ -83,12 +88,15 @@ set( EC_HAVE_GMTIME_R 1 )
 set( EC_HAVE_GETPWUID_R 1 )
 set( EC_HAVE_GETPWNAM_R 1 )
 set( EC_HAVE_READDIR_R 1 )
+set( EC_HAVE_DIRENT_D_TYPE 1 )
 set( EC_HAVE_GETHOSTBYNAME_R 1 )
 set( EC_HAVE_ATTRIBUTE_CONSTRUCTOR 1 )
 set( EC_ATTRIBUTE_CONSTRUCTOR_INITS_ARGV 0 )
 set( EC_HAVE_PROCFS 1 )
 set( EC_HAVE_DLFCN_H 1 )
 set( EC_HAVE_DLADDR 1 )
+set( EC_HAVE_AIOCB 1 )
+set( EC_HAVE_AIOCB64 1 )
 
 # Disable relative rpaths as aprun does not respect it
 set( ENABLE_RELATIVE_RPATHS OFF CACHE STRING "Disable relative rpaths" FORCE )
@@ -106,6 +114,8 @@ CMAKE_FORCE_Fortran_COMPILER ( ftn Cray )
 set( ECBUILD_FIND_MPI OFF )
 set( ECBUILD_TRUST_FLAGS ON )
 
+set( CXX11_FLAG "-hstd=c++11" )
+
 ####################################################################
 # OpenMP FLAGS
 ####################################################################
@@ -122,10 +132,16 @@ set( OMPSTUBS_Fortran_FLAGS  "-hnoomp" )
 # LINK FLAGS
 ####################################################################
 
+if( EXISTS "$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so" )
+  set( LIBCRAY_CXX_RTS "$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so" ) 
+elseif( EXISTS "$ENV{CC_X86_64}/lib/libcray-c++-rts.so" )
+  set( LIBCRAY_CXX_RTS "$ENV{CC_X86_64}/lib/libcray-c++-rts.so" ) 
+endif()
+
 set( ECBUILD_SHARED_LINKER_FLAGS "-Wl,--eh-frame-hdr -Ktrap=fp" )
 set( ECBUILD_MODULE_LINKER_FLAGS "-Wl,--eh-frame-hdr -Ktrap=fp -Wl,-Map,loadmap" )
 set( ECBUILD_EXE_LINKER_FLAGS    "-Wl,--eh-frame-hdr -Ktrap=fp -Wl,-Map,loadmap -Wl,--as-needed" )
-set( ECBUILD_CXX_IMPLICIT_LINK_LIBRARIES "$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so" CACHE STRING "" )
+set( ECBUILD_CXX_IMPLICIT_LINK_LIBRARIES "${LIBCRAY_CXX_RTS}" CACHE STRING "" )
 
 ####################################################################
 # LIBRARIES
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
index 5acd12e..d98fe29 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
@@ -3,6 +3,11 @@
 ####################################################################
 
 set( EC_HAVE_C_INLINE 1 )
+set( EC_HAVE_FUNCTION_DEF 1 )
+set( EC_HAVE_CXXABI_H 1 )
+set( EC_HAVE_CXX_BOOL 1 )
+set( EC_HAVE_CXX_SSTREAM 1 )
+set( EC_HAVE_CXX_INT_128 1 )
 set( CMAKE_SIZEOF_VOID_P 8 )
 set( EC_SIZEOF_PTR 8 )
 set( EC_SIZEOF_CHAR 1 )
@@ -83,6 +88,7 @@ set( EC_HAVE_GMTIME_R 1 )
 set( EC_HAVE_GETPWUID_R 1 )
 set( EC_HAVE_GETPWNAM_R 1 )
 set( EC_HAVE_READDIR_R 1 )
+set( EC_HAVE_DIRENT_D_TYPE 1 )
 set( EC_HAVE_GETHOSTBYNAME_R 1 )
 set( EC_HAVE_ATTRIBUTE_CONSTRUCTOR 1 )
 set( EC_ATTRIBUTE_CONSTRUCTOR_INITS_ARGV 0 )
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
index 8e6b41d..042d3da 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
@@ -3,6 +3,11 @@
 ####################################################################
 
 set( EC_HAVE_C_INLINE 1 )
+set( EC_HAVE_FUNCTION_DEF 1 )
+set( EC_HAVE_CXXABI_H 1 )
+set( EC_HAVE_CXX_BOOL 1 )
+set( EC_HAVE_CXX_SSTREAM 1 )
+set( EC_HAVE_CXX_INT_128 1 )
 set( CMAKE_SIZEOF_VOID_P 8 )
 set( EC_SIZEOF_PTR 8 )
 set( EC_SIZEOF_CHAR 1 )
@@ -83,6 +88,7 @@ set( EC_HAVE_GMTIME_R 1 )
 set( EC_HAVE_GETPWUID_R 1 )
 set( EC_HAVE_GETPWNAM_R 1 )
 set( EC_HAVE_READDIR_R 1 )
+set( EC_HAVE_DIRENT_D_TYPE 1 )
 set( EC_HAVE_GETHOSTBYNAME_R 1 )
 set( EC_HAVE_ATTRIBUTE_CONSTRUCTOR 1 )
 set( EC_ATTRIBUTE_CONSTRUCTOR_INITS_ARGV 0 )
diff --git a/share/magics/cream/coastlines.json b/share/magics/cream/coastlines.json
index 99d648f..0a1b299 100644
--- a/share/magics/cream/coastlines.json
+++ b/share/magics/cream/coastlines.json
@@ -1,41 +1,61 @@
-{
-    "foreground": {
-        "contour_legend_text": "Dark Coastlines", 
-        "map_coastline_resolution": "high", 
-        "map_coastline_thickness": 2, 
-        "map_grid": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "tan"
+[
+    {
+        "criteria": { 
+            "name": "foreground"
+        },
+        "visdef": {
+            "contour_legend_text": "Dark Coastlines", 
+            "map_coastline_resolution": "high", 
+            "map_coastline_thickness": 2, 
+            "map_grid": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "tan"
+        }
     }, 
-    "boundaries": {
-        "contour_legend_text": "Boundaries For WWW", 
-        "map_boundaries": "on", 
-        "map_grid": "off", 
-        "map_boundaries_colour": "tan",
-        "map_administrative_boundaries_style": "dot", 
-        "map_disputed_boundaries": "$disputed", 
-        "map_coastline": "off", 
-        "map_label": "off", 
-        "map_administrative_boundaries_countries_list": "$country_list", 
-        "map_administrative_boundaries_colour": "tan", 
-        "map_coastline_colour": "tan", 
-        "map_administrative_boundaries": "on"
+    {
+        "criteria": { 
+            "name": "boundaries"
+        },
+        "visdef": {
+            "contour_legend_text": "Boundaries For WWW", 
+            "map_boundaries": "on", 
+            "map_grid": "off", 
+            "map_boundaries_colour": "tan",
+            "map_administrative_boundaries_style": "dot", 
+            "map_disputed_boundaries": "$disputed", 
+            "map_coastline": "off", 
+            "map_label": "off", 
+            "map_administrative_boundaries_countries_list": "$country_list", 
+            "map_administrative_boundaries_colour": "tan", 
+            "map_coastline_colour": "tan", 
+            "map_administrative_boundaries": "on"
+        }
     }, 
-    "grid": {
-        "contour_legend_text": "grid for WWW", 
-        "map_grid_thickness": 2, 
-        "map_grid": "on", 
-        "map_grid_line_style": "dot", 
-        "map_grid_colour": "tan",
-        "map_coastline": "off"
-    }, 
-    "background": {
-        "map_coastline_resolution": "high", 
-        "map_coastline_land_shade_colour": "cream", 
-        "map_grid": "off", 
-        "map_coastline_land_shade": "on", 
-        "map_coastline_sea_shade": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "rgb(65, 64, 66)"
-    } 
-}
+    {
+        "criteria": { 
+            "name": "grid"
+        },
+        "visdef": {
+            "contour_legend_text": "grid for WWW", 
+            "map_grid_thickness": 2, 
+            "map_grid": "on", 
+            "map_grid_line_style": "dot", 
+            "map_grid_colour": "tan",
+            "map_coastline": "off"
+        }
+    },
+    {
+        "criteria": { 
+            "name": "background"
+        },
+        "visdef": {
+            "map_coastline_resolution": "high", 
+            "map_coastline_land_shade_colour": "cream", 
+            "map_grid": "off", 
+            "map_coastline_land_shade": "on", 
+            "map_coastline_sea_shade": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "rgb(65, 64, 66)"
+        } 
+    }
+]
diff --git a/share/magics/dark/coastlines.json b/share/magics/dark/coastlines.json
index eaa4aaf..2b8c577 100644
--- a/share/magics/dark/coastlines.json
+++ b/share/magics/dark/coastlines.json
@@ -1,88 +1,133 @@
-{
-    "foreground": {
-        "contour_legend_text": "Dark Coastlines", 
-        "map_coastline_resolution": "high", 
-        "map_coastline_thickness": 2, 
-        "map_grid": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "rgb(85, 85, 85)"
+[
+    {
+        "criteria": { 
+            "name": "foreground"
+        },
+        "visdef": {
+            "contour_legend_text": "Dark Coastlines", 
+            "map_coastline_resolution": "low", 
+            "map_coastline_thickness": 2, 
+            "map_grid": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "rgb(85, 85, 85)"
+        }
+    },
+    {
+        "criteria": { 
+            "name": "map_background"
+        },
+        "visdef": {
+            "map_coastline_sea_shade": "on", 
+            "map_coastline_resolution": "low", 
+            "map_coastline_land_shade_colour": "rgb(65, 65, 65)", 
+            "map_grid": "off", 
+            "map_coastline_land_shade": "on", 
+            "map_coastline_sea_shade_colour": "rgb(65, 65, 65)", 
+            "map_label": "off", 
+            "map_coastline_colour": "white"
+        }
     }, 
-    "map_background": {
-        "map_coastline_sea_shade": "on", 
-        "map_coastline_resolution": "high", 
-        "map_coastline_land_shade_colour": "rgb(65, 65, 65)", 
-        "map_grid": "off", 
-        "map_coastline_land_shade": "on", 
-        "map_coastline_sea_shade_colour": "rgb(65, 65, 65)", 
-        "map_label": "off", 
-        "map_coastline_colour": "white"
+    {
+        "criteria": { 
+            "name": "grey_foreground"
+        },
+        "visdef": {
+            "contour_legend_text": "grey Coastlines", 
+            "map_coastline_resolution": "low", 
+            "map_coastline_thickness": 2, 
+            "map_grid": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "rgb(65,64,66)"
+        }
     }, 
-    "grey_foreground": {
-        "contour_legend_text": "grey Coastlines", 
-        "map_coastline_resolution": "high", 
-        "map_coastline_thickness": 2, 
-        "map_grid": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "rgb(65,64,66)"
+    {
+        "criteria": { 
+            "name": "grey_boundaries"
+        },
+        "visdef": {
+            "contour_legend_text": "Boundaries For WWW", 
+            "map_boundaries": "on", 
+            "map_grid": "off", 
+            "map_boundaries_colour": "rgb(65,64,66)", 
+            "map_administrative_boundaries_style": "dot", 
+            "map_disputed_boundaries": "$disputed", 
+            "map_coastline": "off", 
+            "map_label": "off", 
+            "map_administrative_boundaries_countries_list": "$country_list", 
+            "map_administrative_boundaries_colour": "rgb(65,64,66)", 
+            "map_administrative_boundaries": "on"
+        }
+    },
+    {
+        "criteria": { 
+            "name": "land_background"
+        },
+        "visdef": {
+            "map_coastline_resolution": "low", 
+            "map_coastline_land_shade_colour": "rgb(65, 65, 65)", 
+            "map_grid": "off", 
+            "map_coastline_land_shade": "on", 
+            "map_coastline_sea_shade": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "white"
+        } 
+    },
+    {
+        "criteria": { 
+            "name": "boundaries"
+        },
+        "visdef": {   
+            "contour_legend_text": "Boundaries For WWW", 
+            "map_boundaries": "on", 
+            "map_grid": "off", 
+            "map_boundaries_colour": "rgba(85, 85, 85, 0.7)", 
+            "map_administrative_boundaries_style": "dot", 
+            "map_disputed_boundaries": "$disputed", 
+            "map_coastline": "off", 
+            "map_label": "off", 
+            "map_administrative_boundaries_countries_list": "$country_list", 
+            "map_administrative_boundaries_colour": "white", 
+            "map_coastline_colour": "white", 
+            "map_administrative_boundaries": "on"
+        }
     }, 
-    "grey_boundaries": {
-        "contour_legend_text": "Boundaries For WWW", 
-        "map_boundaries": "on", 
-        "map_grid": "off", 
-        "map_boundaries_colour": "rgb(65,64,66)", 
-        "map_administrative_boundaries_style": "dot", 
-        "map_disputed_boundaries": "$disputed", 
-        "map_coastline": "off", 
-        "map_label": "off", 
-        "map_administrative_boundaries_countries_list": "$country_list", 
-        "map_administrative_boundaries_colour": "rgb(65,64,66)", 
-        "map_administrative_boundaries": "on"
+    {
+        "criteria": { 
+            "name": "grid"
+        },
+        "visdef": {   
+            "contour_legend_text": "grid for WWW", 
+            "map_grid_thickness": 2, 
+            "map_grid": "on", 
+            "map_grid_line_style": "dot", 
+            "map_grid_colour": "rgba(85, 85, 85, 0.7)", 
+            "map_coastline": "off"
+        }
+    },
+    {
+        "criteria": { 
+            "name": "background"
+        },
+        "visdef": {
+            "map_coastline_resolution": "low", 
+            "map_coastline_land_shade_colour": "rgb(190, 189, 191)", 
+            "map_grid": "off", 
+            "map_coastline_land_shade": "on", 
+            "map_coastline_sea_shade": "off", 
+            "map_label": "off", 
+            "map_coastline_colour": "rgb(65, 64, 66)"
+        }
     }, 
-    "land_background": {
-        "map_coastline_resolution": "high", 
-        "map_coastline_land_shade_colour": "rgb(65, 65, 65)", 
-        "map_grid": "off", 
-        "map_coastline_land_shade": "on", 
-        "map_coastline_sea_shade": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "white"
-    }, 
-    "boundaries": {
-        "contour_legend_text": "Boundaries For WWW", 
-        "map_boundaries": "on", 
-        "map_grid": "off", 
-        "map_boundaries_colour": "rgba(85, 85, 85, 0.7)", 
-        "map_administrative_boundaries_style": "dot", 
-        "map_disputed_boundaries": "$disputed", 
-        "map_coastline": "off", 
-        "map_label": "off", 
-        "map_administrative_boundaries_countries_list": "$country_list", 
-        "map_administrative_boundaries_colour": "white", 
-        "map_coastline_colour": "white", 
-        "map_administrative_boundaries": "on"
-    }, 
-    "grid": {
-        "contour_legend_text": "grid for WWW", 
-        "map_grid_thickness": 2, 
-        "map_grid": "on", 
-        "map_grid_line_style": "dot", 
-        "map_grid_colour": "rgba(85, 85, 85, 0.7)", 
-        "map_coastline": "off"
-    }, 
-    "background": {
-        "map_coastline_resolution": "high", 
-        "map_coastline_land_shade_colour": "rgb(190, 189, 191)", 
-        "map_grid": "off", 
-        "map_coastline_land_shade": "on", 
-        "map_coastline_sea_shade": "off", 
-        "map_label": "off", 
-        "map_coastline_colour": "rgb(65, 64, 66)"
-    }, 
-    "grey_grid": {
-        "contour_legend_text": "grid for WWW", 
-        "map_grid_line_style": "dot", 
-        "map_grid_colour": "rgb(65,64,66), 0.7)", 
-        "map_coastline": "off", 
-        "map_grid": "on"
+    {
+        "criteria": { 
+            "name": "grey_grid"
+        },
+        "visdef": {
+            "contour_legend_text": "grid for WWW", 
+            "map_grid_line_style": "dot", 
+            "map_grid_colour": "rgb(65,64,66), 0.7)", 
+            "map_coastline": "off", 
+            "map_grid": "on"
+        }
     }
-}
\ No newline at end of file
+]
\ No newline at end of file
diff --git a/share/magics/dark/contours.json b/share/magics/dark/contours.json
index 007c6b0..3ecac8c 100644
--- a/share/magics/dark/contours.json
+++ b/share/magics/dark/contours.json
@@ -1,58 +1,109 @@
-{
-    "232.140": {
-        "contour_level_selection_type": "level_list", 
-        "contour_shade_colour_method": "list", 
-        "contour_legend_text": "Contour shade (Range: 0.0 / 18.5)", 
-        "contour_label_colour": "black", 
-        "contour_shade": "on", 
-        "contour_level_list": "0.0/3.5/5.0/6.5/8.0/9.5/11.0/12.5/14.0/15.5/17.0/18.5", 
-        "contour_reference_level": 0, 
-        "contour_label_quality": "high", 
-        "contour_hilo": "off", 
-        "contour": "off", 
-        "contour_label_format": "(F4.1)", 
-        "contour_highlight": "off", 
-        "contour_label": "off", 
-        "contour_min_level": 0, 
-        "contour_shade_method": "area_fill", 
-        "_name": "wave_mwp", 
-        "contour_shade_min_level": 0, 
-        "contour_shade_colour_list": "rgb(242,250,239)/rgb(216,237,232)/rgb(179,223,226)/rgb(130,192,215)/rgb(76,157,210)/rgb(33,128,192)/rgb(39,93,163)/rgb(54,71,127)/rgb(51,50,92)/rgb(35,34,65)/rgb(25,18,36)"
-    }, 
-    "151.128": {
-        "contour_label_height": 0.4, 
-        "contour_legend_text": "Interval 5, thickness 2", 
-        "contour_label_colour": "charcoal", 
-        "contour_level_selection_type": "interval", 
-        "contour_reference_level": 1010, 
-        "contour_label_frequency": 2, 
-        "_name": "msl", 
-        "contour_line_colour": "charcoal", 
-        "contour_hilo": "off", 
-        "contour_line_thickness": 2, 
-        "contour_label": "on", 
-        "contour_highlight_colour": "charcoal", 
-        "contour_highlight_thickness": 4, 
-        "contour_interval": 5
-    }, 
-    "167.128": {
-        "contour_level_selection_type": "level_list", 
-        "contour_shade_colour_method": "gradients", 
-        "contour_legend_text": "Contour shade (Range: -80 / 56)", 
-        "contour_shade_method": "area_fill", 
-        "contour_shade": "on", 
-        "contour_level_list": "-80/-70/-60/-52/-48/-44/-40/-36/-32/-28/-24/-20/-16/-12/-8/-4/0/4/8/12/16/20/24/28/32/36/40/44/48/52/56", 
-        "contour_gradients_colour_list": "rgb(5,64,106)/white/rgb(134,25,20)", 
-        "contour_label_frequency": 1, 
-        "contour_label_quality": "high", 
-        "contour_hilo": "off", 
-        "contour_label": "on", 
-        "contour_gradients_step_list": "15/15", 
-        "contour_gradients_technique_direction": "anti_clockwise", 
-        "_name": "2t", 
-        "contour_gradients_technique": "hsl", 
-        "contour": "off", 
-        "contour_gradients_waypoint_list": "-60./0/60.", 
-        "contour_gradients_waypoint_method": "ignore"
+[
+    {
+        "criteria" : { 
+            "standard_name" : "sea_surface_height_above_sea_level"
+        },
+        "visdef" : {
+            "contour_shade" : "on",
+            "contour" : "off",
+            "contour_shade_method" : "area_fill"
+        },
+        "more" : [
+            {
+                "criteria" : { 
+                    "units" : "deg"
+                },
+                "visdef" : {
+                    "contour" : "on",
+                    "contour_line_thickness" : "4",
+                    "contour_line_colour" : "red",
+                    "contour_highlight_colour" : "red"
+                },
+                "more" : [
+                    {
+                        "criteria" : { 
+                            "grid_mapping" : "crs"
+                        },
+                        "visdef" : { 
+                            "contour" : "on",
+                            "contour_line_thickness" : "6",
+                            "contour_line_colour" : "yellow",
+                             "contour_highlight_colour" : "orange"
+                        }
+                    }
+                ]
+            }
+        ]
+    },
+    {
+        "criteria" : {
+            "paramId" : "232.140"
+        },
+        "visdef" : {
+            "contour_level_selection_type": "level_list", 
+            "contour_shade_colour_method": "list", 
+            "contour_legend_text": "Contour shade (Range: 0.0 / 18.5)", 
+            "contour_label_colour": "black", 
+            "contour_shade": "on", 
+            "contour_level_list": "0.0/3.5/5.0/6.5/8.0/9.5/11.0/12.5/14.0/15.5/17.0/18.5", 
+            "contour_reference_level": 0, 
+            "contour_label_quality": "high", 
+            "contour_hilo": "off", 
+            "contour": "off", 
+            "contour_label_format": "(F4.1)", 
+            "contour_highlight": "off", 
+            "contour_label": "off", 
+            "contour_min_level": 0, 
+            "contour_shade_method": "area_fill", 
+            "_name": "wave _mwp", 
+            "contour_shade_min_level": 0, 
+            "contour_shade_colour_list": "rgb(242,250,239)/rgb(216,237,232)/rgb(179,223,226)/rgb(130,192,215)/rgb(76,157,210)/rgb(33,128,192)/rgb(39,93,163)/rgb(54,71,127)/rgb(51,50,92)/rgb(35,34,65)/rgb(25,18,36)"
+        }
+    },
+    {
+        "criteria" : {
+            "paramId" : "151.128"
+        },
+        "visdef" : {
+            "contour_label_height": 0.4, 
+            "contour_legend_text": "Interval 5, thickness 2", 
+            "contour_label_colour": "charcoal", 
+            "contour_level_selection_type": "interval", 
+            "contour_reference_level": 1010, 
+            "contour_label_frequency": 2, 
+            "_name": "msl", 
+            "contour_line_colour": "charcoal", 
+            "contour_hilo": "off", 
+            "contour_line_thickness": 2, 
+            "contour_label": "on", 
+            "contour_highlight_colour": "charcoal", 
+            "contour_highlight_thickness": 4, 
+            "contour_interval": 5
+        }
+    },
+    {
+        "criteria" : {
+            "paramId" : "167.128"
+        },
+        "visdef" : { 
+            "contour_level_selection_type": "level_list", 
+            "contour_shade_colour_method": "gradients", 
+            "contour_legend_text": "Contour shade (Range: -80 / 56)", 
+            "contour_shade_method": "area_fill", 
+            "contour_shade": "on", 
+            "contour_level_list": "-80/-70/-60/-52/-48/-44/-40/-36/-32/-28/-24/-20/-16/-12/-8/-4/0/4/8/12/16/20/24/28/32/36/40/44/48/52/56", 
+            "contour_gradients_colour_list": "rgb(5,64,106)/white/rgb(134,25,20)", 
+            "contour_label_frequency": 1, 
+            "contour_label_quality": "high", 
+            "contour_hilo": "off", 
+            "contour_label": "on", 
+            "contour_gradients_step_list": "15/15", 
+            "contour_gradients_technique_direction": "anti_clockwise", 
+            "_name": "2t", 
+            "contour_gradients_technique": "hsl", 
+            "contour": "off", 
+            "contour_gradients_waypoint_list": "-60./0/60.", 
+            "contour_gradients_waypoint_method": "ignore"
+        }
     }
-}
\ No newline at end of file
+]
\ No newline at end of file
diff --git a/share/magics/epsg.json b/share/magics/epsg.json
index 93f794c..9087389 100644
--- a/share/magics/epsg.json
+++ b/share/magics/epsg.json
@@ -37,7 +37,8 @@
                 "max_longitude": 360,
                 "method": "simple",
                 "min_latitude": -80,
-                "min_longitude": -180
+                "min_longitude": -180,
+                "default_max_longitude" : 180.
             }
         },
         {
diff --git a/share/magics/netcdf-convention.json b/share/magics/netcdf-convention.json
new file mode 100644
index 0000000..984bc91
--- /dev/null
+++ b/share/magics/netcdf-convention.json
@@ -0,0 +1,18 @@
+{
+    "latitude" : {
+        "units" : [ "degrees_north", "degrees_south" ],
+        "standard_name" : ["latitude"],
+        "long_name" : ["latitude"]
+        },
+    "longitude" : {
+        "units" : [ "degrees_west", "degrees_east" ],
+        "standard_name" : ["longitude"],
+        "long_name" : ["longitude"]
+        },
+     "time" : {
+        "calendar" : [ "gregorian", "proleptic_gregorian"],
+        "long_name" : ["time", "date and time"]
+        }
+
+}
+
diff --git a/share/magics/palettes.json b/share/magics/palettes.json
new file mode 100644
index 0000000..c02b757
--- /dev/null
+++ b/share/magics/palettes.json
@@ -0,0 +1,6719 @@
+{
+    "eccharts_clouds_all_64" : {
+        "n_colours" : "64",
+        "tags" : [
+            "64",
+            "eccharts",
+            "clouds_all"
+        ],
+        "values" : [
+            "HSL(0,0,1)",
+            "HSL(29,0.12,0.92)",
+            "HSL(29,0.23,0.83)",
+            "HSL(29,0.35,0.75)",
+            "HSL(300,0.12,0.92)",
+            "HSL(344,0.17,0.84)",
+            "HSL(2,0.26,0.75)",
+            "HSL(10,0.37 ,0.67)",
+            "HSL(300,0.23,0.83)",
+            "HSL(326,0.26,0.75)",
+            "HSL(344,0.34,0.67)",
+            "HSL(355,0.43,0.58)",
+            "HSL(300,0.35,0.75)",
+            "HSL(318,0.37,0.67)",
+            "HSL(333,0.43,0.58)",
+            "HSL(344,0.5,0.5)",
+            "HSL(180,0.17,0.92)",
+            "HSL(138,0.08,0.84)",
+            "HSL(70,0.12,0.75)",
+            "HSL(50,0.22,0.67)",
+            "HSL(223,0.15,0.84)",
+            "HSL(262,0.04,0.75)",
+            "HSL(7,0.1,0.67)",
+            "HSL(19,0.21,0.59)",
+            "HSL(256,0.21,0.75)",
+            "HSL(289,0.16,0.67)",
+            "HSL(330,0.18,0.58)",
+            "HSL(352,0.26,0.5)",
+            "HSL(271,0.3,0.67)",
+            "HSL(294,0.27,0.59)",
+            "HSL(318,0.29,0.5)",
+            "HSL(337,0.34,0.42)",
+            "HSL(180,0.34,0.83)",
+            "HSL(166,0.24,0.75)",
+            "HSL(138,0.17,0.67)",
+            "HSL(99,0.17,0.58)",
+            "HSL(199,0.29,0.75)",
+            "HSL(194,0.18,0.67) ",
+            "HSL(169,0.07,0.58)",
+            "HSL(67,0.08,0.5)",
+            "HSL(223,0.3,0.67)",
+            "HSL(231,0.19,0.58)",
+            "HSL(262,0.09,0.5)",
+            "HSL(339,0.1,0.42)",
+            "HSL(242,0.34,0.58)",
+            "HSL(256,0.2 5,0.5)",
+            "HSL(283,0.2,0.42)",
+            "HSL(317,0.2,0.33)",
+            "HSL(180,0.5,0.75)",
+            "HSL(171,0.4,0.67)",
+            "HSL(158,0.32,0.58)",
+            "HSL(138,0.26,0.5)",
+            "HSL(192,0.45,0.67)",
+            "HSL(187,0.34,0.59)",
+            "HSL(176,0.24,0.5)",
+            "HSL(152,0.15,0.42)",
+            "HSL(207,0.43,0.58)",
+            "HSL(207,0.32,0.5)",
+            "HSL(206,0.2,0.42)",
+            "HSL(203,0.08,0.33)",
+            "HSL(223,0.44,0.5)",
+            "HSL(227,0.33,0.42)",
+            "HSL(237,0.22,0.33)",
+            "HSL(262,0.13,0.25)"
+        ]
+    },
+    "eccharts_blue_2" : {
+        "n_colours" : "2",
+        "tags" : [
+            "2",
+            "eccharts",
+            "dot_blu_f03t1lst",
+            "blue"
+        ],
+        "values" : [
+            "rgb(0,0.9,1)",
+            "rgb(0,0.5,1)"
+        ]
+    },
+    "eccharts_blue_red1_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "eccharts",
+            "dot_blured_f05t300lst",
+            "blue",
+            "red"
+        ],
+        "values" : [
+            "cyan",
+            "greenish_blue",
+            "blue",
+            "bluish_purple",
+            "magenta",
+            "orange",
+            "red"
+        ]
+    },
+    "eccharts_blue_red1_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "dot_blured_fM1t1lst",
+            "blue",
+            "red"            
+        ],
+        "values" : [
+            "rgb(1, 0, 0.8536, 1)",
+            "rgb(0.2348, 0, 1, 1)",
+            "rgb(0, 0.6768, 1, 1)",
+            "rgb(0, 1, 0.4116, 1)",
+            "rgb(0.5, 1, 0, 1)",
+            "none",
+            "rgb(1, 1, 0, 1)",
+            "rgb(1, 0.75, 0, 1)",
+            "rgb(1, 0.5, 0, 1)",
+            "rgb(1, 0.25, 0, 1)",
+            "rgb(1, 0, 0, 1)"
+        ]
+    },
+    "eccharts_green_2" : {
+        "n_colours" : "2",
+        "tags" : [
+            "2",
+            "eccharts",
+            "dot_grn_f03t1lst",
+            "green"
+        ],
+        "values" : [
+            "rgb(0,0.9,0)",
+            "rgb(0,0.5,0)"
+        ]
+    },
+    "eccharts_red_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "dot_red_f10t80lst",
+            "red"
+        ],
+        "values" : [
+            "rgb(1,0.45,0)",
+            "red",
+            "rgb(0.8,0,0)",
+            "burgundy",
+            "rose",
+            "magenta",
+            "rgb(1,0.5,1)",
+            "rgb(1,0.75,1)"
+        ]
+    },
+    "eccharts_red_3" : {
+        "n_colours" : "3",
+        "tags" : [
+            "3",
+            "eccharts",
+            "efas_radar_ffhz1h",
+            "efas",
+            "radar",
+            "ERICHA - FF hazard levels forecasts",
+            "red"
+        ],
+        "values" : [
+            "RGB(255, 255, 0)",
+            "RGB(255, 150, 0)",
+            "RGB(255, 0, 0)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_17" : {
+        "n_colours" : "17",
+        "tags" : [
+            "17",
+            "eccharts",
+            "efas_radar_tp",
+            "efas_radar_tpr24hacc",
+            "efas",
+            "radar",
+            "precipitation",
+            "tp",
+            "ERICHA 15-min accumulation precipitation",
+            "ERICHA 24-h accumulations",
+            "rainbow",
+            "blue",
+            "purple"
+        ],
+        "values" : [
+            "RGB(214, 226, 255)",
+            "RGB(142, 178, 255)",
+            "RGB(99, 112, 247)",
+            "RGB(0, 99, 255)",
+            "RGB(0, 150, 150)",
+            "RGB(0, 198, 51)",
+            "RGB(99, 255, 0)",
+            "RGB(198, 255, 51)",
+            "RGB(255, 255, 0)",
+            "RGB(255, 198, 0)",
+            "RGB(255, 160, 0)",
+            "RGB(255, 124, 0)",
+            "RGB(255, 25, 0)",
+            "RGB(162, 10, 40)",
+            "RGB(156, 21, 157)",
+            "RGB(210, 148, 210)",
+            "RGB(246, 233, 246)"
+        ]
+    },
+    "eccharts_red_blue1_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "soil_moisture",
+            "efas",
+            "efas_soil_moisture",
+            "red",
+            "blue"
+        ],
+        "values" : [
+            "RGB(82, 3, 0)",
+            "RGB(153, 22, 8)",
+            "RGB(255, 0, 0)",
+            "RGB(255, 128, 0)",
+            "RGB(255, 218, 0)",
+            "RGB(204, 230, 255)",
+            "RGB(115, 163, 255)",
+            "RGB(0, 128, 255)",
+            "RGB(0, 0, 255)",
+            "RGB(0, 0, 102)"
+        ]
+    },
+    "eccharts_rainbow_purple_violet_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "genesis_prob",
+            "www_genesis_probablity",
+            "probability",
+            "10m wind gusts probability",
+            "Tropical storm strike probability",
+            "rainbow",
+            "purple",
+            "violet"
+        ],
+        "values" : [
+            "purple",
+            "reddish_orange",
+            "yellowish_orange",
+            "yellow",
+            "yellowish_green",
+            "kelly_green",
+            "cyan",
+            "greenish_blue",
+            "blue",
+            "violet"
+        ]
+    },
+    "eccharts_rainbow_magenta_purple_dark_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "genesis_prob_dark",
+            "probability",
+            "dark",
+            "Hurricane strike probability",
+            "Tropical cyclone strike probability",
+            "rainbow",
+            "magenta",
+            "purple"            
+        ],
+        "values" : [
+            "rgb(0.55,0,0.55)",
+            "rgb(0.5,0.1,0)",
+            "rgb(0.55,0.3,0)",
+            "rgb(0.6,0.55,0)",
+            "rgb(0.1,0.45,0)",
+            "rgb(0,0.2,0)",
+            "rgb(0,0.55,0.55)",
+            "rgb(0,0.25,0.5)",
+            "rgb(0,0,0.35)",
+            "rgb(0.25,0,0.35)"
+        ]
+    },
+    "eccharts_rainbow_magenta_purple_light_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "genesis_prob_light",
+            "probability",
+            "light",
+            "10m wind gusts probability",
+            "rainbow",
+            "magenta",
+            "purple"            
+        ],
+        "values" : [
+            "rgb(1,0.75,1)",
+            "rgb(1,0.7,0.6)",
+            "rgb(1,0.85,0.55)",
+            "rgb(1,1,0.75)",
+            "rgb(0.8,1,0.7)",
+            "rgb(0.65,0.85,0.65)",
+            "rgb(0.85,1,1)",
+            "rgb(0.7,0.9,1)",
+            "rgb(0.6,0.75,1)",
+            "rgb(0.75,0.6,0.95)"
+        ]
+    },
+    "eccharts_red_magenta_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "hat_red_f10t80lst",
+            "red"
+        ],
+        "values" : [
+            "rgb(1,0.45,0)",
+            "red",
+            "rgb(0.8,0,0)",
+            "burgundy",
+            "rose",
+            "magenta",
+            "rgb(1,0.5,1)",
+            "rgb(1,0.75,1)"
+        ]
+    },
+    "eccharts_green_brown1_28" : {
+        "n_colours" : "28",
+        "tags" : [
+            "28",
+            "eccharts",
+            "orog_28levels_label",
+            "orography",
+            "green",
+            "brown"
+        ],
+        "values" : [
+            "rgb(0.15,0.5,0.4)",
+            "none",
+            "rgb(0.16,0.4,0)",
+            "rgb(0.18,0.45,0)",
+            "rgb(0.2,0.5,0)",
+            "rgb(0.25,0.55,0)",
+            "rgb(0.3,0.6,0)",
+            "rgb(0.35,0.65,0)",
+            "rgb(0.4,0.7,0)",
+            "rgb(0.45,0.75,0)",
+            "rgb(0.5,0.8,0)",
+            "rgb(0.57,0.83,0)",
+            "rgb(0.64,0.86,0)",
+            "rgb(0.7,0.9,0)",
+            "rgb(0.8,0.95,0)",
+            "rgb(0.9,1,0)",
+            "rgb(0.9,0.8,0)",
+            "rgb(0.85,0.7,0)",
+            "rgb(0.8,0.6,0)",
+            "rgb(0.75,0.52,0)",
+            "rgb(0.7,0.45,0)",
+            "rgb(0.65,0.37,0)",
+            "rgb(0.6,0.3,0)",
+            "rgb(0.45,0.2,0)",
+            "rgb(0.45,0.3,0.1)",
+            "rgb(0.5,0.4,0.3)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(1,1,0.5)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "range_50_9000",
+            "rainbow",
+            "cape",
+            "Convective available potential energy (CAPE)"
+        ],
+        "values" : [
+            "RGB(0.01,0.45,0.99)",
+            "RGB(0.0098,0.73,0.99)",
+            "RGB(0.01,0.99,0.95)",
+            "RGB(0.02,0.70,0.65)",
+            "RGB(0.0098,0.99,0.21)",
+            "RGB(0.77,0.99,0.01)",
+            "RGB(0.99,0.58,0.0098)",
+            "RGB(0.99,0.075,0.0098)",
+            "RGB(0.7,0.038,0.49)",
+            "RGB(1,0,1)",
+            "RGB(0.5,0.01,0.99)"
+        ]
+    },
+    "eccharts_green_brown_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "sh_BrBG_o3_sfc",
+            "Ozone at surface",
+            "cams",
+            "green",
+            "brown"
+        ],
+        "values" : [
+            "rgb(0.0018,0.3128,0.2731)",
+            "rgb(0.0038,0.3968,0.3651)",
+            "rgb(0.1039,0.4942,0.4628)",
+            "rgb(0.2078,0.5922,0.5608)",
+            "rgb(0.3578,0.7001,0.6607)",
+            "rgb(0.4962,0.7998,0.7530)",
+            "rgb(0.6384,0.8597,0.8261)",
+            "rgb(0.7804,0.9176,0.8980)",
+            "rgb(0.8724,0.9396,0.9300)",
+            "rgb(0.9609,0.9598,0.9569)",
+            "rgb(0.9627,0.9358,0.8647)",
+            "rgb(0.9647,0.9098,0.7647)",
+            "rgb(0.9187,0.8338,0.6248)",
+            "rgb(0.8720,0.7558,0.4840)",
+            "rgb(0.8081,0.6258,0.3241)",
+            "rgb(0.7490,0.5059,0.1765)",
+            "rgb(0.6471,0.4099,0.1065)",
+            "rgb(0.5447,0.3151,0.0388)",
+            "rgb(0.4328,0.2491,0.0288)",
+            "rgb(0.3294,0.1882,0.0196)"
+        ]
+    },
+    "eccharts_purple_darkred_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "sh_BuYlRdBr_aod",
+            "Aerosol optical depth at 550 nm",
+            "cams",
+            "purple",
+            "red"
+        ],
+        "values" : [
+            "rgb(210,210,256)",
+            "rgb(161,161,256)",
+            "rgb(112,112,256)",
+            "rgb(135,135,199)",
+            "rgb(184,184,118)",
+            "rgb(233,233,38)",
+            "rgb(256,218,0)",
+            "rgb(256,138,0)",
+            "rgb(256,57,0)",
+            "rgb(244,0,0)",
+            "rgb(196,0,0)",
+            "rgb(147,0,0)",
+            "rgb(100,0,0)"
+        ]
+    },
+    "eccharts_purple_red_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "sh_BuYlRd_aod",
+            "Aerosol optical depth at 550 nm",
+            "cams",
+            "purple",
+            "red"
+        ],
+        "values" : [
+            "rgb(211,215,235)",
+            "rgb(168,175,215)",
+            "rgb(136,146,191)",
+            "rgb(163,168,145)",
+            "rgb(190,189,101)",
+            "rgb(216,210,57)",
+            "rgb(243,231,11)",
+            "rgb(244,198,10)",
+            "rgb(246,165,8)",
+            "rgb(248,132,6)",
+            "rgb(249,98,5)",
+            "rgb(251,65,3)",
+            "rgb(253,32,1)",
+            "rgb(255,0,0)"
+        ]
+    },
+    "eccharts_sh_BuYlRd_aod_lowthreshold_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "sh_BuYlRd_aod_lowthreshold",
+            "Aerosol optical depth at 550 nm",
+            "cams",
+            "purple",
+            "red"
+        ],
+        "values" : [
+            "rgb(211,215,235)",
+            "rgb(168,175,215)",
+            "rgb(136,146,191)",
+            "rgb(163,168,145)",
+            "rgb(190,189,101)",
+            "rgb(216,210,57)",
+            "rgb(243,231,11)",
+            "rgb(244,198,10)",
+            "rgb(246,165,8)",
+            "rgb(248,132,6)",
+            "rgb(249,98,5)",
+            "rgb(251,65,3)",
+            "rgb(253,32,1)",
+            "rgb(255,0,0)"
+        ]
+    },
+    "eccharts_orange_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "sh_Oranges_aod",
+            "Aerosol optical depth at 550 nm",
+            "cams",
+            "orange",
+            "transparent"
+        ],
+        "values" : [
+            "rgba(0.9985,0.9386,0.8788,0.0500)",
+            "rgba(0.9969,0.9146,0.8324,0.1000)",
+            "rgba(0.9953,0.8854,0.7747,0.1500)",
+            "rgba(0.9937,0.8502,0.7043,0.2000)",
+            "rgba(0.9922,0.8146,0.6336,0.2500)",
+            "rgba(0.9922,0.7644,0.5524,0.3000)",
+            "rgba(0.9922,0.7101,0.4644,0.3500)",
+            "rgba(0.9922,0.6565,0.3827,0.4000)",
+            "rgba(0.9922,0.6037,0.3076,0.4500)",
+            "rgba(0.9914,0.5507,0.2328,0.5000)",
+            "rgba(0.9737,0.4976,0.1722,0.5500)",
+            "rgba(0.9545,0.4400,0.1067,0.6000)",
+            "rgba(0.9255,0.3849,0.0598,0.6500)",
+            "rgba(0.8872,0.3321,0.0310,0.7000)",
+            "rgba(0.8463,0.2807,0.0041,0.7500)",
+            "rgba(0.7710,0.2541,0.0071,0.8000)",
+            "rgba(0.6894,0.2253,0.0103,0.8500)",
+            "rgba(0.6180,0.1991,0.0126,0.9000)",
+            "rgba(0.5556,0.1751,0.0142,0.9500)",
+            "rgba(0.4980,0.1529,0.0157,1.0000)"
+        ]
+    },
+    "eccharts_grey_red_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "sh_RdGy_r_ch4_300hpa",
+            "Methane at 300 hPa",
+            "ch4",
+            "methane",
+            "cams"
+            ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.2667, 0.2667, 0.2667)",
+            "rgb(0.4491, 0.4491, 0.4491)",
+            "rgb(0.6314, 0.6314, 0.6314)",
+            "rgb(0.7791, 0.7791, 0.7791)",
+            "rgb(0.8975, 0.8975, 0.8975)",
+            "rgb(0.9998, 0.9972, 0.9957)",
+            "rgb(0.9934, 0.8810, 0.8148)",
+            "rgb(0.9686, 0.7176, 0.6000)",
+            "rgb(0.8946, 0.5038, 0.3998)",
+            "rgb(0.7894, 0.2768, 0.2549)",
+            "rgb(0.6461, 0.0775, 0.1603)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "sh_RdGy_r_ch4_500hpa",
+            "sh_RdGy_r_ch4_50hpa",
+            "Methane at 50 hPa",
+            "Methane at 500 hPa",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.1804, 0.1804, 0.1804)",
+            "rgb(0.2667, 0.2667, 0.2667)",
+            "rgb(0.3599, 0.3599, 0.3599)",
+            "rgb(0.4491, 0.4491, 0.4491)",
+            "rgb(0.5451, 0.5451, 0.5451)",
+            "rgb(0.6314, 0.6314, 0.6314)",
+            "rgb(0.7098, 0.7098, 0.7098)",
+            "rgb(0.7791, 0.7791, 0.7791)",
+            "rgb(0.8434, 0.8434, 0.8434)",
+            "rgb(0.8975, 0.8975, 0.8975)",
+            "rgb(0.9499, 0.9499, 0.9499)",
+            "rgb(0.9998, 0.9972, 0.9957)",
+            "rgb(0.9968, 0.9419, 0.9096)",
+            "rgb(0.9934, 0.8810, 0.8148)",
+            "rgb(0.9825, 0.8007, 0.7061)",
+            "rgb(0.9686, 0.7176, 0.6000)",
+            "rgb(0.9453, 0.6205, 0.4894)",
+            "rgb(0.8946, 0.5038, 0.3998)",
+            "rgb(0.8484, 0.3977, 0.3183)",
+            "rgb(0.7894, 0.2768, 0.2549)",
+            "rgb(0.7285, 0.1550, 0.1974)",
+            "rgb(0.6461, 0.0775, 0.1603)",
+            "rgb(0.5193, 0.0369, 0.1400)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "sh_RdGy_r_ch4_850hpa",
+            "sh_RdGy_r_co2_500hpa",
+            "sh_RdGy_r_co2_totalcolumn",
+            "Methane at 850 hPa",
+            "Carbon dioxide at 500 hPa",
+            "Total column of carbon dioxide",
+            "ch4",
+            "methane",
+            "co2",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.2039, 0.2039, 0.2039)",
+            "rgb(0.3064, 0.3064, 0.3064)",
+            "rgb(0.4313, 0.4313, 0.4313)",
+            "rgb(0.5451, 0.5451, 0.5451)",
+            "rgb(0.6549, 0.6549, 0.6549)",
+            "rgb(0.7499, 0.7499, 0.7499)",
+            "rgb(0.8317, 0.8317, 0.8317)",
+            "rgb(0.9023, 0.9023, 0.9023)",
+            "rgb(0.9690, 0.9690, 0.9690)",
+            "rgb(0.9980, 0.9640, 0.9440)",
+            "rgb(0.9937, 0.8865, 0.8235)",
+            "rgb(0.9811, 0.7924, 0.6955)",
+            "rgb(0.9617, 0.6761, 0.5469)",
+            "rgb(0.9130, 0.5463, 0.4324)",
+            "rgb(0.8484, 0.3977, 0.3183)",
+            "rgb(0.7783, 0.2547, 0.2444)",
+            "rgb(0.7008, 0.0997, 0.1712)",
+            "rgb(0.5539, 0.0480, 0.1456)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_23" : {
+        "n_colours" : "23",
+        "tags" : [
+            "23",
+            "eccharts",
+            "sh_RdGy_r_ch4_surface",
+            "Methane at surface",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.1882, 0.1882, 0.1882)",
+            "rgb(0.2824, 0.2824, 0.2824)",
+            "rgb(0.3778, 0.3778, 0.3778)",
+            "rgb(0.4848, 0.4848, 0.4848)",
+            "rgb(0.5843, 0.5843, 0.5843)",
+            "rgb(0.6706, 0.6706, 0.6706)",
+            "rgb(0.7557, 0.7557, 0.7557)",
+            "rgb(0.8258, 0.8258, 0.8258)",
+            "rgb(0.8880, 0.8880, 0.8880)",
+            "rgb(0.9452, 0.9452, 0.9452)",
+            "rgb(0.9998, 0.9972, 0.9957)",
+            "rgb(0.9965, 0.9363, 0.9010)",
+            "rgb(0.9928, 0.8699, 0.7976)",
+            "rgb(0.9797, 0.7841, 0.6849)",
+            "rgb(0.9631, 0.6844, 0.5576)",
+            "rgb(0.9223, 0.5675, 0.4487)",
+            "rgb(0.8715, 0.4507, 0.3590)",
+            "rgb(0.8115, 0.3211, 0.2758)",
+            "rgb(0.7451, 0.1882, 0.2131)",
+            "rgb(0.6692, 0.0849, 0.1640)",
+            "rgb(0.5308, 0.0406, 0.1419)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "sh_RdGy_r_ch4_totalcolumn",
+            "Total column of methane",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.2353, 0.2353, 0.2353)",
+            "rgb(0.3778, 0.3778, 0.3778)",
+            "rgb(0.5294, 0.5294, 0.5294)",
+            "rgb(0.6627, 0.6627, 0.6627)",
+            "rgb(0.7791, 0.7791, 0.7791)",
+            "rgb(0.8784, 0.8784, 0.8784)",
+            "rgb(0.9595, 0.9595, 0.9595)",
+            "rgb(0.9974, 0.9529, 0.9268)",
+            "rgb(0.9922, 0.8588, 0.7804)",
+            "rgb(0.9686, 0.7176, 0.6000)",
+            "rgb(0.9176, 0.5569, 0.4405)",
+            "rgb(0.8392, 0.3765, 0.3020)",
+            "rgb(0.7451, 0.1882, 0.2131)",
+            "rgb(0.6000, 0.0627, 0.1529)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_17" : {
+        "n_colours" : "17",
+        "tags" : [
+            "17",
+            "eccharts",
+            "sh_RdGy_r_co2_300hpa",
+            "Carbon dioxide at 300 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.2275, 0.2275, 0.2275)",
+            "rgb(0.3599, 0.3599, 0.3599)",
+            "rgb(0.5027, 0.5027, 0.5027)",
+            "rgb(0.6314, 0.6314, 0.6314)",
+            "rgb(0.7499, 0.7499, 0.7499)",
+            "rgb(0.8434, 0.8434, 0.8434)",
+            "rgb(0.9261, 0.9261, 0.9261)",
+            "rgb(0.9998, 0.9972, 0.9957)",
+            "rgb(0.9949, 0.9087, 0.8579)",
+            "rgb(0.9825, 0.8007, 0.7061)",
+            "rgb(0.9603, 0.6678, 0.5363)",
+            "rgb(0.8946, 0.5038, 0.3998)",
+            "rgb(0.8171, 0.3322, 0.2810)",
+            "rgb(0.7285, 0.1550, 0.1974)",
+            "rgb(0.5769, 0.0554, 0.1493)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_30" : {
+        "n_colours" : "30",
+        "tags" : [
+            "30",
+            "eccharts",
+            "sh_RdGy_r_co2_50hpa",
+            "Carbon dioxide at 500 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.1647, 0.1647, 0.1647)",
+            "rgb(0.2353, 0.2353, 0.2353)",
+            "rgb(0.3064, 0.3064, 0.3064)",
+            "rgb(0.3867, 0.3867, 0.3867)",
+            "rgb(0.4670, 0.4670, 0.4670)",
+            "rgb(0.5373, 0.5373, 0.5373)",
+            "rgb(0.6078, 0.6078, 0.6078)",
+            "rgb(0.6784, 0.6784, 0.6784)",
+            "rgb(0.7440, 0.7440, 0.7440)",
+            "rgb(0.7966, 0.7966, 0.7966)",
+            "rgb(0.8492, 0.8492, 0.8492)",
+            "rgb(0.8927, 0.8927, 0.8927)",
+            "rgb(0.9356, 0.9356, 0.9356)",
+            "rgb(0.9785, 0.9785, 0.9785)",
+            "rgb(0.9986, 0.9751, 0.9612)",
+            "rgb(0.9958, 0.9253, 0.8837)",
+            "rgb(0.9931, 0.8754, 0.8062)",
+            "rgb(0.9852, 0.8173, 0.7273)",
+            "rgb(0.9728, 0.7426, 0.6318)",
+            "rgb(0.9603, 0.6678, 0.5363)",
+            "rgb(0.9269, 0.5781, 0.4568)",
+            "rgb(0.8854, 0.4826, 0.3835)",
+            "rgb(0.8438, 0.3871, 0.3101)",
+            "rgb(0.8005, 0.2990, 0.2654)",
+            "rgb(0.7506, 0.1993, 0.2183)",
+            "rgb(0.7008, 0.0997, 0.1712)",
+            "rgb(0.6000, 0.0627, 0.1529)",
+            "rgb(0.4962, 0.0295, 0.1363)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_32" : {
+        "n_colours" : "32",
+        "tags" : [
+            "32",
+            "eccharts",
+            "sh_RdGy_r_co2_850hpa",
+            "Carbon dioxide at 850 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.1647, 0.1647, 0.1647)",
+            "rgb(0.2275, 0.2275, 0.2275)",
+            "rgb(0.2902, 0.2902, 0.2902)",
+            "rgb(0.3689, 0.3689, 0.3689)",
+            "rgb(0.4402, 0.4402, 0.4402)",
+            "rgb(0.5116, 0.5116, 0.5116)",
+            "rgb(0.5765, 0.5765, 0.5765)",
+            "rgb(0.6471, 0.6471, 0.6471)",
+            "rgb(0.7098, 0.7098, 0.7098)",
+            "rgb(0.7616, 0.7616, 0.7616)",
+            "rgb(0.8083, 0.8083, 0.8083)",
+            "rgb(0.8609, 0.8609, 0.8609)",
+            "rgb(0.9023, 0.9023, 0.9023)",
+            "rgb(0.9404, 0.9404, 0.9404)",
+            "rgb(0.9785, 0.9785, 0.9785)",
+            "rgb(0.9986, 0.9751, 0.9612)",
+            "rgb(0.9962, 0.9308, 0.8923)",
+            "rgb(0.9937, 0.8865, 0.8235)",
+            "rgb(0.9880, 0.8339, 0.7486)",
+            "rgb(0.9755, 0.7592, 0.6531)",
+            "rgb(0.9645, 0.6927, 0.5682)",
+            "rgb(0.9453, 0.6205, 0.4894)",
+            "rgb(0.9084, 0.5356, 0.4242)",
+            "rgb(0.8669, 0.4401, 0.3509)",
+            "rgb(0.8281, 0.3543, 0.2915)",
+            "rgb(0.7839, 0.2657, 0.2497)",
+            "rgb(0.7396, 0.1772, 0.2078)",
+            "rgb(0.6807, 0.0886, 0.1659)",
+            "rgb(0.5885, 0.0591, 0.1511)",
+            "rgb(0.4962, 0.0295, 0.1363)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_grey_red_73" : {
+        "n_colours" : "73",
+        "tags" : [
+            "73",
+            "eccharts",
+            "sh_RdGy_r_co2_surface",
+            "Carbon dioxide at surface",
+            "co2",
+            "carbon dioxide",
+            "cams"          
+        ],
+        "values" : [
+            "rgb(0.1020, 0.1020, 0.1020)",
+            "rgb(0.1255, 0.1255, 0.1255)",
+            "rgb(0.1569, 0.1569, 0.1569)",
+            "rgb(0.1804, 0.1804, 0.1804)",
+            "rgb(0.2118, 0.2118, 0.2118)",
+            "rgb(0.2353, 0.2353, 0.2353)",
+            "rgb(0.2667, 0.2667, 0.2667)",
+            "rgb(0.2902, 0.2902, 0.2902)",
+            "rgb(0.3243, 0.3243, 0.3243)",
+            "rgb(0.3599, 0.3599, 0.3599)",
+            "rgb(0.3867, 0.3867, 0.3867)",
+            "rgb(0.4224, 0.4224, 0.4224)",
+            "rgb(0.4491, 0.4491, 0.4491)",
+            "rgb(0.4848, 0.4848, 0.4848)",
+            "rgb(0.5116, 0.5116, 0.5116)",
+            "rgb(0.5451, 0.5451, 0.5451)",
+            "rgb(0.5686, 0.5686, 0.5686)",
+            "rgb(0.6000, 0.6000, 0.6000)",
+            "rgb(0.6314, 0.6314, 0.6314)",
+            "rgb(0.6549, 0.6549, 0.6549)",
+            "rgb(0.6863, 0.6863, 0.6863)",
+            "rgb(0.7098, 0.7098, 0.7098)",
+            "rgb(0.7382, 0.7382, 0.7382)",
+            "rgb(0.7557, 0.7557, 0.7557)",
+            "rgb(0.7791, 0.7791, 0.7791)",
+            "rgb(0.7966, 0.7966, 0.7966)",
+            "rgb(0.8200, 0.8200, 0.8200)",
+            "rgb(0.8434, 0.8434, 0.8434)",
+            "rgb(0.8609, 0.8609, 0.8609)",
+            "rgb(0.8832, 0.8832, 0.8832)",
+            "rgb(0.8975, 0.8975, 0.8975)",
+            "rgb(0.9166, 0.9166, 0.9166)",
+            "rgb(0.9309, 0.9309, 0.9309)",
+            "rgb(0.9499, 0.9499, 0.9499)",
+            "rgb(0.9642, 0.9642, 0.9642)",
+            "rgb(0.9833, 0.9833, 0.9833)",
+            "rgb(0.9998, 0.9972, 0.9957)",
+            "rgb(0.9989, 0.9806, 0.9699)",
+            "rgb(0.9977, 0.9585, 0.9354)",
+            "rgb(0.9968, 0.9419, 0.9096)",
+            "rgb(0.9955, 0.9197, 0.8751)",
+            "rgb(0.9946, 0.9031, 0.8493)",
+            "rgb(0.9934, 0.8810, 0.8148)",
+            "rgb(0.9925, 0.8644, 0.7890)",
+            "rgb(0.9880, 0.8339, 0.7486)",
+            "rgb(0.9825, 0.8007, 0.7061)",
+            "rgb(0.9783, 0.7758, 0.6743)",
+            "rgb(0.9728, 0.7426, 0.6318)",
+            "rgb(0.9686, 0.7176, 0.6000)",
+            "rgb(0.9631, 0.6844, 0.5576)",
+            "rgb(0.9589, 0.6595, 0.5257)",
+            "rgb(0.9453, 0.6205, 0.4894)",
+            "rgb(0.9315, 0.5887, 0.4650)",
+            "rgb(0.9130, 0.5463, 0.4324)",
+            "rgb(0.8946, 0.5038, 0.3998)",
+            "rgb(0.8807, 0.4720, 0.3753)",
+            "rgb(0.8623, 0.4295, 0.3427)",
+            "rgb(0.8484, 0.3977, 0.3183)",
+            "rgb(0.8281, 0.3543, 0.2915)",
+            "rgb(0.8115, 0.3211, 0.2758)",
+            "rgb(0.7894, 0.2768, 0.2549)",
+            "rgb(0.7728, 0.2436, 0.2392)",
+            "rgb(0.7506, 0.1993, 0.2183)",
+            "rgb(0.7285, 0.1550, 0.1974)",
+            "rgb(0.7119, 0.1218, 0.1817)",
+            "rgb(0.6807, 0.0886, 0.1659)",
+            "rgb(0.6461, 0.0775, 0.1603)",
+            "rgb(0.6000, 0.0627, 0.1529)",
+            "rgb(0.5654, 0.0517, 0.1474)",
+            "rgb(0.5193, 0.0369, 0.1400)",
+            "rgb(0.4847, 0.0258, 0.1345)",
+            "rgb(0.4385, 0.0111, 0.1271)",
+            "rgb(0.4039, 0.0000, 0.1216)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_22" : {
+        "n_colours" : "22",
+        "tags" : [
+            "22",
+            "eccharts",
+            "sh_Spectral_r_co2_300hpa",
+            "sh_Spectral_r_co2_500hpa",
+            "sh_Spectral_r_co2_50hpa",
+            "sh_Spectral_r_co2_850hpa",
+            "sh_Spectral_r_co2_surface",
+            "Carbon dioxide at 300 hPa",
+            "Carbon dioxide at 500 hPa",
+            "Carbon dioxide at 50 hPa",
+            "Carbon dioxide at 850 hPa",
+            "Carbon dioxide at surface",
+            "rainbow",
+            "light",
+            "purple",
+            "red",
+            "co2",
+            "carbon dioxide",
+            "cams" 
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.2874, 0.4150, 0.6851)",
+            "rgb(0.2062, 0.5202, 0.7349)",
+            "rgb(0.2800, 0.6270, 0.7024)",
+            "rgb(0.3760, 0.7340, 0.6581)",
+            "rgb(0.4955, 0.7982, 0.6457)",
+            "rgb(0.6334, 0.8521, 0.6437)",
+            "rgb(0.7477, 0.8980, 0.6275)",
+            "rgb(0.8566, 0.9423, 0.6053)",
+            "rgb(0.9289, 0.9715, 0.6381)",
+            "rgb(0.9750, 0.9900, 0.7100)",
+            "rgb(0.9990, 0.9690, 0.6970)",
+            "rgb(0.9972, 0.9118, 0.6011)",
+            "rgb(0.9953, 0.8400, 0.5128)",
+            "rgb(0.9935, 0.7477, 0.4353)",
+            "rgb(0.9873, 0.6474, 0.3642)",
+            "rgb(0.9693, 0.5174, 0.3043)",
+            "rgb(0.9426, 0.4058, 0.2683)",
+            "rgb(0.8854, 0.3190, 0.2904)",
+            "rgb(0.8226, 0.2291, 0.3068)",
+            "rgb(0.7211, 0.1165, 0.2828)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_27" : {
+        "n_colours" : "27",
+        "tags" : [
+            "27",
+            "eccharts",
+            "sh_Spectral_r_co2_totalcolumn",
+            "Total column of carbon dioxide",
+            "rainbow",
+            "light",
+            "purple",
+            "red",
+            "co2",
+            "carbon_dioxide",
+            "cams" 
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.3077, 0.3887, 0.6727)",
+            "rgb(0.2401, 0.4764, 0.7142)",
+            "rgb(0.2241, 0.5646, 0.7283)",
+            "rgb(0.3040, 0.6537, 0.6913)",
+            "rgb(0.3840, 0.7429, 0.6544)",
+            "rgb(0.4849, 0.7940, 0.6458)",
+            "rgb(0.5804, 0.8314, 0.6444)",
+            "rgb(0.6842, 0.8722, 0.6404)",
+            "rgb(0.7749, 0.9091, 0.6219)",
+            "rgb(0.8657, 0.9460, 0.6035)",
+            "rgb(0.9250, 0.9700, 0.6321)",
+            "rgb(0.9635, 0.9854, 0.6920)",
+            "rgb(0.9999, 0.9976, 0.7450)",
+            "rgb(0.9985, 0.9547, 0.6730)",
+            "rgb(0.9970, 0.9070, 0.5931)",
+            "rgb(0.9955, 0.8477, 0.5193)",
+            "rgb(0.9939, 0.7708, 0.4547)",
+            "rgb(0.9924, 0.6939, 0.3901)",
+            "rgb(0.9804, 0.5974, 0.3412)",
+            "rgb(0.9679, 0.5074, 0.2997)",
+            "rgb(0.9473, 0.4130, 0.2664)",
+            "rgb(0.8997, 0.3407, 0.2849)",
+            "rgb(0.8520, 0.2684, 0.3033)",
+            "rgb(0.7803, 0.1822, 0.2968)",
+            "rgb(0.6957, 0.0884, 0.2768)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_yellow_blue_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "sh_YlGnBu_co_upper",
+            "sh_YlGnBu_o3_sfc",
+            "Ozone at surface",            
+            "Carbon monoxide at 700 hPa",
+            "co",
+            "carbon_monoxide",
+            "o3",
+            "ozone",
+            "cams",     
+            "yellow",
+            "blue"
+        ],
+        "values" : [
+            "rgb(0.9601,0.9845,0.7624)",
+            "rgb(0.9101,0.9649,0.6956)",
+            "rgb(0.8260,0.9317,0.7023)",
+            "rgb(0.6985,0.8819,0.7138)",
+            "rgb(0.5390,0.8199,0.7294)",
+            "rgb(0.3960,0.7661,0.7481)",
+            "rgb(0.2527,0.7114,0.7684)",
+            "rgb(0.1730,0.6295,0.7595)",
+            "rgb(0.1166,0.5396,0.7393)",
+            "rgb(0.1276,0.4267,0.6861)",
+            "rgb(0.1369,0.3182,0.6348)",
+            "rgb(0.1436,0.2252,0.5905)",
+            "rgb(0.0956,0.1647,0.4780)",
+            "rgb(0.0314,0.1137,0.3451)"
+        ]
+    },
+    "eccharts_green_grey_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "sh_albedo",
+            "sh_brn_f0t1",
+            "Surface albedo",
+            "albedo"
+        ],
+        "values" : [
+            "rgb(0.61,0.61,1)",
+            "rgb(0.1,0.2,0.1)",
+            "rgb(0.2,0.3,0.2)",
+            "rgb(0.3,0.4,0.3)",
+            "rgb(0.5,0.5,0.4)",
+            "rgb(0.6,0.6,0.5)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.8,0.8,0.8)",
+            "rgb(0.9,0.9,0.9)",
+            "rgb(1.0,1.0,1.0)"
+        ]
+    },
+    "eccharts_blue_red1_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "sh_all_aod550",
+            "sh_all_aod",
+            "aerosol_optical_depth",
+            "Aerosol optical depth at 550 nm",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0000,0.0000,0.9456)",
+            "rgb(0.0000,0.3000,1.0000)",
+            "rgb(0.0000,0.6922,1.0000)",
+            "rgb(0.1613,1.0000,0.8065)",
+            "rgb(0.4902,1.0000,0.4775)",
+            "rgb(0.8065,1.0000,0.1613)",
+            "rgb(1.0000,0.7705,0.0000)",
+            "rgb(1.0000,0.4074,0.0000)",
+            "rgb(0.9456,0.0298,0.0000)",
+            "rgb(0.5000,0.0000,0.0000)"
+        ]
+    },
+    "eccharts_rainbow_purple_red1_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "sh_all_ch4_300hpa",
+            "Methane at 300 hPa",
+            "ch4",
+            "methane",
+            "rainbow",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.2265, 0.4939, 0.7225)",
+            "rgb(0.3280, 0.6805, 0.6803)",
+            "rgb(0.5379, 0.8148, 0.6451)",
+            "rgb(0.7477, 0.8980, 0.6275)",
+            "rgb(0.9173, 0.9669, 0.6201)",
+            "rgb(0.9999, 0.9976, 0.7450)",
+            "rgb(0.9967, 0.8975, 0.5771)",
+            "rgb(0.9935, 0.7477, 0.4353)",
+            "rgb(0.9735, 0.5474, 0.3181)",
+            "rgb(0.9140, 0.3624, 0.2794)",
+            "rgb(0.7972, 0.2009, 0.3008)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "sh_all_ch4_500hpa",
+            "Methane at 500 hPa",
+            "sh_all_co2_500hpa",
+            "Carbon dioxide at 500 hPa",
+            "ch4",
+            "co2",
+            "methane",
+            "carbon_dioxide",
+            "rainbow",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.2468, 0.4676, 0.7100)",
+            "rgb(0.2800, 0.6270, 0.7024)",
+            "rgb(0.4318, 0.7732, 0.6466)",
+            "rgb(0.6334, 0.8521, 0.6437)",
+            "rgb(0.8022, 0.9202, 0.6164)",
+            "rgb(0.9289, 0.9715, 0.6381)",
+            "rgb(0.9999, 0.9976, 0.7450)",
+            "rgb(0.9972, 0.9118, 0.6011)",
+            "rgb(0.9944, 0.7938, 0.4740)",
+            "rgb(0.9873, 0.6474, 0.3642)",
+            "rgb(0.9610, 0.4574, 0.2766)",
+            "rgb(0.8854, 0.3190, 0.2904)",
+            "rgb(0.7719, 0.1728, 0.2948)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "sh_all_ch4_50hpa",
+            "Methane at 50 hPa",            
+            "ch4",
+            "methane",
+            "rainbow",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.3010, 0.3975, 0.6768)",
+            "rgb(0.2265, 0.4939, 0.7225)",
+            "rgb(0.2481, 0.5913, 0.7172)",
+            "rgb(0.3280, 0.6805, 0.6803)",
+            "rgb(0.4212, 0.7691, 0.6468)",
+            "rgb(0.5379, 0.8148, 0.6451)",
+            "rgb(0.6441, 0.8563, 0.6435)",
+            "rgb(0.7477, 0.8980, 0.6275)",
+            "rgb(0.8475, 0.9386, 0.6072)",
+            "rgb(0.9173, 0.9669, 0.6201)",
+            "rgb(0.9596, 0.9839, 0.6860)",
+            "rgb(0.9999, 0.9976, 0.7450)",
+            "rgb(0.9984, 0.9499, 0.6651)",
+            "rgb(0.9967, 0.8975, 0.5771)",
+            "rgb(0.9950, 0.8246, 0.4999)",
+            "rgb(0.9935, 0.7477, 0.4353)",
+            "rgb(0.9887, 0.6574, 0.3689)",
+            "rgb(0.9735, 0.5474, 0.3181)",
+            "rgb(0.9596, 0.4474, 0.2720)",
+            "rgb(0.9140, 0.3624, 0.2794)",
+            "rgb(0.8615, 0.2829, 0.2997)",
+            "rgb(0.7972, 0.2009, 0.3008)",
+            "rgb(0.7042, 0.0977, 0.2788)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "sh_all_ch4_850hpa",
+            "sh_all_co2_850hpa",
+            "sh_all_co2_50hpa",
+            "Methane at 850 hPa",
+            "Carbon dioxide at 850 hPa",
+            "Carbon dioxide at 50 hPa",
+            "ch4",
+            "co2",
+            "methane",
+            "carbon_dioxide",
+            "rainbow",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.2130, 0.5114, 0.7308)",
+            "rgb(0.3600, 0.7162, 0.6655)",
+            "rgb(0.5910, 0.8355, 0.6443)",
+            "rgb(0.8203, 0.9276, 0.6127)",
+            "rgb(0.9558, 0.9823, 0.6800)",
+            "rgb(0.9982, 0.9452, 0.6571)",
+            "rgb(0.9947, 0.8092, 0.4870)",
+            "rgb(0.9818, 0.6074, 0.3458)",
+            "rgb(0.9330, 0.3913, 0.2720)",
+            "rgb(0.8141, 0.2197, 0.3048)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "rainbow",
+            "sh_all_co2_300hpa",
+            "sh_all_co_upper",
+            "Carbon dioxide at 300 hPa",
+            "Carbon monoxide at 700 hPa",
+            "co2",
+            "co",
+            "carbon_dioxide",
+            "carbon_monoxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.3686, 0.3098, 0.6353)",
+            "rgb(0.2401, 0.4764, 0.7142)",
+            "rgb(0.3040, 0.6537, 0.6913)",
+            "rgb(0.4849, 0.7940, 0.6458)",
+            "rgb(0.6842, 0.8722, 0.6404)",
+            "rgb(0.8657, 0.9460, 0.6035)",
+            "rgb(0.9635, 0.9854, 0.6920)",
+            "rgb(0.9985, 0.9547, 0.6730)",
+            "rgb(0.9955, 0.8477, 0.5193)",
+            "rgb(0.9924, 0.6939, 0.3901)",
+            "rgb(0.9679, 0.5074, 0.2997)",
+            "rgb(0.8997, 0.3407, 0.2849)",
+            "rgb(0.7803, 0.1822, 0.2968)",
+            "rgb(0.6196, 0.0039, 0.2588)"
+        ]
+    },
+    "eccharts_rainbow_blue_brown_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "brown",
+            "sh_all_co_50hpa",
+            "sh_all_co_300hpa",
+            "sh_all_co_500hpa",
+            "sh_all_co_850hpa",
+            "sh_all_go3_300hpa",
+            "sh_all_go3_500hpa",
+            "sh_all_go3_850hpa",
+            "sh_all_go3_50hpa",
+            "sh_all_o3_300hpa",
+            "sh_all_o3_500hpa",
+            "sh_all_o3_850hpa",
+            "sh_all_o3_50hpa",
+            "sh_all_hcho_300hpa",
+            "sh_all_hcho_500hpa",
+            "sh_all_hcho_850hpa",
+            "sh_all_hcho_50hpa",
+            "sh_all_no2_850hpa",
+            "sh_all_no2_500hpa",
+            "sh_all_no2_300hpa",
+            "sh_all_no2_50hpa",
+            "sh_all_so2_850hpa",            
+            "sh_all_so2_500hpa",
+            "sh_all_so2_300hpa",
+            "sh_all_so2_50hpa",
+            "Nitrogen dioxide at 850 hPa",            
+            "Nitrogen dioxide at 500 hPa",            
+            "Nitrogen dioxide at 300 hPa",
+            "Nitrogen dioxide at 50 hPa",            
+            "Formaldehyde at 300 hPa",            
+            "Formaldehyde at 500 hPa",            
+            "Formaldehyde at 850 hPa",
+            "Formaldehyde at 50 hPa",
+            "Carbon monoxide at 50 hPa",
+            "Carbon monoxide at 300 hPa",
+            "Carbon monoxide at 500 hPa",
+            "Carbon monoxide at 850 hPa",
+            "Ozone at 50 hPa",            
+            "Ozone at 300 hPa",
+            "Ozone at 500 hPa",
+            "Ozone at 850 hPa",
+            "Sulphur dioxide at 50 hPa",
+            "Sulphur dioxide at 30 hPa",
+            "Sulphur dioxide at 850 hPa",
+            "Sulphur dioxide at 500 hPa",
+            "co",
+            "o3",
+            "hcho",
+            "no2",
+            "so2",
+            "carbon_monoxide",
+            "nitrogen dioxide",
+            "formaldehyde",
+            "cams"
+            ],
+        "values" : [
+            "rgb(0.149020,0.356863,0.627451)",
+            "rgb(0.149020,0.568627,0.439216)",
+            "rgb(0.419608,0.698039,0.356863)",
+            "rgb(0.658824,0.788235,0.419608)",
+            "rgb(1.000000,0.956863,0.607843)",
+            "rgb(0.956863,0.819608,0.219608)",
+            "rgb(0.917647,0.709804,0.219608)",
+            "rgb(0.866667,0.529412,0.250980)",
+            "rgb(0.800000,0.207843,0.200000)",
+            "rgb(0.607843,0.086275,0.137255)",
+            "rgb(0.337255,0.098039,0.098039)",
+            "rgb(0.2039,0.098039,0.098039)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "rainbow",
+            "sh_all_f03t70_beauf",
+            "10 m wind gust"
+        ],
+        "values" : [
+            "rgb(0.85,1,1)",
+            "rgb(0.65,1,1)",
+            "rgb(0.45,0.95,1)",
+            "rgb(0.6,1,0.6)",
+            "rgb(0.65,0.95,0.2)",
+            "rgb(1,1,0)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.5,0)",
+            "rgb(1,0,0)",
+            "rgb(0.9,0,0.5)",
+            "rgb(0.7,0,0.7)"
+        ]
+    },
+    "eccharts_rainbow_purple_burgundy_18" : {
+        "n_colours" : "18",
+        "tags" : [
+            "18",
+            "eccharts",
+            "rainbow",
+            "purple",
+            "burgundy",
+            "sh_all_f05t300lst",
+            "Convective precipitation",
+            "rain"
+        ],
+        "values" : [
+            "rgb(0.95,0.65,0.95)",
+            "rgb(0.85,0.55,0.85)",
+            "rgb(0.75,0.5,0.85)",
+            "rgb(0.6,0.6,1)",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.8,1.0)",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "rgb(1,1,0.5)",
+            "yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "rgb(1,0.45,0)",
+            "red",
+            "rgb(0.8,0,0)",
+            "burgundy"
+        ]
+    },
+    "eccharts_rainbow_blue_charcoal_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "sh_all_f0t18i1_5",
+            "sh_all_f0t20lst",
+            "total_swell_height",
+            "rainbow",
+            "blue",
+            "charcoal",
+            "wave",
+            "swh",
+            "Significant height of total swell",
+            "Mean period of total swell"
+        ],
+        "values" : [
+            "blue",
+            "greenish_blue",
+            "sky",
+            "yellowish_green",
+            "yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "red",
+            "brown",
+            "charcoal"
+        ]
+    },
+    "eccharts_rainbow_blue_pink_18" : {
+        "n_colours" : "18",
+        "tags" : [
+            "18",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "pink",
+            "sh_all_f0t640_energy",
+            "Wave energy flux magnitude"
+        ],
+        "values" : [
+            "rgb(0,0,50)",
+            "rgb(0,0,102)",
+            "rgb(0,33,112)",
+            "rgb(0,69,122)",
+            "rgb(0,112,133)",
+            "rgb(0,143,122)",
+            "rgb(0,153,89)",
+            "rgb(0,163,48)",
+            "rgb(0,173,0)",
+            "rgb(51,184,0)",
+            "rgb(110,194,0)",
+            "rgb(173,204,0)",
+            "rgb(214,186,0)",
+            "rgb(224,130,0)",
+            "rgb(235,69,0)",
+            "rgb(245,3,0)",
+            "rgb(255,0,69)",
+            "rgb(255,0,128)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_24" : {
+        "n_colours" : "24",
+        "tags" : [
+            "24",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "purple",
+            "sh_all_f2t50i2",
+            "10 m wind gust"
+        ],
+        "values" : [
+            "rgb(0.6,0.9,1)",
+            "rgb(0.45,0.7,1)",
+            "rgb(0.3,0.5,1)",
+            "rgb(0.15,0.3,1)",
+            "rgb(0.8,1,0.2)",
+            "rgb(0.65,0.95,0)",
+            "rgb(0.5,0.85,0)",
+            "rgb(0.15,0.75,0.1)",
+            "rgb(0,0.55,0.19)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.74,0)",
+            "rgb(1,0.62,0)",
+            "rgb(1,0.5,0)",
+            "rgb(0.85,0.45,0)",
+            "rgb(1,0.75,0.75)",
+            "rgb(1,0.5,0.5)",
+            "rgb(1,0,0)",
+            "rgb(0.8,0,0)",
+            "rgb(0.6,0,0)",
+            "rgb(0.85,0.6,1)",
+            "rgb(0.75,0.4,1)",
+            "rgb(0.6,0.2,1)",
+            "rgb(0.5,0,0.9)",
+            "rgb(0.35,0,0.6)"
+        ]
+    },
+    "eccharts_rainbow_green_purple_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "eccharts",
+            "rainbow",
+            "green",
+            "purple",
+            "sh_all_f30t100i10",
+            "200 hPa wind speed"
+        ],
+        "values" : [
+            "rgb(0,1,0)",
+            "rgb(1,1,0.3)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0,0)",
+            "rgb(0.9,0,0.5)",
+            "rgb(0.7,0,0.7)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",            
+            "rainbow",
+            "blue",
+            "purple",
+            "sh_all_f5t70lst",
+            "600 hPa wind speed"
+        ],
+        "values" : [
+            "rgb(0.8,1,1)",
+            "rgb(0.5,0.95,1)",
+            "rgb(0,1,0)",
+            "rgb(1,1,0.3)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0,0)",
+            "rgb(0.9,0,0.5)",
+            "rgb(0.7,0,0.7)"
+        ]
+    },
+    "eccharts_rainbow_purple_magenta_17" : {
+        "n_colours" : "17",
+        "tags" : [
+            "17",
+            "eccharts",            
+            "rainbow",
+            "magenta",
+            "purple",
+            "sh_all_fM24t44i4"
+        ],
+        "values" : [
+            "blue_purple",
+            "greenish_blue",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "yellow",
+            "orangish_yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "reddish_orange",
+            "red_orange",
+            "orangish_red",
+            "red",
+            "magenta",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_grey_red_37" : {
+        "n_colours" : "37",
+        "tags" : [
+            "37",
+            "eccharts",
+            "grey",
+            "red",
+            "rainbow",
+            "sh_all_fM32t42i2",
+            "2m temperature percentile",
+            "2 metre dew point temperature percentile",
+            "2m mean temperature over an interval",
+            "2m temperature",
+            "2m temperature from UERRA dataset",
+            "2m temperature from HRES forecast",
+            "2m temperature percentile",
+            "Maximum 2 metre temperature",
+            "Minimum 2 metre temperature",
+            "2m temperature control forecast",
+            "T2m",
+            "temperature"
+        ],
+        "values" : [
+            "rgb(0.3,0.3,0.3)",
+            "rgb(0.4,0.4,0.4)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.8,0.8,0.8)",
+            "rgb(0.35,0,0.6)",
+            "rgb(0.5,0,0.9)",
+            "rgb(0.6,0.2,1)",
+            "rgb(0.75,0.4,1)",
+            "rgb(0.85,0.6,1)",
+            "rgb(0,0,0.75)",
+            "rgb(0,0,1)",
+            "rgb(0.2,0.4,1)",
+            "rgb(0.4,0.7,1)",
+            "rgb(0.6,0.9,1)",
+            "rgb(0,0.55,0.19)",
+            "rgb(0.15,0.75,0.1)",
+            "rgb(0.5,0.85,0)",
+            "rgb(0.65,0.95,0)",
+            "rgb(0.8,1,0.2)",
+            "rgb(0.65,0.65,0)",
+            "rgb(0.8,0.8,0)",
+            "rgb(0.92,0.92,0)",
+            "rgb(1,1,0)",
+            "rgb(1,1,0.6)",
+            "rgb(0.85,0.45,0)",
+            "rgb(1,0.5,0)",
+            "rgb(1,0.62,0)",
+            "rgb(1,0.74,0)",
+            "rgb(1,0.85,0)",
+            "rgb(0.6,0,0)",
+            "rgb(0.8,0,0)",
+            "rgb(1,0,0)",
+            "rgb(1,0.4,0.4)",
+            "rgb(1,0.6,0.6)",
+            "rgb(1,0.75,0.75)"
+        ]
+    },
+    "eccharts_rainbow_blue_magenta_24" : {
+        "n_colours" : "24",
+        "tags" : [
+            "24",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "magenta",
+            "sh_all_fM48t48i4"
+        ],
+        "values" : [
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.85)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.85)",
+            "rgb(0.25,0,1)",
+            "blue_purple",
+            "greenish_blue",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "yellow",
+            "orangish_yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "reddish_orange",
+            "red_orange",
+            "orangish_red",
+            "red",
+            "magenta",
+            "magenta",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_blue_magenta_27" : {
+        "n_colours" : "27",
+        "tags" : [
+            "27",
+            "eccharts",
+            "sh_all_fM48t56i4",
+            "sh_f220t300",
+            "rainbow",
+            "blue",
+            "magenta",
+            "temperature",
+            "2Td",
+            "2 metre dew point temperature",
+            "2 metre dew point temperature percentile"
+        ],
+        "values" : [
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.85)",
+            "rgb(0.25,0,1)",
+            "blue_purple",
+            "greenish_blue",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "yellow",
+            "orangish_yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "reddish_orange",
+            "red_orange",
+            "orangish_red",
+            "red",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_blue_magenta_53" : {
+        "n_colours" : "53",
+        "tags" : [
+            "53",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "magenta",
+            "temperature",            
+            "sh_all_fM48t56i4_ct_wh",
+            "2m temperature percentile",
+            "2 metre dew point temperature percentile",
+            "2 metre dew point temperature",
+            "2m mean temperature over an interval",
+            "2m temperature",
+            "2m temperature from UERRA dataset",
+            "2m temperature percentile",
+            "Maximum 2 metre temperature",
+            "Minimum 2 metre temperature",
+            "2m temperature control forecast",
+            "T2m",
+            "temperature"
+        ],
+        "values" : [
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.85)",
+            "rgb(0,0,0.85)",
+            "rgb(0.25,0,1)",
+            "rgb(0.25,0,1)",
+            "blue_purple",
+            "blue_purple",
+            "greenish_blue",
+            "greenish_blue",
+            "blue_green",
+            "blue_green",
+            "bluish_green",
+            "bluish_green",
+            "yellow_green",
+            "yellow_green",
+            "greenish_yellow",
+            "greenish_yellow",
+            "yellow",
+            "yellow",
+            "orangish_yellow",
+            "orangish_yellow",
+            "orange_yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "yellowish_orange",
+            "orange",
+            "orange",
+            "reddish_orange",
+            "reddish_orange",
+            "red_orange",
+            "red_orange",
+            "orangish_red",
+            "orangish_red",
+            "red",
+            "red",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_purple_magenta_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "sh_all_fM52t48i4",
+            "sh_all_fM64t36i4",
+            "sh_all_fM80t20i4",
+            "rainbow",
+            "blue",
+            "magenta",
+            "temperature",            
+            "sh_all_fM48t56i4_ct_wh",
+            "2m temperature percentile",
+            "2 metre dew point temperature percentile",
+            "2 metre dew point temperature",
+            "2m mean temperature over an interval",
+            "2m temperature",
+            "2m temperature from UERRA dataset",
+            "2m temperature percentile",
+            "Maximum 2 metre temperature",
+            "Minimum 2 metre temperature",
+            "2m temperature control forecast",
+            "T2m",
+            "temperature"            
+        ],
+        "values" : [
+            "rgb(0.88,0.2,0.88)",
+            "rgb(0.68,0.2,0.68)",
+            "rgb(0.48,0.2,0.48)",
+            "rgb(0.28,0.2,0.28)",
+            "rgb(0.2,0,0.4)",
+            "rgb(0.35,0,0.5)",
+            "blue_purple",
+            "greenish_blue",
+            "rgb(0,0.8,1.0)",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "rgb(1,1,0.5)",
+            "yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "rgb(1,0.45,0)",
+            "red",
+            "rgb(0.8,0,0)",
+            "burgundy",
+            "rose",
+            "magenta",
+            "rgb(1,0.5,1)",
+            "rgb(1,0.75,1)"
+        ]
+    },
+    "eccharts_rainbow_purple_magenta_light_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "sh_all_fM52t48i4_light",
+            "light",
+            "rainbow",
+            "blue",
+            "magenta",
+            "temperature",            
+            "sh_all_fM48t56i4_ct_wh",
+            "2m temperature percentile",
+            "2 metre dew point temperature percentile",
+            "2 metre dew point temperature",
+            "2m mean temperature over an interval",
+            "2m temperature",
+            "2m temperature from UERRA dataset",
+            "2m temperature percentile",
+            "Maximum 2 metre temperature",
+            "Minimum 2 metre temperature",
+            "2m temperature control forecast",
+            "T2m",
+            "temperature" 
+        ],
+        "values" : [
+            "rgb(0.95,0.65,0.95)",
+            "rgb(0.85,0.55,0.85)",
+            "rgb(0.75,0.5,0.75)",
+            "rgb(0.6,0.5,0.6)",
+            "rgb(0.5,0.35,0.7)",
+            "rgb(0.65,0.45,0.85)",
+            "rgb(0.75,0.65,1)",
+            "rgb(0.4,0.85,1)",
+            "rgb(0.47,0.93,1)",
+            "rgb(0.65,1,1)",
+            "rgb(0.6,1,0.75)",
+            "rgb(0.75,1,0.65)",
+            "rgb(0.95,1,0.6)",
+            "rgb(1,1,0.9)",
+            "rgb(1,1,0.7)",
+            "rgb(1,0.9,0.65)",
+            "rgb(1,0.82,0.67)",
+            "rgb(1,0.75,0.55)",
+            "rgb(1,0.55,0.55)",
+            "rgb(0.9,0.4,0.4)",
+            "rgb(0.8,0.35,0.4)",
+            "rgb(0.9,0.55,0.65)",
+            "rgb(1,0.62,1)",
+            "rgb(1,0.75,1)",
+            "rgb(1,0.85,1)"
+        ]
+    },
+    "eccharts_rainbow_purple_magenta_31" : {
+        "n_colours" : "31",
+        "tags" : [
+            "31",
+            "eccharts",
+            "sh_all_fM64t52i4",
+            "rainbow",
+            "blue",
+            "magenta",
+            "temperature",
+            "2m temperature percentile",
+            "2 metre dew point temperature",
+            "2 metre dew point temperature percentile",
+            "250 hPa temperature",
+            "2m mean temperature over an interval",
+            "2m temperature",
+            "2m temperature from UERRA dataset",
+            "2m temperature percentile",
+            "500 hPa temperature",
+            "600 hPa temperature",
+            "700 hPa temperature",
+            "800 hPa temperature",
+            "850 hPa temperature",
+            "850 hPa wet bulb potential temperature",
+            "925 hPa temperature",
+            "Maximum 2 metre temperature",
+            "Minimum 2 metre temperature",
+            "YOPP project: 2m temperature control forecast"
+        ],
+        "values" : [
+            "rgb(0,0,0.1)",
+            "rgb(0.1,0,0.2)",
+            "rgb(0.2,0,0.4)",
+            "rgb(0.35,0,0.5)",
+            "rgb(0.42,0,0.6)",
+            "violet",
+            "rgb(0.5,0,0.85)",
+            "blue_purple",
+            "rgb(0.42,0.08,1)",
+            "rgb(0.36,0.16,1)",
+            "rgb(0.25,0.25,1)",
+            "rgb(0.1,0.4,1)",
+            "greenish_blue",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.7,1)",
+            "rgb(0,0.8,1)",
+            "rgb(0,0.9,1)",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "yellow",
+            "orangish_yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "reddish_orange",
+            "red_orange",
+            "orangish_red",
+            "red",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_white_grey_30" : {
+        "n_colours" : "30",
+        "tags" : [
+            "30",
+            "eccharts",
+            "rainbow",
+            "white",
+            "grey",
+            "sh_all_fM80t56i4",
+            "250 hPa temperature"
+        ],
+        "values" : [
+            "rgb(1,1,1)",
+            "rgb(0.9,0.9,0.9)",
+            "rgb(0.8,0.8,0.8)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.68,0.6,0.68)",
+            "rgb(0.48,0.4,0.48)",
+            "rgb(0.28,0.2,0.28)",
+            "rgb(0.2,0,0.4)",
+            "rgb(0.35,0,0.5)",
+            "blue_purple",
+            "greenish_blue",
+            "rgb(0,0.8,1.0)",
+            "blue_green",
+            "rgb(0.15,0.9,0.6)",
+            "rgb(0.4,0.75,0.15)",
+            "rgb(0.75,0.9,0.15)",
+            "rgb(1,1,0.5)",
+            "yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "rgb(1,0.45,0)",
+            "red",
+            "rgb(0.8,0,0)",
+            "burgundy",
+            "rose",
+            "magenta",
+            "rgb(1,0.5,1)",
+            "rgb(1,0.75,1)",
+            "rgb(0.9,0.8,0.9)",
+            "rgb(0.9,0.9,0.9)"
+        ]
+    },
+    "eccharts_red_white_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "red",
+            "yellow",
+            "white",
+            "sh_all_fire",
+            "Fire radiative power"
+        ],
+        "values" : [
+            "rgb(0.2063,0.0000,0.0000)",
+            "rgb(0.3710,0.0000,0.0000)",
+            "rgb(0.5358,0.0000,0.0000)",
+            "rgb(0.7005,0.0000,0.0000)",
+            "rgb(0.8652,0.0000,0.0000)",
+            "rgb(1.0000,0.0299,0.0000)",
+            "rgb(1.0000,0.1946,0.0000)",
+            "rgb(1.0000,0.3593,0.0000)",
+            "rgb(1.0000,0.5240,0.0000)",
+            "rgb(1.0000,0.6887,0.0000)",
+            "rgb(1.0000,0.8534,0.0000)",
+            "rgb(1.0000,1.0000,0.0272)",
+            "rgb(1.0000,1.0000,0.2743)",
+            "rgb(1.0000,1.0000,0.5213)",
+            "rgb(1.0000,1.0000,0.7684)",
+            "rgb(1.0000,1.0000,1.0000)"
+        ]
+    },
+    "eccharts_rainbow_blue_brown_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "brown",
+            "sh_all_hcho_surface",
+            "sh_all_no2_surface",
+            "sh_all_o3_sfc",
+            "sh_all_so2_surface",
+            "sh_all_tcco",
+            "sh_all_tchcho",
+            "sh_all_tcno2",
+            "sh_all_tcso2",
+            "Total column of carbon monoxide",
+            "Total column of formaldehyde",
+            "Total column of nitrogen dioxide",
+            "Total column of sulphur dioxide",
+            "Nitrogen dioxide at surface",
+            "Formaldehyde at surface",
+            "Ozone at surface",
+            "Sulphur dioxide at surface",
+            "hcho",
+            "no2",
+            "o3",
+            "so2",
+            "co",
+            "nitrogen dioxide",
+            "formaldehyde",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.607,0.780,0.917)",
+            "rgb(0.000,0.619,0.878)",
+            "rgb(0.000,0.482,0.749)",
+            "rgb(0.149,0.356,0.627)",
+            "rgb(0.149,0.568,0.439)",
+            "rgb(0.419,0.698,0.356)",
+            "rgb(0.658,0.788,0.419)",
+            "rgb(1.000,0.956,0.607)",
+            "rgb(0.956,0.819,0.219)",
+            "rgb(0.917,0.709,0.219)",
+            "rgb(0.866,0.529,0.250)",
+            "rgb(0.800,0.207,0.200)",
+            "rgb(0.607,0.086,0.137)",
+            "rgb(0.337,0.098,0.098)"
+        ]
+    },
+    "eccharts_rainbow_black_tan_22" : {
+        "n_colours" : "22",
+        "tags" : [
+            "22",
+            "eccharts",
+            "rainbow",
+            "green",
+            "tan",
+            "sh_all_tco3",
+            "Total column of ozone",
+            "o3",
+            "cams"
+        ],
+        "values" : [
+            "black",
+            "navy",
+            "blue",
+            "greenish_blue",
+            "sky",
+            "blue_green",
+            "bluish_green",
+            "yellow_green",
+            "greenish_yellow",
+            "yellow",
+            "orange_yellow",
+            "yellowish_orange",
+            "orange",
+            "reddish_orange",
+            "red",
+            "brick",
+            "brown",
+            "chestnut",
+            "beige",
+            "cream",
+            "tan"
+        ]
+    },
+    "eccharts_rainbow_green_blue_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "rainbow",
+            "green",
+            "blue",
+            "sh_all_uvindex",
+            "Total sky UV index forecast",
+            "Clear-sky UV index",
+            "UV index",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.258824,0.650980,0.192157)",
+            "rgb(0.647059,0.776471,0.000000)",
+            "rgb(1.000000,0.952941,0.000000)",
+            "rgb(1.000000,0.843137,0.000000)",
+            "rgb(0.968627,0.698039,0.000000)",
+            "rgb(0.937255,0.541176,0.000000)",
+            "rgb(0.901961,0.411765,0.000000)",
+            "rgb(0.901961,0.207843,0.062745)",
+            "rgb(0.901961,0.141176,0.517647)",
+            "rgb(0.709804,0.396078,0.647059)",
+            "rgb(0.517647,0.490196,0.709804)",
+            "rgb(0.482353,0.650980,1.000000)",
+            "rgb(0.388235,0.745098,1.000000)",
+            "rgb(0.290196,0.858824,1.000000)"
+        ]
+    },
+    "eccharts_blue_red_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",
+            "sh_anomaly_rb_m20t20",
+            "anomaly",
+            "temperature",
+            "blue",
+            "red",
+            "Extended range: 2m temperature weekly mean anomaly"
+        ],
+        "values" : [
+            "purple",
+            "#2C19FF",
+            "#4433FF",
+            "#7266FF",
+            "#A199FF",
+            "#FFB2BB",
+            "#FF7F8E",
+            "#FF4C61",
+            "#FF334B"
+        ]
+    },
+    "eccharts_blue_red_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "blue",
+            "red",            
+            "sh_anomaly_rb_m24t24"
+        ],
+        "values" : [
+            "purple",
+            "#3F4E7F",
+            "navy",
+            "#2C19FF",
+            "#4433FF",
+            "#5B4CFF",
+            "#7266FF",
+            "#8A7FFF",
+            "#A199FF",
+            "none",
+            "none",
+            "#FFB2BB",
+            "#FF99A5",
+            "#FF7F8E",
+            "#FF6678",
+            "#FF4C61",
+            "#FF334B",
+            "red",
+            "orange_red",
+            "orange"
+        ]
+    },
+    "eccharts_blue_red2_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "anomaly",
+            "blue",
+            "red",            
+            "sh_anomaly_rb_mslp",
+            "mslp_anomaly"
+        ],
+        "values" : [
+            "HSL(220,1,0.1)",
+            "HSL(220,1,0.3)",
+            "HSL(220,1,0.5)",
+            "HSL(220,1,0.7)",
+            "HSL(220,1,0.9)",
+            "HSL(1,1,0.9)",
+            "HSL(1,1,0.7)",
+            "HSL(1,1,0.5)",
+            "HSL(1,1,0.3)",
+            "HSL(1,1,0.1)"
+        ]
+    },
+    "eccharts_red_blue2_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "blue",
+            "red",            
+            "sh_anomaly_rb_rain",
+            "Extended range: precipitation weekly mean anomaly"
+        ],
+        "values" : [
+            "HSL(1,1,0.1)",
+            "HSL(1,1,0.3)",
+            "HSL(1,1,0.5)",
+            "HSL(1,1,0.7)",
+            "HSL(1,1,0.9)",
+            "HSL(220,1,0.9)",
+            "HSL(220,1,0.7)",
+            "HSL(220,1,0.5)",
+            "HSL(220,1,0.3)",
+            "HSL(220,1,0.1)"
+        ]
+    },
+    "eccharts_grey1_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "sh_black_f0t900",
+            "Convective inhibition (CIN)",
+            "Convective inhibition",
+            "cin"
+        ],
+        "values" : [
+            "white",
+            "RGB(0.84,0.84,0.84)",
+            "RGB(0.77,0.76,0.76)",
+            "RGB(0.66,0.65,0.65)",
+            "RGB(0.5,0.48,0.48)",
+            "RGB(0.4,0.39,0.39)",
+            "RGB(0.28,0.23,0.23)",
+            "RGB(0.42,0.075,0.075)"
+        ]
+    },
+    "eccharts_cyan_blue_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",
+            "cyan",
+            "blue",
+            "sh_blu_f0t20_douglas",
+            "Significant height of wind waves",
+            "waves"
+        ],
+        "values" : [
+            "rgb(0.75,1,1)",
+            "rgb(0.5,1,1)",
+            "rgb(0.2,1,1)",
+            "rgb(0,0.9,1)",
+            "rgb(0,0.75,1)",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0,0.85)",
+            "rgb(0,0,0.4)"
+        ]
+    },
+    "eccharts_cyan_blue_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "cyan",
+            "blue",            
+            "sh_blu_f0t20lst",
+            "sh_blu_f0t20lst_warn",
+            "Significant height of wind waves",
+            "waves"
+        ],
+        "values" : [
+            "rgb(0.5,1,1)",
+            "rgb(0.1,1,1)",
+            "rgb(0,0.9,1)",
+            "rgb(0,0.8,1)",
+            "rgb(0,0.7,1)",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.45,1)",
+            "rgb(0,0.2,1)",
+            "rgb(0,0,0.85)",
+            "rgb(0,0,0.65)",
+            "rgb(0,0,0.4)"
+        ]
+    },
+    "eccharts_cyan_blue_light_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "cyan",
+            "blue",            
+            "light",
+            "sh_blu_f0t20lst_light",
+            "Significant height of wind waves",
+            "waves"
+        ],
+        "values" : [
+            "rgb(0.85,1,1)",
+            "rgb(0.7,1,1)",
+            "rgb(0.65,0.95,1)",
+            "rgb(0.6,0.9,1)",
+            "rgb(0.55,0.85,1)",
+            "rgb(0.5,0.8,1)",
+            "rgb(0.45,0.75,1)",
+            "rgb(0.4,0.65,1)",
+            "rgb(0.35,0.55,1)",
+            "rgb(0.3,0.5,0.9)",
+            "rgb(0.2,0.4,0.6)"
+        ]
+    },
+    "eccharts_blue_cyan_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "cyan",
+            "blue",
+            "sh_blu_fM50tM1lst",
+            "1000 hPa divergence",
+            "300 hPa divergence",
+            "500 hPa divergence",
+            "700 hPa divergence",
+            "925 hPa divergence",
+            "250 hPa relative vorticity",
+            "300 hPa relative vorticity",
+            "500 hPa relative vorticity",
+            "700 hPa relative vorticity",
+            "850 hPa relative vorticity",
+            "divergence",
+            "relative vorticity"
+        ],
+        "values" : [
+            "rgb(0,0,0.3)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.7)",
+            "rgb(0,0,0.9)",
+            "rgb(0,0.15,1)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0.45,1)",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.75,1)",
+            "rgb(0,0.85,1)",
+            "rgb(0.2,0.95,1)",
+            "rgb(0.45,1,1)",
+            "rgb(0.75,1,1)"
+        ]
+    },
+    "eccharts_blue_cyan_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",
+            "cyan",
+            "blue",            
+            "sh_blu_fM5tM005lst",
+            "700 hPa vertical velocity",
+            "700w"
+        ],
+        "values" : [
+            "rgb(0,0,0.4)",
+            "rgb(0,0,0.75)",
+            "rgb(0,0,1)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0.5,1)",
+            "rgb(0,0.7,1)",
+            "rgb(0,0.85,1)",
+            "rgb(0.1,1,1)",
+            "rgb(0.6,1,1)"
+        ]
+    },
+    "eccharts_bluegrey_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "blue",
+            "grey",
+            "sh_blugry_f0t1lst",
+            "High cloud cover",
+            "hcc"
+        ],
+        "values" : [
+            "rgb(0.95,0.98,0.98)",
+            "rgb(0.9,0.94,0.94)",
+            "rgb(0.85,0.9,0.9)",
+            "rgb(0.8,0.86,0.86)",
+            "rgb(0.76,0.83,0.83)",
+            "rgb(0.72,0.8,0.8)",
+            "rgb(0.68,0.77,0.77)",
+            "rgb(0.64,0.74,0.74)"
+        ]
+    },
+    "eccharts_blue_red2_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "blue",
+            "red",
+            "sh_blured_f01t500lst",
+            "Stratiform precipitation"
+        ],
+        "values" : [
+            "rgb(240,248,255)",
+            "rgb(135,206,250)",
+            "rgb(0,191,255)",
+            "greenish_blue",
+            "blue",
+            "bluish_purple",
+            "magenta",
+            "orange",
+            "red",
+            "charcol",
+            "maroon"
+        ]
+    },
+    "eccharts_blue_red_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "blue",
+            "red",            
+            "sh_blured_f05t300lst",
+            "Stratiform precipitation"
+        ],
+        "values" : [
+            "cyan",
+            "greenish_blue",
+            "blue",
+            "bluish_purple",
+            "magenta",
+            "orange",
+            "red",
+            "charcol"
+        ]
+    },
+    "eccharts_blue_red2_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "eccharts",
+            "blue",
+            "red", 
+            "sh_blured_f1t100lst",
+            "Stratiform precipitation"
+        ],
+        "values" : [
+            "cyan",
+            "greenish_blue",
+            "blue",
+            "bluish_purple",
+            "magenta",
+            "red",
+            "charcoal"
+        ]
+    },
+    "eccharts_blue_red_dark_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "blue",
+            "red",             
+            "sh_blured_f1t100lst_dark",
+            "Stratiform precipitation"
+        ],
+        "values" : [
+            "rgb(0,0.6,0.6)",
+            "rgb(0,0.25,0.55)",
+            "rgb(0,0,0.5)",
+            "rgb(0.4,0,0.55)",
+            "rgb(0.55,0,0.55)",
+            "rgb(0.5,0,0)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_26" : {
+        "n_colours" : "26",
+        "tags" : [
+            "26",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "purple",
+            "sh_blured_fM16t50_thickness",
+            "Thickness from 1000-500 hPa"
+        ],
+        "values" : [
+            "rgb(0.01,0.01,0.45)",
+            "rgb(0.05,0.05,0.55)",
+            "rgb(0.15,0.25,0.75)",
+            "rgb(0.20,0.30,0.90)",
+            "rgb(0.37,0.50,1.00)",
+            "rgb(0.50,0.70,1.00)",
+            "rgb(0.50,0.90,1.00)",
+            "rgb(0.30,0.68,0.40)",
+            "rgb(0.43,0.77,0.20)",
+            "rgb(0.60,0.86,0.10)",
+            "rgb(0.75,0.98,0.00)",
+            "rgb(1.00,1.00,0.00)",
+            "rgb(1.00,0.89,0.00)",
+            "rgb(1.00,0.78,0.00)",
+            "rgb(1.00,0.67,0.00)",
+            "rgb(1.00,0.55,0.00)",
+            "rgb(1.00,0.35,0.00)",
+            "rgb(1.00,0.23,0.00)",
+            "rgb(1.00,0.00,0.20)",
+            "rgb(1.00,0.00,0.53)",
+            "rgb(1.00,0.00,0.84)",
+            "rgb(1.00,0.00,0.95)",
+            "rgb(0.92,0.00,1.00)",
+            "rgb(0.83,0.00,1.00)",
+            "rgb(0.75,0.00,1.00)",
+            "rgb(0.75,0.00,1.00)"
+        ]
+    },
+    "eccharts_blue_red1_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "blue",
+            "red",
+            "sh_blured_fM1t1lst",
+            "2m maximum temperature extreme forecast index",
+            "2m minimum temperature extreme forecast index",
+            "EFI temperature",
+            "2m temperature extreme forecast index ",
+            "EFI"
+        ],
+        "values" : [
+            "rgb(1, 0, 0.8536, 1)",
+            "rgb(0.2348, 0, 1, 1)",
+            "rgb(0, 0.6768, 1, 1)",
+            "rgb(0, 1, 0.4116, 1)",
+            "rgb(0.5, 1, 0,1)",
+            "none",
+            "none",
+            "none",
+            "none",
+            "none",
+            "rgb(1, 1, 0, 1)",
+            "rgb(1, 0.75, 0, 1)",
+            "rgb(1, 0.5, 0, 1)",
+            "rgb(1, 0.25, 0, 1)",
+            "rgb(1, 0, 0, 1)"
+        ]
+    },
+    "eccharts_blue_red_27" : {
+        "n_colours" : "27",
+        "tags" : [
+            "27",
+            "eccharts",
+            "blue",
+            "red",
+            "sh_blured_fM50t50lst",
+            "sh_blured_fM50t50lst_cell",
+            "300 hPa divergence",
+            "500 hPa divergence",
+            "700 hPa divergence",
+            "925 hPa divergence",
+            "1000 hPa divergence",
+            "700 hPa relative vorticity",
+            "850 hPa relative vorticity",
+            "250 hPa relative vorticity",
+            "300 hPa relative vorticity",
+            "500 hPa relative vorticity"
+        ],
+        "values" : [
+            "rgb(0,0,0.3)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.7)",
+            "rgb(0,0,0.9)",
+            "rgb(0,0.15,1)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0.45,1)",
+            "rgb(0,0.6,1)",
+            "rgb(0,0.75,1)",
+            "rgb(0,0.85,1)",
+            "rgb(0.2,0.95,1)",
+            "rgb(0.45,1,1)",
+            "rgb(0.75,1,1)",
+            "none",
+            "rgb(1,1,0)",
+            "rgb(1,0.9,0)",
+            "rgb(1,0.8,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.6,0)",
+            "rgb(1,0.5,0)",
+            "rgb(1,0.4,0)",
+            "rgb(1,0.3,0)",
+            "rgb(1,0.15,0)",
+            "rgb(0.9,0,0)",
+            "rgb(0.7,0,0)",
+            "rgb(0.5,0,0)",
+            "rgb(0.3,0,0)"
+        ]
+    },
+    "eccharts_blue_red1_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "eccharts",
+            "sh_blured_fM50t50lst_less",
+            "sh_blured_fM50t50lst_less_adaptive",
+            "300 hPa divergence",
+            "500 hPa divergence",
+            "700 hPa divergence",
+            "925 hPa divergence",
+            "1000 hPa divergence",
+            "700 hPa relative vorticity",
+            "850 hPa relative vorticity",
+            "250 hPa relative vorticity",
+            "300 hPa relative vorticity",
+            "500 hPa relative vorticity"
+        ],
+        "values" : [
+            "rgb(0,0,0.3)",
+            "rgb(0,0,0.5)",
+            "rgb(0,0,0.9)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0.45,1)",
+            "rgb(0,0.75,1)",
+            "rgb(0.2,0.95,1)",
+            "rgb(0.45,1,1)",
+            "rgb(0.75,1,1)",
+            "none",
+            "rgb(1,1,0)",
+            "rgb(1,0.9,0)",
+            "rgb(1,0.8,0)",
+            "rgb(1,0.6,0)",
+            "rgb(1,0.4,0)",
+            "rgb(1,0.3,0)",
+            "rgb(0.9,0,0)",
+            "rgb(0.5,0,0)",
+            "rgb(0.3,0,0)"
+        ]
+    },
+    "eccharts_cyan_orange_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "sh_blured_fM50t50lst_narrow_range",
+            "700 hPa relative vorticity",
+            "500 hPa relative vorticity"
+        ],
+        "values" : [
+            "rgb(0,0.75,1)",
+            "rgb(0,0.85,1)",
+            "rgb(0.2,0.95,1)",
+            "rgb(0.45,1,1)",
+            "rgb(0.75,1,1)",
+            "none",
+            "rgb(1,1,0)",
+            "rgb(1,0.9,0)",
+            "rgb(1,0.8,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.6,0)"
+        ]
+    },
+    "eccharts_blue_red2_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "eccharts",
+            "sh_blured_fM5t5lst",
+            "700 hPa vertical velocity"
+        ],
+        "values" : [
+            "rgb(0,0,0.4)",
+            "rgb(0,0,0.75)",
+            "rgb(0,0,1)",
+            "rgb(0,0.3,1)",
+            "rgb(0,0.5,1)",
+            "rgb(0,0.7,1)",
+            "rgb(0,0.85,1)",
+            "rgb(0.1,1,1)",
+            "rgb(0.6,1,1)",
+            "none",
+            "rgb(1,1,0)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.55,0)",
+            "rgb(1,0.4,0)",
+            "rgb(1,0.1,0)",
+            "rgb(0.85,0,0)",
+            "rgb(0.6,0,0)",
+            "rgb(0.4,0,0)"
+        ]
+    },
+    "eccharts_brown_28" : {
+        "n_colours" : "28",
+        "tags" : [
+            "28",
+            "eccharts",
+            "orography",
+            "brown",
+            "sh_brn_fM09t60_oro",
+            "Model orography  from HRES forecast"
+        ],
+        "values" : [
+            "rgb(0.38,0.14,0)",
+            "none",
+            "rgb(0.42,0.16,0)",
+            "rgb(0.46,0.18,0)",
+            "rgb(0.5,0.21,0)",
+            "rgb(0.54,0.24,0.01)",
+            "rgb(0.58,0.26,0.02)",
+            "rgb(0.62,0.28,0.03)",
+            "rgb(0.66,0.31,0.04)",
+            "rgb(0.7,0.34,0.06)",
+            "rgb(0.74,0.37,0.08)",
+            "rgb(0.78,0.4,0.1)",
+            "rgb(0.82,0.43,0.12)",
+            "rgb(0.86,0.46,0.14)",
+            "rgb(0.89,0.49,0.17)",
+            "rgb(0.92,0.52,0.2)",
+            "rgb(0.94,0.55,0.23)",
+            "rgb(0.96,0.58,0.26)",
+            "rgb(0.98,0.62,0.29)",
+            "rgb(1,0.66,0.32)",
+            "rgb(1,0.7,0.36)",
+            "rgb(1,0.74,0.4)",
+            "rgb(1,0.78,0.45)",
+            "rgb(1,0.82,0.5)",
+            "rgb(1,0.86,0.6)",
+            "rgb(1,0.9,0.7)",
+            "rgb(1,0.95,0.8)",
+            "rgb(1,1,0.6)"
+        ]
+    },
+    "eccharts_brown_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "brown",
+            "sh_brn_fM4t70_l16_oro",
+            "orography",
+            "Model orography from ensemble forecast"
+        ],
+        "values" : [
+            "rgb(0.38,0.14,0)",
+            "none",
+            "rgb(0.42,0.16,0)",
+            "rgb(0.5,0.21,0)",
+            "rgb(0.58,0.26,0.02)",
+            "rgb(0.66,0.31,0.04)",
+            "rgb(0.74,0.37,0.08)",
+            "rgb(0.86,0.46,0.14)",
+            "rgb(0.92,0.52,0.2)",
+            "rgb(0.94,0.55,0.23)",
+            "rgb(0.98,0.62,0.29)",
+            "rgb(1,0.7,0.36)",
+            "rgb(1,0.78,0.45)",
+            "rgb(1,0.82,0.5)",
+            "rgb(1,0.9,0.7)",
+            "rgb(1,1,0.5)"
+        ]
+    },
+    "eccharts_rainbow_magenta_grey_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "rainbow",
+            "magenta",
+            "grey",
+            "sh_cbh_f0t22000",
+            "YOPP project: Cloud base height",
+            "Cloud base height",
+            "Ceiling",
+            "cbh"
+        ],
+        "values" : [
+            "magenta",
+            "RGB(1.000,0.035,0.0000)",
+            "RGB(1.000,0.498,0.0000)",
+            "RGB(1.000,0.855,0.0000)",
+            "RGB(0.855,1.000,0.0000)",
+            "RGB(0.145,1.000,0.0000)",
+            "RGB(0.424,0.651,0.1922)",
+            "RGB(0.000,0.549,0.1882)",
+            "RGB(0.000,1.000,1.0000)",
+            "RGB(0.000,0.498,1.0000)",
+            "RGB(0.145,0.000,1.0000)",
+            "RGB(0.45,0.45,0.45)",
+            "RGB(0.70,0.70,0.70)"
+        ]
+    },
+    "eccharts_black_red_21" : {
+        "n_colours" : "21",
+        "tags" : [
+            "21",
+            "eccharts",
+            "sh_comparison_rb_m10t10"
+        ],
+        "values" : [
+            "#07090D",
+            "#1D2434",
+            "#333F5B",
+            "#425276",
+            "#6277A7",
+            "#7C8EB6",
+            "#97A4C4",
+            "#B1BBD3",
+            "#CBD2E2",
+            "#E5E8F0",
+            "None",
+            "#FFDCD6",
+            "#FFBAAD",
+            "#FF9785",
+            "#FF745C",
+            "#FF5233",
+            "#E02200",
+            "#A31800",
+            "#7A1200",
+            "#520C00",
+            "#290600"
+        ]
+    },
+    "eccharts_blue_brown_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "black",
+            "red",
+            "sh_diverging_ch4_300hpa",
+            "Methane at 300 hPa",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0940, 0.3100, 0.6350)",
+            "rgb(0.2432, 0.4236, 0.6951)",
+            "rgb(0.3924, 0.5373, 0.7552)",
+            "rgb(0.5488, 0.6564, 0.8182)",
+            "rgb(0.6980, 0.7700, 0.8783)",
+            "rgb(0.8472, 0.8836, 0.9385)",
+            "rgb(0.9983, 0.9976, 0.9968)",
+            "rgb(0.9266, 0.8975, 0.8605)",
+            "rgb(0.8550, 0.7973, 0.7243)",
+            "rgb(0.7799, 0.6924, 0.5816)",
+            "rgb(0.7083, 0.5923, 0.4454)",
+            "rgb(0.6366, 0.4921, 0.3092)",
+            "rgb(0.5650, 0.3920, 0.1730)"
+        ]
+    },
+    "eccharts_blue_brown_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "sh_diverging_ch4_500hpa",
+            "sh_diverging_co2_500hpa",
+            "Methane at 500 hPa",
+            "Carbon dioxide at 500 hPa",
+            "ch4",
+            "co2",
+            "methane",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0940, 0.3100, 0.6350)",
+            "rgb(0.2219, 0.4074, 0.6865)",
+            "rgb(0.3498, 0.5048, 0.7381)",
+            "rgb(0.4777, 0.6022, 0.7896)",
+            "rgb(0.6127, 0.7051, 0.8440)",
+            "rgb(0.7406, 0.8025, 0.8955)",
+            "rgb(0.8685, 0.8999, 0.9470)",
+            "rgb(0.9983, 0.9976, 0.9968)",
+            "rgb(0.9369, 0.9118, 0.8800)",
+            "rgb(0.8755, 0.8259, 0.7633)",
+            "rgb(0.8141, 0.7401, 0.6465)",
+            "rgb(0.7492, 0.6495, 0.5233)",
+            "rgb(0.6878, 0.5637, 0.4065)",
+            "rgb(0.6264, 0.4778, 0.2898)",
+            "rgb(0.5650, 0.3920, 0.1730)"
+        ]
+    },
+    "eccharts_blue_brown_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "sh_diverging_ch4_50hpa",
+            "Methane at 50 hPa",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0940, 0.3100, 0.6350)",
+            "rgb(0.1651, 0.3641, 0.6636)",
+            "rgb(0.2432, 0.4236, 0.6951)",
+            "rgb(0.3214, 0.4832, 0.7266)",
+            "rgb(0.3924, 0.5373, 0.7552)",
+            "rgb(0.4706, 0.5968, 0.7867)",
+            "rgb(0.5488, 0.6564, 0.8182)",
+            "rgb(0.6198, 0.7105, 0.8468)",
+            "rgb(0.6980, 0.7700, 0.8783)",
+            "rgb(0.7762, 0.8295, 0.9098)",
+            "rgb(0.8472, 0.8836, 0.9385)",
+            "rgb(0.9254, 0.9432, 0.9699)",
+            "rgb(0.9983, 0.9976, 0.9968)",
+            "rgb(0.9642, 0.9499, 0.9319)",
+            "rgb(0.9266, 0.8975, 0.8605)",
+            "rgb(0.8891, 0.8450, 0.7892)",
+            "rgb(0.8550, 0.7973, 0.7243)",
+            "rgb(0.8175, 0.7449, 0.6530)",
+            "rgb(0.7799, 0.6924, 0.5816)",
+            "rgb(0.7458, 0.6447, 0.5168)",
+            "rgb(0.7083, 0.5923, 0.4454)",
+            "rgb(0.6708, 0.5398, 0.3741)",
+            "rgb(0.6366, 0.4921, 0.3092)",
+            "rgb(0.5991, 0.4397, 0.2379)",
+            "rgb(0.5650, 0.3920, 0.1730)"
+        ]
+    },
+    "eccharts_blue_brown_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "blue",
+            "brown",
+            "sh_diverging_ch4_850hpa",
+            "sh_diverging_co2_50hpa",
+            "sh_diverging_co2_850hpa",
+            "Methane at 850 hPa",
+            "Carbon dioxide at 50 hPa",
+            "Carbon dioxide at 850 hPa",
+            "ch4",
+            "co2",
+            "methane",
+            "carbon dioxide",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.0940, 0.3100, 0.6350)",
+            "rgb(0.2574, 0.4345, 0.7008)",
+            "rgb(0.4209, 0.5589, 0.7667)",
+            "rgb(0.5843, 0.6834, 0.8325)",
+            "rgb(0.7548, 0.8133, 0.9012)",
+            "rgb(0.9183, 0.9378, 0.9671)",
+            "rgb(0.9608, 0.9452, 0.9254)",
+            "rgb(0.8823, 0.8355, 0.7762)",
+            "rgb(0.8004, 0.7210, 0.6206)",
+            "rgb(0.7219, 0.6114, 0.4714)",
+            "rgb(0.6435, 0.5017, 0.3222)",
+            "rgb(0.5650, 0.3920, 0.1730)"
+        ]
+    },
+    "eccharts_blue_brown_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "sh_diverging_co2_300hpa",
+            "Carbon dioxide at 300 hPa",
+            "co2",
+            "carbon_dioxide",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.0940, 0.3100, 0.6350)",
+            "rgb(0.2290, 0.4128, 0.6894)",
+            "rgb(0.3711, 0.5211, 0.7466)",
+            "rgb(0.5132, 0.6293, 0.8039)",
+            "rgb(0.6483, 0.7321, 0.8583)",
+            "rgb(0.7904, 0.8404, 0.9155)",
+            "rgb(0.9325, 0.9486, 0.9728)",
+            "rgb(0.9676, 0.9547, 0.9384)",
+            "rgb(0.8994, 0.8593, 0.8087)",
+            "rgb(0.8311, 0.7640, 0.6789)",
+            "rgb(0.7663, 0.6733, 0.5557)",
+            "rgb(0.6981, 0.5780, 0.4260)",
+            "rgb(0.6298, 0.4826, 0.2962)",
+            "rgb(0.5650, 0.3920, 0.1730)"
+        ]
+    },
+    "eccharts_rainbow_blue_charcoal_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "charcoal",
+            "sh_douglas_sea_scale",
+            "Significant height of total swell"
+        ],
+        "values" : [
+            "blue",
+            "greenish_blue",
+            "sky",
+            "yellowish_green",
+            "yellow",
+            "orange_yellow",
+            "orange",
+            "red",
+            "charcoal"
+        ]
+    },
+    "eccharts_blue_red_5" : {
+        "n_colours" : "5",
+        "tags" : [
+            "5",
+            "eccharts",
+            "sh_efi2t_fM1t1lst",
+            "Significant wave height extreme forecast index",
+            "2m maximum temperature extreme forecast index",
+            "2m minimum temperature extreme forecast index",
+            "EFI temperature",
+            "2m temperature extreme forecast index",
+            "EFI"
+        ],
+        "values" : [
+            "sky",
+            "rgb(0.8,0.9,0.9)",
+            "none",
+            "yellow",
+            "orange"
+        ]
+    },
+    "eccharts_blue_red_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "sh_efi2t_fM1t1lst_nc",
+            "Significant wave height extreme forecast index",
+            "EFI temperature",
+            "2m temperature extreme forecast index",
+            "EFI"            
+        ],
+        "values" : [
+            "RGB(1,0,0.87)",
+            "RGB(0,0.38,1)",
+            "RGB(0,0.81,1)",
+            "RGB(0,1,0.65)",
+            "RGB(0.65,1,0)",
+            "none",
+            "none",
+            "RGB(1,1,0)",
+            "RGB(1,0.85,0)",
+            "RGB(1,0.65,0)",
+            "RGB(1,0.40,0)",
+            "RGB(1,0,0)"
+        ]
+    },
+    "eccharts_yellow_red_5" : {
+        "n_colours" : "5",
+        "tags" : [
+            "5",
+            "eccharts",
+            "yellow",
+            "orange",
+            "red",
+            "sh_efi_f05t1_nc",
+            "CAPE extreme forecast index",
+            "CAPE shear extreme forecast index",
+            "Snowfall extreme forecast index",
+            "Total precipitation extreme forecast index",
+            "10m wind gust extreme forecast index",
+            "10m wind speed extreme forecast index",
+            "2m maximum temperature extreme forecast index",
+            "2m minimum temperature extreme forecast index",          
+            "EFI wind",
+            "EFI precipitation",
+            "EFI"
+        ],
+        "values" : [
+            "RGB(1,1,0)",
+            "RGB(1,0.85,0)",
+            "RGB(1,0.65,0)",
+            "RGB(1,0.40,0)",
+            "RGB(1,0,0)"
+        ]
+    },
+    "eccharts_green_brown_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "sh_f50t6000_oro",
+            "green",
+            "brown",
+            "orography",
+            "Model orography from HRES forecast"
+        ],
+        "values" : [
+            "rgb(0.15,0.5,0.4)",
+            "none",
+            "rgb(0.16,0.4,0)",
+            "rgb(0.2,0.5,0)",
+            "rgb(0.3,0.6,0)",
+            "rgb(0.4,0.7,0)",
+            "rgb(0.5,0.8,0)",
+            "rgb(0.7,0.9,0)",
+            "rgb(0.9,1,0)",
+            "rgb(0.9,0.8,0)",
+            "rgb(0.8,0.6,0)",
+            "rgb(0.7,0.45,0)",
+            "rgb(0.6,0.3,0)",
+            "rgb(0.45,0.2,0)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(1,1,0.5)"
+        ]
+    },
+    "eccharts_green_brown2_28" : {
+        "n_colours" : "28",
+        "tags" : [
+            "28",
+            "eccharts",
+            "green",
+            "brown",
+            "orography",
+            "sh_fM09t60_l25_oro",
+            "Model orography  from HRES forecast"
+        ],
+        "values" : [
+            "rgb(0.15,0.5,0.4)",
+            "none",
+            "rgb(0.16,0.4,0)",
+            "rgb(0.18,0.45,0)",
+            "rgb(0.2,0.5,0)",
+            "rgb(0.25,0.55,0)",
+            "rgb(0.3,0.6,0)",
+            "rgb(0.35,0.65,0)",
+            "rgb(0.4,0.7,0)",
+            "rgb(0.45,0.75,0)",
+            "rgb(0.5,0.8,0)",
+            "rgb(0.57,0.83,0)",
+            "rgb(0.64,0.86,0)",
+            "rgb(0.7,0.9,0)",
+            "rgb(0.8,0.95,0)",
+            "rgb(0.9,1,0)",
+            "rgb(0.9,0.8,0)",
+            "rgb(0.85,0.7,0)",
+            "rgb(0.8,0.6,0)",
+            "rgb(0.75,0.52,0)",
+            "rgb(0.7,0.45,0)",
+            "rgb(0.65,0.37,0)",
+            "rgb(0.6,0.3,0)",
+            "rgb(0.45,0.2,0)",
+            "rgb(0.45,0.3,0.1)",
+            "rgb(0.5,0.4,0.3)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(0.5,1,0.5)"
+        ]
+    },
+    "eccharts_green_brown_29" : {
+        "n_colours" : "29",
+        "tags" : [
+            "29",
+            "eccharts",
+            "green",
+            "brown",
+            "orography",
+            "sh_fM09t60_l25_oro_grid"
+        ],
+        "values" : [
+            "rgb(0.125,0.69,0.66)",
+            "none",
+            "none",
+            "rgb(0.16,0.4,0)",
+            "rgb(0.18,0.45,0)",
+            "rgb(0.2,0.5,0)",
+            "rgb(0.25,0.55,0)",
+            "rgb(0.3,0.6,0)",
+            "rgb(0.35,0.65,0)",
+            "rgb(0.4,0.7,0)",
+            "rgb(0.45,0.75,0)",
+            "rgb(0.5,0.8,0)",
+            "rgb(0.57,0.83,0)",
+            "rgb(0.64,0.86,0)",
+            "rgb(0.7,0.9,0)",
+            "rgb(0.8,0.95,0)",
+            "rgb(0.9,1,0)",
+            "rgb(0.9,0.8,0)",
+            "rgb(0.85,0.7,0)",
+            "rgb(0.8,0.6,0)",
+            "rgb(0.75,0.52,0)",
+            "rgb(0.7,0.45,0)",
+            "rgb(0.65,0.37,0)",
+            "rgb(0.6,0.3,0)",
+            "rgb(0.45,0.2,0)",
+            "rgb(0.45,0.3,0.1)",
+            "rgb(0.5,0.4,0.3)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(1,1,0.5)"
+        ]
+    },
+    "eccharts_green_red_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "green",
+            "red",
+            "eccharts",
+            "sh_green_f15t60",
+            "K-index"
+        ],
+        "values" : [
+            "RGB(0.039,0.59,0.039)",
+            "RGB(0.66,0.81,0.12)",
+            "RGB(0.92,0.94,0.025)",
+            "RGB(0.94,0.62,0.025)",
+            "RGB(0.94,0.25,0.025)",
+            "RGB(0.67,0.06,0.1)"
+        ]
+    },
+    "eccharts_grey_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "eccharts",
+            "grey",
+            "sh_grey_f0t90000",
+            "Visibility"
+        ],
+        "values" : [
+            "white",
+            "rgb(0.9,0.9,0.9)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(0.3,0.3,0.3)",
+            "rgb(0.2,0.2,0.2)",
+            "black"
+        ]
+    },
+    "eccharts_green_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "green",
+            "sh_grn_f0t18i1_5",
+            "Mean period of total swell",
+            "swell"
+        ],
+        "values" : [
+            "rgb(0.8,1.0,0.85)",
+            "rgb(0.7,0.97,0.8)",
+            "rgb(0.65,0.95,0.75)",
+            "rgb(0.6,0.9,0.7)",
+            "rgb(0.5,0.85,0.65)",
+            "rgb(0.4,0.8,0.55)",
+            "rgb(0.25,0.75,0.5)",
+            "rgb(0.15,0.65,0.4)",
+            "rgb(0,0.55,0.3)",
+            "rgb(0,0.45,0.2)",
+            "rgb(0,0.35,0)"
+        ]
+    },
+    "eccharts_yellow_blue_dark_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "eccharts",
+            "yellow",
+            "blue",
+            "sh_grn_f10t100lst",
+            "10 m wind gust",
+            "wind gust",
+            "10 m wind speed",
+            "wind speed",
+            "10m wind gusts percentile"
+        ],
+        "values" : [
+            "rgb(1,1,0.40)",
+            "greenish_yellow",
+            "rgb(0.58,1,0.0)",
+            "avocado",
+            "evergreen",
+            "rgb(0.0,0.33,0.28)",
+            "rgb(0.0,0.26,0.28)",
+            "rgb(0.0,0.20,0.44)",
+            "rgb(0.0,0.20,0.64)"
+        ]
+    },
+    "eccharts_green_blue_light_3" : {
+        "n_colours" : "3",
+        "tags" : [
+            "3",
+            "eccharts",
+            "green",
+            "blue",
+            "sh_grnblu_f65t100i15_light",
+            "250 hPa relative humidity",
+            "500 hPa relative humidity",
+            "600 hPa relative humidity",
+            "700 hPa relative humidity",
+            "800 hPa relative humidity",
+            "850 hPa relative humidity",
+            "925 hPa relative humidity",
+            "1000 hPa relative humidity"
+        ],
+        "values" : [
+            "rgb(0.8,1,0.8)",
+            "rgb(0.7,0.95,0.9)",
+            "rgb(0.6,0.75,1)"
+        ]
+    },
+    "eccharts_greengrey_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "greengrey",
+            "sh_grngry_f0t1lst",
+            "Medium cloud cover",
+            "mcc"
+        ],
+        "values" : [
+            "rgb(0.95,0.98,0.95)",
+            "rgb(0.9,0.94,0.9)",
+            "rgb(0.85,0.9,0.85)",
+            "rgb(0.8,0.86,0.8)",
+            "rgb(0.76,0.83,0.76)",
+            "rgb(0.72,0.8,0.72)",
+            "rgb(0.68,0.77,0.68)",
+            "rgb(0.64,0.74,0.64)"
+        ]
+    },
+    "eccharts_green_violet_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "green",
+            "violet",
+            "sh_grnvio_f1t100lst",
+            "Stratiform precipitation",
+            "Stratiform precipitation percentile",
+            "Total precipitation",
+            "tp",
+            "Total precipitation ensemble members from UERRA dataset",
+            "Total precipitation percentile",
+            "Total snowfall",
+            "YOPP project: Total precipitation",
+            "YOPP project: Total snowfall",
+            "Convective precipitation",
+            "Convective precipitation percentile"
+        ],
+        "values" : [
+            "rgb(0.5,1,0.7)",
+            "rgb(0.4,0.9,0.6)",
+            "rgb(0.3,0.83,0.6)",
+            "rgb(0.43,0.76,0.7)",
+            "rgb(0.56,0.69,0.8)",
+            "rgb(0.7,0.62,0.9)"
+        ]
+    },
+    "eccharts_grey2_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "grey",
+            "sh_gry_f0t1lst",
+            "Low cloud cover",
+            "lcc"
+        ],
+        "values" : [
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.68,0.68,0.68)",
+            "rgb(0.66,0.66,0.66)",
+            "rgb(0.64,0.64,0.64)",
+            "rgb(0.62,0.62,0.62)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.58,0.58,0.58)",
+            "rgb(0.56,0.56,0.56)"
+        ]
+    },
+    "eccharts_white_grey_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "white",
+            "grey",
+            "eccharts",
+            "300 hPa potential vorticity",
+            "500 hPa potential vorticity",
+            "315K (potential temperature level) potential vorticity",
+            "sh_gry_f0t20lst"
+        ],
+        "values" : [
+            "rgb(0.89,0.89,0.89)",
+            "rgb(0.93,0.93,0.93)",
+            "rgb(0.96,0.96,0.96)",
+            "none",
+            "rgb(0.73,0.73,0.73)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.52,0.52,0.52)",
+            "rgb(0.44,0.44,0.44)",
+            "rgb(0.37,0.37,0.37)",
+            "rgb(0.3,0.3,0.3)"
+        ]
+    },
+    "eccharts_rainbow_green_red_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "rainbow",
+            "grey",
+            "red",
+            "sh_hcct_f0t22000",
+            "Height of convective cloud top",
+            "hcct",
+            "convective cloud top"
+        ],
+        "values" : [
+            "RGB(0.70,0.70,0.70)",
+            "RGB(0.45,0.45,0.45)",
+            "RGB(0.145,0.000,1.0000)",
+            "RGB(0.000,0.498,1.0000)",
+            "RGB(0.000,1.000,1.0000)",
+            "RGB(0.000,0.549,0.1882)",
+            "RGB(0.145,1.000,0.0000)",
+            "RGB(0.855,1.000,0.0000)",
+            "RGB(1.000,0.855,0.0000)",
+            "RGB(1.000,0.690,0.0000)",
+            "RGB(1.000,0.498,0.0000)",
+            "RGB(1.000,0.035,0.0000)"
+        ]
+    },
+    "eccharts_rainbow_purple_pink_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "rainbow",
+            "purple",
+            "pink",
+            "sh_height_fM100t10000",
+            "Height of zero-degree/one-degree wet-bulb temperature"
+        ],
+        "values" : [
+            "RGB(0.79,0.81,0.94)",
+            "RGB(0.45,0.55,0.96)",
+            "RGB(0.13,0.42,0.99)",
+            "RGB(0.042,0.73,0.94)",
+            "RGB(0.19,0.94,0.98)",
+            "RGB(0.17,0.79,0.59)",
+            "RGB(0.13,0.89,0.086)",
+            "RGB(0.6,0.99,0.0059)",
+            "RGB(0.92,0.95,0.19)",
+            "RGB(1,0.71,0.02)",
+            "RGB(0.98,0.53,0.16)",
+            "RGB(0.98,0.3,0.07)",
+            "RGB(0.89,0.092,0.42)",
+            "RGB(0.97,0.43,0.84)"
+        ]
+    },
+    "eccharts_green_black_11" : {  
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "sh_lai_f0t7",
+            "Leaf area index"
+        ],
+        "values" : [
+            "RGB(1.0,0.92,0.84)",
+            "RGB(0.9,0.9,0.8)",
+            "RGB(0.78,0.85,0.74)",
+            "RGB(0.55,0.8,0.5)",
+            "RGB(0.0,1.0,0.0)",
+            "RGB(0.10,0.82,0.10)",
+            "RGB(0.11,0.65,0.11)",
+            "RGB(0.10,0.50,0.30)",
+            "RGB(0.07,0.35,0.21)",
+            "RGB(0.0,0.20,0.10)",
+            "black"
+        ]
+    },
+    "eccharts_light_grey_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "sh_lgtgry_f0t1lst",
+            "Medium cloud cover",
+            "mcc"
+        ],
+        "values" : [
+            "rgb(0.86,0.86,0.86)",
+            "rgb(0.84,0.84,0.84)",
+            "rgb(0.82,0.82,0.82)",
+            "rgb(0.8,0.8,0.8)",
+            "rgb(0.78,0.78,0.78)",
+            "rgb(0.76,0.76,0.76)",
+            "rgb(0.74,0.74,0.74)",
+            "rgb(0.72,0.72,0.72)"
+        ]
+    },
+    "eccharts_rainbow_purple_pink_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "rainbow",
+            "purple",
+            "pink",
+            "sh_mag_f0t10000",
+            "Height of zero degree level"
+        ],
+        "values" : [
+            "none",
+            "RGB(0.92,0.92,1.0)",
+            "RGB(0.8,0.8,1.0)",
+            "RGB(0.68,0.68,1.0)",
+            "RGB(0.56,0.56,1.0)",
+            "RGB(0.45,0.45,1.0)",
+            "RGB(0.4,1.0,1.0)",
+            "RGB(0.0,0.8,0.8)",
+            "RGB(0.6,1.0,0.6)",
+            "RGB(0.2,0.95,0.2)",
+            "RGB(1.0,0.85,0.5)",
+            "RGB(1.0,0.7,0.1)",
+            "RGB(1.0,0.5,0.5)",
+            "RGB(1.0,0.5,1.0)",
+            "magenta"
+        ]
+    },
+    "eccharts_rainbow_blue_grey_18" : {
+        "n_colours" : "18",
+        "tags" : [
+            "18",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "grey",
+            "sh_mc_cape_f10t13000",
+            "24h 4-value-maximum CAPE from M-Climate at various percentiles",
+            "maximum cape",
+            "cape"
+        ],
+        "values" : [
+            "RGB(0.0098,0.45,0.99)",
+            "RGB(0.0098,0.73,0.99)",
+            "RGB(0.0098,0.99,0.95)",
+            "RGB(0.0098,0.99,0.55)",
+            "RGB(0.0098,0.99,0.21)",
+            "RGB(0.77,0.99,0.0098)",
+            "RGB(0.92,0.99,0.0098)",
+            "RGB(0.99,0.82,0.0098)",
+            "RGB(0.99,0.58,0.0098)",
+            "RGB(0.98,0.28,0.066)",
+            "RGB(0.99,0.075,0.0098)",
+            "RGB(0.79,0.12,0.069)",
+            "RGB(0.7,0.038,0.49)",
+            "magenta",
+            "RGB(0.95,0.55,0.9)",
+            "RGB(0.5,0.35,0.6)",
+            "grey",
+            "RGB(0.3,0.3,0.3)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_14" : {
+        "n_colours" : "14",
+        "tags" : [
+            "14",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "purple",            
+            "sh_mc_capes_f10t4000",
+            "24h 4-value-maximum CAPESHEAR from M-Climate at various percentiles",
+            "24h 4-value-maximum CAPE from M-Climate at various percentiles",
+            "capeshear M-Climate",
+            "cape M-Climate",
+            "maximum cape",
+            "capeshear",
+            "cape"            
+        ],
+        "values" : [
+            "RGB(0.75,0.75,0.95)",
+            "RGB(0.5,0.5,0.95)",
+            "RGB(0.01,0.45,0.99)",
+            "RGB(0.0098,0.73,0.99)",
+            "RGB(0.01,0.99,0.95)",
+            "RGB(0.02,0.70,0.65)",
+            "RGB(0.,0.5,0.1)",
+            "RGB(0.0098,0.99,0.21)",
+            "RGB(0.77,0.99,0.01)",
+            "RGB(0.99,0.58,0.0098)",
+            "RGB(0.99,0.075,0.0098)",
+            "RGB(0.7,0.038,0.49)",
+            "RGB(1,0,1)",
+            "RGB(0.5,0.01,0.99)"
+        ]
+    },
+    "eccharts_blue_purple_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "blue",
+            "purple",            
+            "sh_mc_sf_f01t100",
+            "24h total snowfall from M-Climate at various percentiles",
+            "snowfall Mclimate"
+        ],
+        "values" : [
+            "RGB(0.82,0.95,0.95)",
+            "RGB(0.51,0.96,0.95)",
+            "RGB(0.09,0.82,0.8)",
+            "RGB(0.42,1,0.52)",
+            "RGB(0.16,0.67,0.23)",
+            "RGB(0.14,0.41,0.4)",
+            "RGB(0.26,0.47,1)",
+            "RGB(0.11,0.05,0.73)",
+            "RGB(0.63,0.33,0.87)",
+            "RGB(0.85,0,1)",
+            "RGB(0.47,0.01,0.55)"
+        ]
+    },
+    "eccharts_green_purple_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "green",
+            "purple",            
+            "sh_mc_swh_f0t20",
+            "24h maximum sig wave height from M-Climate at various percentiles",
+            "sig wave height M-Climate",
+            "M-climate"
+        ],
+        "values" : [
+            "RGB(0.82,0.95,0.95)",
+            "RGB(0.51,0.96,0.95)",
+            "RGB(0.09,0.82,0.8)",
+            "RGB(0.18,0.65,0.64)",
+            "RGB(0.2,0.52,0.52)",
+            "RGB(0.14,0.41,0.4)",
+            "RGB(0.05,0.44,0.73)",
+            "RGB(0.05,0.33,0.73)",
+            "RGB(0.11,0.05,0.73)",
+            "RGB(0.85,0,1)",
+            "RGB(0.47,0.01,0.55)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "rainbow",
+            "red",
+            "purple",            
+            "sh_mc_t_fM80t60",
+            "24h 5-value-mean temperature from M-Climate at various quantiles",
+            "24h maximum 2m temperature from M-Climate at various percentiles",
+            "24h minimum 2m temperature from M-Climate at various percentiles",
+            "temperature M-climate",
+            "M-climate"
+        ],
+        "values" : [
+            "RGB(0.51,0,0.76)",
+            "RGB(0.93,0,0.98)",
+            "RGB(1,0.49,0.96)",
+            "RGB(0.83,0.48,1)",
+            "RGB(0.03,0.03,0.84)",
+            "RGB(0,0.48,1)",
+            "RGB(0,0.65,1)",
+            "RGB(0,0.82,1)",
+            "RGB(0,0.97,1)",
+            "RGB(0.79,0.99,1)",
+            "RGB(0,0.51,0.2)",
+            "RGB(0.22,0.86,0.47)",
+            "RGB(0,1,0.24)",
+            "RGB(0.63,1,0)",
+            "RGB(0.98,1,0)",
+            "RGB(1,0.84,0)",
+            "RGB(1,0.63,0)",
+            "RGB(1,0.42,0)",
+            "RGB(1,0.15,0)",
+            "RGB(0.78,0.01,0.05)"
+        ]
+    },
+    "eccharts_rainbow_orange_red_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "eccharts",
+            "rainbow",
+            "red",
+            "orange",               
+            "sh_mc_tp_f01t1000",
+            "24h total precipitation from M-Climate at various percentiles"
+        ],
+        "values" : [
+            "RGB(1,0.63,0)",
+            "RGB(1,0.88,0)",
+            "RGB(1,1,0)",
+            "RGB(0.77,1,0)",
+            "RGB(0.35,1,0)",
+            "RGB(0.24,0.64,0.02)",
+            "RGB(0,1,0.7)",
+            "RGB(0,1,1)",
+            "RGB(0,0.78,0.78)",
+            "RGB(0.03,0.5,0.5)",
+            "RGB(0,0.6,1)",
+            "RGB(0,0,1)",
+            "RGB(0.04,0.01,0.74)",
+            "RGB(0.98,0.6,0.95)",
+            "RGB(1,0,0.98)",
+            "RGB(0.75,0,0.74)",
+            "RGB(0.43,0,0.42)",
+            "RGB(1,0,0)",
+            "RGB(0.62,0.05,0.02)"
+        ]
+    },
+    "eccharts_rainbow_blue_purple_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "rainbow",
+            "blue",
+            "purple",
+            "sh_mc_wind_f0t80",
+            "24h 4-value-mean 10m wind speed from M-Climate at various percentiles"
+        ],
+        "values" : [
+            "RGB(0.85,0.99,0.93)",
+            "RGB(0.45,0.98,0.96)",
+            "RGB(0,0.73,1)",
+            "RGB(0,0.18,1)",
+            "RGB(0.03,0.01,0.64)",
+            "RGB(0.16,0.99,0.14)",
+            "RGB(0.57,1,0)",
+            "RGB(0.83,1,0)",
+            "RGB(1,0.98,0)",
+            "RGB(1,0.85,0)",
+            "RGB(1,0.63,0)",
+            "RGB(1,0.4,0)",
+            "RGB(1,0.12,0)",
+            "RGB(1,0,0.67)",
+            "RGB(0.85,0,1)",
+            "RGB(0.47,0.01,0.55)"
+        ]
+    },
+    "eccharts_blue_red3_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "eccharts",
+            "blue",
+            "red",   
+            "anomaly",
+            "temperature",
+            "monthly forecast",
+            "sh_mf_2t_prob",
+            "sh_mf_tp_prob",
+            "sh_mf_2t_tercile",
+            "sh_mf_tp_tercile",
+            "sh_mf_pdist_decile",
+            "sh_mf_pdist_quintile",
+            "Extended range: MSLP probability dist. at various quantiles",
+            "Extended range: precipitation probability dist. at various quantiles",
+            "Extended range: surface temperature probability dist. at various quantiles",
+            "Extended range: 2t probability dist. at various quantiles",
+            "mslp probability distribution",
+            "precipitation probability distribution",
+            "2m tempearature probability distribution",
+            "surface tempearature probability distribution"
+        ],
+        "values" : [
+            "HSL(220,1,0.5)",
+            "HSL(220,1,0.7)",
+            "WHITE",
+            "HSL(1,1,0.9)",
+            "HSL(1,1,0.7)",
+            "HSL(1,1,0.5)",
+            "HSL(1,1,0.3)"
+        ]
+    },
+    "eccharts_rainbow_purple_red2_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "rainbow",
+            "red",
+            "purple",            
+            "sh_mf_pdist",
+            "sh_mofc_pdist",
+            "2m tempearature probability distribution",
+            "Extended range: 2t probability dist. at various quantiles"
+        ],
+        "values" : [
+            "RGB(0.47,0.018,0.77)",
+            "RGB(0.42,0.33,0.83)",
+            "RGB(0.14,0.26,0.94)",
+            "RGB(0.0085,0.51,0.86)",
+            "RGB(0.022,0.68,0.72)",
+            "RGB(0.01,0.82,0.85)",
+            "RGB(0.46,0.95,0.75)",
+            "RGB(0.15,0.87,0.58)",
+            "RGB(0.59,0.89,0.048)",
+            "RGB(0.88,0.95,0.17)",
+            "RGB(0.99,0.72,0.025)",
+            "RGB(0.92,0.49,0.13)",
+            "RGB(0.9,0.19,0.19)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "rainbow",
+            "red",
+            "purple",
+            "sh_mf_pdist_2",
+            "sh_mofc_pdist_2",
+            "Extended range: MSLP probability dist. at various quantiles",
+            "mslp probability distribution"
+        ],
+        "values" : [
+            "RGB(0.47,0.018,0.77)",
+            "RGB(0.14,0.26,0.94)",
+            "RGB(0.022,0.68,0.72)",
+            "RGB(0.15,0.87,0.58)",
+            "RGB(0.41,0.98,0.0038)",
+            "RGB(0.92,0.95,0.13)",
+            "RGB(0.99,0.72,0.025)",
+            "RGB(0.9,0.19,0.19)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",
+            "sh_nipy_spectral_ch4_300hpa",
+            "sh_spectral_ch4_300hpa",
+            "Methane at 300 hPa",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.5098, 0.0000, 0.5765)",
+            "rgb(0.0000, 0.0000, 0.7255)",
+            "rgb(0.0000, 0.4693, 0.8667)",
+            "rgb(0.0000, 0.6445, 0.7334)",
+            "rgb(0.0000, 0.6458, 0.3660)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.9582, 0.0000)",
+            "rgb(0.8000, 0.9778, 0.0000)",
+            "rgb(1.0000, 0.7882, 0.0000)",
+            "rgb(1.0000, 0.1765, 0.0000)",
+            "rgb(0.8432, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_25" : {
+        "n_colours" : "25",
+        "tags" : [
+            "25",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",            
+            "sh_nipy_spectral_ch4_500hpa",
+            "sh_nipy_spectral_ch4_50hpa",
+            "sh_spectral_ch4_50hpa",
+            "Methane at 500 hPa",
+            "Methane at 50 hPa",
+            "ch4",
+            "methane",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.3768, 0.0108, 0.4291)",
+            "rgb(0.5098, 0.0000, 0.5765)",
+            "rgb(0.2614, 0.0000, 0.6340)",
+            "rgb(0.0000, 0.0000, 0.7255)",
+            "rgb(0.0000, 0.0732, 0.8667)",
+            "rgb(0.0000, 0.4693, 0.8667)",
+            "rgb(0.0000, 0.5739, 0.8667)",
+            "rgb(0.0000, 0.6445, 0.7334)",
+            "rgb(0.0000, 0.6667, 0.5961)",
+            "rgb(0.0000, 0.6458, 0.3660)",
+            "rgb(0.0000, 0.6235, 0.0000)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.8432, 0.0000)",
+            "rgb(0.0000, 0.9582, 0.0000)",
+            "rgb(0.4026, 1.0000, 0.0000)",
+            "rgb(0.8000, 0.9778, 0.0000)",
+            "rgb(0.9464, 0.9072, 0.0000)",
+            "rgb(1.0000, 0.7882, 0.0000)",
+            "rgb(1.0000, 0.6314, 0.0000)",
+            "rgb(1.0000, 0.1765, 0.0000)",
+            "rgb(0.9242, 0.0000, 0.0000)",
+            "rgb(0.8432, 0.0000, 0.0000)",
+            "rgb(0.7137, 0.0000, 0.0259)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_20" : {
+        "n_colours" : "20",
+        "tags" : [
+            "20",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",             
+            "sh_nipy_spectral_ch4_850hpa",
+            "sh_nipy_spectral_co2_500hpa",
+            "sh_nipy_spectral_co2_totalcolumn",
+            "Carbon dioxide at 500 hPa",
+            "Total column of carbon dioxide",
+            "co2",
+            "carbon dioxide",
+            "Methane at 850 hPa",
+            "ch4",
+            "methane",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.4680, 0.0000, 0.5346)",
+            "rgb(0.5124, 0.0000, 0.6026)",
+            "rgb(0.0000, 0.0000, 0.6942)",
+            "rgb(0.0000, 0.0732, 0.8667)",
+            "rgb(0.0000, 0.5007, 0.8667)",
+            "rgb(0.0000, 0.6183, 0.8118)",
+            "rgb(0.0000, 0.6667, 0.6170)",
+            "rgb(0.0000, 0.6405, 0.3242)",
+            "rgb(0.0000, 0.6653, 0.0000)",
+            "rgb(0.0000, 0.8013, 0.0000)",
+            "rgb(0.0000, 0.9477, 0.0000)",
+            "rgb(0.4601, 1.0000, 0.0000)",
+            "rgb(0.8784, 0.9516, 0.0000)",
+            "rgb(0.9830, 0.8340, 0.0000)",
+            "rgb(1.0000, 0.6314, 0.0000)",
+            "rgb(1.0000, 0.0824, 0.0000)",
+            "rgb(0.8719, 0.0000, 0.0000)",
+            "rgb(0.8013, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_23" : {
+        "n_colours" : "23",
+        "tags" : [
+            "23",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",             
+            "sh_nipy_spectral_ch4_surface",
+            "Methane at surface",
+            "ch4",
+            "methane",
+            "cams"              
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.4095, 0.0069, 0.4670)",
+            "rgb(0.5202, 0.0000, 0.5869)",
+            "rgb(0.1778, 0.0000, 0.6445)",
+            "rgb(0.0000, 0.0000, 0.7883)",
+            "rgb(0.0000, 0.2562, 0.8667)",
+            "rgb(0.0000, 0.5216, 0.8667)",
+            "rgb(0.0000, 0.6235, 0.7961)",
+            "rgb(0.0000, 0.6667, 0.6275)",
+            "rgb(0.0000, 0.6562, 0.4496)",
+            "rgb(0.0000, 0.6131, 0.0000)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.8536, 0.0000)",
+            "rgb(0.0000, 0.9791, 0.0000)",
+            "rgb(0.5176, 1.0000, 0.0000)",
+            "rgb(0.8627, 0.9568, 0.0000)",
+            "rgb(0.9725, 0.8549, 0.0000)",
+            "rgb(1.0000, 0.7098, 0.0000)",
+            "rgb(1.0000, 0.3647, 0.0000)",
+            "rgb(0.9556, 0.0000, 0.0000)",
+            "rgb(0.8536, 0.0000, 0.0000)",
+            "rgb(0.7451, 0.0000, 0.0165)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_16" : {
+        "n_colours" : "16",
+        "tags" : [
+            "16",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",             
+            "sh_nipy_spectral_ch4_totalcolumn",
+            "Total column of methane",
+            "ch4",
+            "methane",
+            "cams"             
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.4889, 0.0000, 0.5555)",
+            "rgb(0.1778, 0.0000, 0.6445)",
+            "rgb(0.0000, 0.0000, 0.8667)",
+            "rgb(0.0000, 0.5111, 0.8667)",
+            "rgb(0.0000, 0.6445, 0.7334)",
+            "rgb(0.0000, 0.6667, 0.5333)",
+            "rgb(0.0000, 0.6444, 0.0000)",
+            "rgb(0.0000, 0.8222, 0.0000)",
+            "rgb(0.0000, 1.0000, 0.0000)",
+            "rgb(0.8000, 0.9778, 0.0000)",
+            "rgb(0.9778, 0.8444, 0.0000)",
+            "rgb(1.0000, 0.6000, 0.0000)",
+            "rgb(0.9556, 0.0000, 0.0000)",
+            "rgb(0.8222, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_17" : {
+        "n_colours" : "17",
+        "tags" : [
+            "17",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",
+            "sh_nipy_spectral_co2_300hpa",
+            "Carbon dioxide at 300 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"  
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.4837, 0.0000, 0.5503)",
+            "rgb(0.2614, 0.0000, 0.6340)",
+            "rgb(0.0000, 0.0000, 0.8196)",
+            "rgb(0.0000, 0.4693, 0.8667)",
+            "rgb(0.0000, 0.6183, 0.8118)",
+            "rgb(0.0000, 0.6667, 0.5961)",
+            "rgb(0.0000, 0.6144, 0.1150)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.9059, 0.0000)",
+            "rgb(0.4026, 1.0000, 0.0000)",
+            "rgb(0.8941, 0.9464, 0.0000)",
+            "rgb(1.0000, 0.7882, 0.0000)",
+            "rgb(1.0000, 0.4118, 0.0000)",
+            "rgb(0.9242, 0.0000, 0.0000)",
+            "rgb(0.8118, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_30" : {
+        "n_colours" : "30",
+        "tags" : [
+            "30",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",            
+            "sh_nipy_spectral_co2_50hpa",
+            "Carbon dioxide at 50 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"              
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.3115, 0.0186, 0.3532)",
+            "rgb(0.4889, 0.0000, 0.5555)",
+            "rgb(0.5124, 0.0000, 0.6026)",
+            "rgb(0.1359, 0.0000, 0.6497)",
+            "rgb(0.0000, 0.0000, 0.7569)",
+            "rgb(0.0000, 0.0366, 0.8667)",
+            "rgb(0.0000, 0.3660, 0.8667)",
+            "rgb(0.0000, 0.5320, 0.8667)",
+            "rgb(0.0000, 0.6131, 0.8275)",
+            "rgb(0.0000, 0.6602, 0.6863)",
+            "rgb(0.0000, 0.6667, 0.5856)",
+            "rgb(0.0000, 0.6510, 0.4078)",
+            "rgb(0.0000, 0.6039, 0.0314)",
+            "rgb(0.0000, 0.6863, 0.0000)",
+            "rgb(0.0000, 0.7804, 0.0000)",
+            "rgb(0.0000, 0.8745, 0.0000)",
+            "rgb(0.0000, 0.9686, 0.0000)",
+            "rgb(0.2876, 1.0000, 0.0000)",
+            "rgb(0.7529, 0.9935, 0.0000)",
+            "rgb(0.8941, 0.9464, 0.0000)",
+            "rgb(0.9673, 0.8653, 0.0000)",
+            "rgb(1.0000, 0.7569, 0.0000)",
+            "rgb(1.0000, 0.6157, 0.0000)",
+            "rgb(1.0000, 0.2706, 0.0000)",
+            "rgb(0.9660, 0.0000, 0.0000)",
+            "rgb(0.8719, 0.0000, 0.0000)",
+            "rgb(0.8222, 0.0000, 0.0000)",
+            "rgb(0.6510, 0.0000, 0.0447)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_32" : {
+        "n_colours" : "32",
+        "tags" : [
+            "32",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",            
+            "sh_nipy_spectral_co2_850hpa",
+            "sh_spectral_co2_300hpa",
+            "Carbon dioxide at 850 hPa",
+            "Carbon dioxide at 300 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.3115, 0.0186, 0.3532)",
+            "rgb(0.4837, 0.0000, 0.5503)",
+            "rgb(0.5255, 0.0000, 0.5922)",
+            "rgb(0.2196, 0.0000, 0.6392)",
+            "rgb(0.0000, 0.0000, 0.7098)",
+            "rgb(0.0000, 0.0000, 0.8353)",
+            "rgb(0.0000, 0.2196, 0.8667)",
+            "rgb(0.0000, 0.4902, 0.8667)",
+            "rgb(0.0000, 0.5739, 0.8667)",
+            "rgb(0.0000, 0.6288, 0.7804)",
+            "rgb(0.0000, 0.6667, 0.6589)",
+            "rgb(0.0000, 0.6667, 0.5647)",
+            "rgb(0.0000, 0.6405, 0.3242)",
+            "rgb(0.0000, 0.6026, 0.0000)",
+            "rgb(0.0000, 0.6863, 0.0000)",
+            "rgb(0.0000, 0.7804, 0.0000)",
+            "rgb(0.0000, 0.8641, 0.0000)",
+            "rgb(0.0000, 0.9477, 0.0000)",
+            "rgb(0.1725, 1.0000, 0.0000)",
+            "rgb(0.6902, 1.0000, 0.0000)",
+            "rgb(0.8470, 0.9621, 0.0000)",
+            "rgb(0.9464, 0.9072, 0.0000)",
+            "rgb(0.9882, 0.8235, 0.0000)",
+            "rgb(1.0000, 0.6941, 0.0000)",
+            "rgb(1.0000, 0.5059, 0.0000)",
+            "rgb(1.0000, 0.1294, 0.0000)",
+            "rgb(0.9451, 0.0000, 0.0000)",
+            "rgb(0.8589, 0.0000, 0.0000)",
+            "rgb(0.8170, 0.0000, 0.0000)",
+            "rgb(0.6510, 0.0000, 0.0447)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_73" : {
+        "n_colours" : "73",
+        "tags" : [
+            "73",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",            
+            "sh_nipy_spectral_co2_surface",
+            "Carbon dioxide at surface",
+            "co2",
+            "carbon dioxide",
+            "cams"
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.1480, 0.0382, 0.1637)",
+            "rgb(0.2788, 0.0225, 0.3153)",
+            "rgb(0.3768, 0.0108, 0.4291)",
+            "rgb(0.4732, 0.0000, 0.5398)",
+            "rgb(0.4889, 0.0000, 0.5555)",
+            "rgb(0.5098, 0.0000, 0.5765)",
+            "rgb(0.5255, 0.0000, 0.5922)",
+            "rgb(0.4287, 0.0000, 0.6131)",
+            "rgb(0.2614, 0.0000, 0.6340)",
+            "rgb(0.1359, 0.0000, 0.6497)",
+            "rgb(0.0000, 0.0000, 0.6785)",
+            "rgb(0.0000, 0.0000, 0.7255)",
+            "rgb(0.0000, 0.0000, 0.7883)",
+            "rgb(0.0000, 0.0000, 0.8353)",
+            "rgb(0.0000, 0.0732, 0.8667)",
+            "rgb(0.0000, 0.1830, 0.8667)",
+            "rgb(0.0000, 0.3294, 0.8667)",
+            "rgb(0.0000, 0.4693, 0.8667)",
+            "rgb(0.0000, 0.5007, 0.8667)",
+            "rgb(0.0000, 0.5425, 0.8667)",
+            "rgb(0.0000, 0.5739, 0.8667)",
+            "rgb(0.0000, 0.6078, 0.8432)",
+            "rgb(0.0000, 0.6235, 0.7961)",
+            "rgb(0.0000, 0.6445, 0.7334)",
+            "rgb(0.0000, 0.6602, 0.6863)",
+            "rgb(0.0000, 0.6667, 0.6379)",
+            "rgb(0.0000, 0.6667, 0.5961)",
+            "rgb(0.0000, 0.6667, 0.5647)",
+            "rgb(0.0000, 0.6615, 0.4915)",
+            "rgb(0.0000, 0.6458, 0.3660)",
+            "rgb(0.0000, 0.6248, 0.1987)",
+            "rgb(0.0000, 0.6092, 0.0732)",
+            "rgb(0.0000, 0.6235, 0.0000)",
+            "rgb(0.0000, 0.6549, 0.0000)",
+            "rgb(0.0000, 0.6967, 0.0000)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.7699, 0.0000)",
+            "rgb(0.0000, 0.8118, 0.0000)",
+            "rgb(0.0000, 0.8432, 0.0000)",
+            "rgb(0.0000, 0.8850, 0.0000)",
+            "rgb(0.0000, 0.9164, 0.0000)",
+            "rgb(0.0000, 0.9582, 0.0000)",
+            "rgb(0.0000, 0.9895, 0.0000)",
+            "rgb(0.1725, 1.0000, 0.0000)",
+            "rgb(0.4026, 1.0000, 0.0000)",
+            "rgb(0.5751, 1.0000, 0.0000)",
+            "rgb(0.7529, 0.9935, 0.0000)",
+            "rgb(0.8000, 0.9778, 0.0000)",
+            "rgb(0.8627, 0.9568, 0.0000)",
+            "rgb(0.9098, 0.9411, 0.0000)",
+            "rgb(0.9464, 0.9072, 0.0000)",
+            "rgb(0.9621, 0.8758, 0.0000)",
+            "rgb(0.9830, 0.8340, 0.0000)",
+            "rgb(1.0000, 0.7882, 0.0000)",
+            "rgb(1.0000, 0.7412, 0.0000)",
+            "rgb(1.0000, 0.6784, 0.0000)",
+            "rgb(1.0000, 0.6314, 0.0000)",
+            "rgb(1.0000, 0.5059, 0.0000)",
+            "rgb(1.0000, 0.3647, 0.0000)",
+            "rgb(1.0000, 0.1765, 0.0000)",
+            "rgb(1.0000, 0.0353, 0.0000)",
+            "rgb(0.9660, 0.0000, 0.0000)",
+            "rgb(0.9242, 0.0000, 0.0000)",
+            "rgb(0.8928, 0.0000, 0.0000)",
+            "rgb(0.8589, 0.0000, 0.0000)",
+            "rgb(0.8432, 0.0000, 0.0000)",
+            "rgb(0.8222, 0.0000, 0.0000)",
+            "rgb(0.8065, 0.0000, 0.0000)",
+            "rgb(0.7137, 0.0000, 0.0259)",
+            "rgb(0.6196, 0.0000, 0.0541)",
+            "rgb(0.4941, 0.0000, 0.0918)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_green_brown_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "green",
+            "brown",
+            "eccharts",
+            "sh_orog_metres",
+            "sh_orog_web",
+            "orography"
+        ],
+        "values" : [
+            "RGB(0.24,0.57,0.39)",
+            "RGB(0.86,1.0,0.08)",
+            "RGB(0.78,0.89,0.13)",
+            "RGB(0.69,0.78,0.2)",
+            "RGB(0.35,1.0,0.01)",
+            "RGB(0.38,0.80,0.16)",
+            "RGB(0.43,0.64,0.32)",
+            "RGB(0.84,0.54,0.33)",
+            "RGB(0.64,0.41,0.33)",
+            "RGB(0.45,0.29,0.18)",
+            "RGB(0.68,0.44,0.69)",
+            "RGB(0.63,0.26,0.65)",
+            "RGB(0.47,0.0,0.49)"
+        ]
+    },
+    "eccharts_rainbow_blue_greypurple_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "sh_prate_f01t256",
+            "sh_prate_radarlike_grided_f01",
+            "Stratiform precipitation rate",          
+            "blue",
+            "greypurple",
+            "rainbow"
+        ],
+        "values" : [
+            "RGB(0,0.083,1)",
+            "RGB(0.33,0.55,0.97)",
+            "RGB(0.12,0.79,0.84)",
+            "RGB(0.011,0.9,0.22)",
+            "RGB(0.88,0.93,0.14)",
+            "RGB(0.99,0.67,0.02)",
+            "RGB(1,0.081,0.016)",
+            "RGB(1,0.016,0.82)",
+            "RGB(0.69,0.0059,0.99)",
+            "RGB(0.791,0.693,0.8837)"
+        ]
+    },
+    "eccharts_rainbow_cyan_white_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "white",
+            "cyan",
+            "rainbow",
+            "sh_prate_radarlike",
+            "sh_prate_radarlike_grided",
+            "Convective precipitation rate",
+            "convective",
+            "rain",
+            "precipitation"
+        ],
+        "values" : [
+            "#38ffff",
+            "#209afd",
+            "#0e27fd",
+            "#34fe28",
+            "#27c71d",
+            "#1a9613",
+            "#fffe30",
+            "#fec627",
+            "#fc761d",
+            "#fc0016",
+            "#c5000e",
+            "#940008",
+            "#fc1ffe",
+            "#9524f8",
+            "white"
+        ]
+    },
+    "eccharts_yellow_red_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "yellow",
+            "red",
+            "eccharts",
+            "sh_red_f005t5lst",
+            "700 hPa vertical velocity"
+        ],
+        "values" : [
+            "rgb(1,1,0)",
+            "rgb(1,0.85,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.55,0)",
+            "rgb(1,0.4,0)",
+            "rgb(1,0.1,0)",
+            "rgb(0.85,0,0)",
+            "rgb(0.6,0,0)",
+            "rgb(0.4,0,0)"
+        ]
+    },
+    "eccharts_white_red_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "white",
+            "red",
+            "eccharts",
+            "sh_red_f05t1i01",
+            "10m wind gust extreme forecast index",
+            "10m wind speed extreme forecast index",
+            "CAPE extreme forecast index",
+            "CAPE shear extreme forecast index",
+            "Significant wave height extreme forecast index",
+            "Snowfall extreme forecast index",
+            "Total precipitation extreme forecast index",
+            "EFI",
+            "EFI cape",
+            "EFI capeshear",
+            "EFI wind speed",
+            "EFI wind gust",
+            "EFI wind",
+            "EFI precipitation",
+            "EFI snowfall",
+            "EFI snow",
+            "EFI wave height"
+        ],
+        "values" : [
+            "none",
+            "none",
+            "rgb(1, 1, 0, 1)",
+            "rgb(1, 0.75, 0, 1)",
+            "rgb(1, 0.5, 0, 1)",
+            "rgb(1, 0.25, 0, 1)",
+            "rgb(1, 0, 0, 1)"
+        ]
+    },
+    "eccharts_red_grey_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "red",
+            "grey",
+            "eccharts",
+            "sh_red_f0t90000",
+            "Visibility"
+        ],
+        "values" : [
+            "red",
+            "orange",
+            "yellow",
+            "green",
+            "RGB(0.40,0.40,0.95)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.4,0.4,0.4)"
+        ]
+    },
+    "eccharts_red_purple_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "red",
+            "purple",
+            "eccharts",
+            "sh_red_f0t900",
+            "Convective inhibition (CIN)",
+            "Convective inhibition",
+            "cin"
+        ],
+        "values" : [
+            "RGB(0.99,0.025,0.025)",
+            "RGB(0.99,0.52,0.0098)",
+            "RGB(0.98,0.98,0.058)",
+            "RGB(0.075,0.47,0.15)",
+            "RGB(0.037,0.96,0.099)",
+            "RGB(0.15,0.37,0.92)",
+            "RGB(0.56,0.24,0.92)"
+        ]
+    },
+    "eccharts_yellow_purple_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "yellow",
+            "purple",
+            "eccharts",
+            "sh_red_f15t60",
+            "K-index"
+        ],
+        "values" : [
+            "RGB(0.92,0.94,0.025)",
+            "RGB(0.94,0.62,0.025)",
+            "RGB(0.94,0.25,0.025)",
+            "RGB(0.67,0.06,0.1)",
+            "RGB(0.94,0.025,0.88)",
+            "RGB(0.43,0.066,0.65)"
+        ]
+    },
+    "eccharts_yellow_darkred_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "yellow",
+            "darkred",
+            "eccharts",
+            "sh_red_f1t50lst",
+            "1000 hPa divergence",
+            "300 hPa divergence",
+            "500 hPa divergence",
+            "700 hPa divergence",
+            "925 hPa divergence",
+            "250 hPa relative vorticity",
+            "300 hPa relative vorticity",
+            "500 hPa relative vorticity",
+            "700 hPa relative vorticity",
+            "850 hPa relative vorticity"
+        ],
+        "values" : [
+            "rgb(1,1,0)",
+            "rgb(1,0.9,0)",
+            "rgb(1,0.8,0)",
+            "rgb(1,0.7,0)",
+            "rgb(1,0.6,0)",
+            "rgb(1,0.5,0)",
+            "rgb(1,0.4,0)",
+            "rgb(1,0.3,0)",
+            "rgb(1,0.15,0)",
+            "rgb(0.9,0,0)",
+            "rgb(0.7,0,0)",
+            "rgb(0.5,0,0)",
+            "rgb(0.3,0,0)"
+        ]
+    },
+    "eccharts_yellow_navy_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "eccharts",
+            "yellow",
+            "navy",
+            "sh_red_f44t70",
+            "Total totals index",
+            "tti"
+        ],
+        "values" : [
+            "none",
+            "RGB(0.92,0.94,0.025)",
+            "RGB(0.94,0.62,0.025)",
+            "RGB(0.94,0.25,0.025)",
+            "RGB(0.67,0.06,0.1)",
+            "RGB(0.94,0.025,0.88)",
+            "RGB(0.43,0.066,0.65",
+            "navy"
+        ]
+    },
+    "eccharts_greyred_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "greyred",
+            "eccharts",
+            "sh_redgry_f0t1lst",
+            "Low cloud cover",
+            "lcc"
+        ],
+        "values" : [
+            "rgb(0.98,0.95,0.95)",
+            "rgb(0.94,0.9,0.9)",
+            "rgb(0.9,0.85,0.85)",
+            "rgb(0.86,0.8,0.8)",
+            "rgb(0.83,0.76,0.76)",
+            "rgb(0.8,0.72,0.72)",
+            "rgb(0.77,0.68,0.68)",
+            "rgb(0.74,0.64,0.64)"
+        ]
+    },
+    "eccharts_green_magenta_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "green",
+            "magenta",
+            "sh_rgb_f5t100",
+            "probability",
+            "Maximum 2 metre temperature probability",
+            "Minimum 2 metre temperature probability",
+            "2m temperature probability",
+            "2m temperature weighted probability",
+            "2 metre dew point temperature probability",
+            "Stratiform precipitation probability",
+            "Stratiform precipitation rate probability",
+            "Convective precipitation probability",
+            "Convective precipitation rate probability",
+            "Total precipitation probability",
+            "Total precipitation rate probability",
+            "Total precipitation weighted probability",
+            "Total snowfall probability",
+            "Total snowfall rate probability",
+            "Visibility probability",
+            "10m wind gusts probability",
+            "10m wind probability",
+            "10m wind speed weighted probability",
+            "Convective available potential energy (CAPE) probability",
+            "Mean wave period probability",
+            "Significant wave height probability",
+            "Probability of combined events of 10 metre wind speed and significant wave height",
+            "Probability of combined events of wind gust and total snowfall",
+            "Probability of combined events of wind speed and total precipitation",
+            "Probability of combined events of 2 metre Temperature and total precipitation"
+        ],
+        "values" : [
+            "RGB(0.48,0.82,0.78)",
+            "RGB(0.42,0.79,0.27)",
+            "RGB(0.83,0.85,0.2)",
+            "RGB(0.9,0.64,0.23)",
+            "RGB(0.97,0.43,0.43)",
+            "RGB(1,0.0039,1)"
+        ]
+    },
+    "eccharts_green_magenta_transparent25_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "green",
+            "magenta",
+            "transparent",
+            "sh_rgb_transparent25_f5t100",
+            "probability",
+            "Maximum 2 metre temperature probability",
+            "Minimum 2 metre temperature probability",
+            "2m temperature probability",
+            "2m temperature weighted probability",
+            "2 metre dew point temperature probability",
+            "Stratiform precipitation probability",
+            "Stratiform precipitation rate probability",
+            "Convective precipitation probability",
+            "Convective precipitation rate probability",
+            "Total precipitation probability",
+            "Total precipitation rate probability",
+            "Total precipitation weighted probability",
+            "Total snowfall probability",
+            "Total snowfall rate probability",
+            "Visibility probability",
+            "10m wind gusts probability",
+            "10m wind probability",
+            "10m wind speed weighted probability",
+            "Convective available potential energy (CAPE) probability",
+            "Mean wave period probability",
+            "Significant wave height probability",
+            "Probability of combined events of 10 metre wind speed and significant wave height",
+            "Probability of combined events of wind gust and total snowfall",
+            "Probability of combined events of wind speed and total precipitation",
+            "Probability of combined events of 2 metre Temperature and total precipitation"            
+        ],
+        "values" : [
+            "rgba(0.48,0.82,0.78,0.25)",
+            "rgba(0.42,0.79,0.27,0.25)",
+            "rgba(0.83,0.85,0.2,0.25)",
+            "rgba(0.9,0.64,0.23,0.25)",
+            "rgba(0.97,0.43,0.43,0.25)",
+            "rgba(1,0.0039,1,0.25)"
+        ]
+    },
+    "eccharts_green_magenta_transparent75_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "green",
+            "magenta",
+            "transparent",            
+            "sh_rgb_transparent75_f5t100",
+            "probability"
+        ],
+        "values" : [
+            "rgba(0.48,0.82,0.78,0.75)",
+            "rgba(0.42,0.79,0.27,0.75)",
+            "rgba(0.83,0.85,0.2,0.75)",
+            "rgba(0.9,0.64,0.23,0.75)",
+            "rgba(0.97,0.43,0.43,0.75)",
+            "rgba(1,0.0039,1,0.75)"
+        ]
+    },
+    "eccharts_green_magenta_transparent50_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "green",
+            "magenta",
+            "transparent",            
+            "sh_rgb_transparent_f5t100",
+            "probability",
+            "Maximum 2 metre temperature probability",
+            "Minimum 2 metre temperature probability",
+            "2m temperature probability",
+            "2m temperature weighted probability",
+            "2 metre dew point temperature probability",
+            "Stratiform precipitation probability",
+            "Stratiform precipitation rate probability",
+            "Convective precipitation probability",
+            "Convective precipitation rate probability",
+            "Total precipitation probability",
+            "Total precipitation rate probability",
+            "Total precipitation weighted probability",
+            "Total snowfall probability",
+            "Total snowfall rate probability",
+            "Visibility probability",
+            "10m wind gusts probability",
+            "10m wind probability",
+            "10m wind speed weighted probability",
+            "Convective available potential energy (CAPE) probability",
+            "Mean wave period probability",
+            "Significant wave height probability",
+            "Probability of combined events of 10 metre wind speed and significant wave height",
+            "Probability of combined events of wind gust and total snowfall",
+            "Probability of combined events of wind speed and total precipitation",
+            "Probability of combined events of 2 metre Temperature and total precipitation"             
+        ],
+        "values" : [
+            "rgba(0.48,0.82,0.78,0.5)",
+            "rgba(0.42,0.79,0.27,0.5)",
+            "rgba(0.83,0.85,0.2,0.5)",
+            "rgba(0.9,0.64,0.23,0.5)",
+            "rgba(0.97,0.43,0.43,0.5)",
+            "rgba(1,0.0039,1,0.5)"
+        ]
+    },
+    "eccharts_red_purple_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "red",
+            "purple",            
+            "eccharts",
+            "sh_spechum_green",
+            "sh_spechum_option2",
+            "1000 hPa specific humidity",
+            "925 hPa specific humidity"            
+        ],
+        "values" : [
+            "RGB(0.41,0.052,0.045)",
+            "RGB(0.66,0.026,0.026)",
+            "RGB(0.96,0.049,0.033)",
+            "peach",
+            "RGB(0.94,0.73,0.73)",
+            "RGB(0.94,0.73,0.9)",
+            "RGB(0.96,0.53,0.81)",
+            "RGB(0.99,0.06,0.87)",
+            "RGB(0.78,0.017,0.66)",
+            "RGB(0.53,0.035,0.43)",
+            "RGB(0.61,0.018,0.76)",
+            "RGB(0.31,0.042,0.44)",
+            "RGB(0.16,0.055,0.22)"
+        ]
+    },
+    "eccharts_rainbow_red_violet_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "rainbow",
+            "red",
+            "violet",
+            "sh_spechum_option1",
+            "sh_spechum_red",
+            "1000 hPa specific humidity",
+            "925 hPa specific humidity",
+            "specific humidity"
+        ],
+        "values" : [
+            "red",
+            "peach",
+            "gold",
+            "yellow",
+            "yellow_green",
+            "kelly_green",
+            "blue_green",
+            "turquoise",
+            "greenish_blue",
+            "blue",
+            "violet",
+            "RGB(0.67,0.019,0.79)",
+            "RGB(1,0.0039,0.78)"
+        ]
+    },
+    "eccharts_green_blue_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "eccharts",
+            "green",
+            "blue",            
+            "sh_spechum_option3",
+            "1000 hPa specific humidity",
+            "925 hPa specific humidity",
+            "specific humidity"            
+        ],
+        "values" : [
+            "RGB(0.82,0.93,0.84)",
+            "RGB(0.52,0.96,0.71)",
+            "RGB(0.36,0.94,0.51)",
+            "RGB(0.19,0.79,0.55)",
+            "RGB(0.021,0.73,0.45)",
+            "RGB(0.06,0.47,0.38)",
+            "RGB(0.029,0.93,0.96)",
+            "RGB(0.029,0.76,0.79)",
+            "RGB(0.47,0.73,0.97)",
+            "RGB(0.18,0.54,0.99)",
+            "RGB(0.06,0.23,0.99)",
+            "RGB(0.026,0.097,0.63)",
+            "RGB(0.12,0.052,0.32)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "eccharts",
+            "sh_spectral_ch4_500hpa",
+            "rainbow",
+            "black",
+            "darkred",
+            "Methane at 500 hPa",
+            "methane",
+            "ch4",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.4941, 0.0000, 0.5608)",
+            "rgb(0.0941, 0.0000, 0.6549)",
+            "rgb(0.0000, 0.1098, 0.8667)",
+            "rgb(0.0000, 0.5634, 0.8667)",
+            "rgb(0.0000, 0.6667, 0.6484)",
+            "rgb(0.0000, 0.6301, 0.2405)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.9268, 0.0000)",
+            "rgb(0.6327, 1.0000, 0.0000)",
+            "rgb(0.9516, 0.8967, 0.0000)",
+            "rgb(1.0000, 0.6471, 0.0000)",
+            "rgb(0.9765, 0.0000, 0.0000)",
+            "rgb(0.8275, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "sh_spectral_ch4_850hpa",
+            "sh_spectral_co2_50hpa",
+            "rainbow",
+            "black",
+            "darkred",
+            "Methane at 850 hPa",
+            "Carbon dioxide at 50 hPa",
+            "co2",
+            "carbon dioxide",
+            "methane",
+            "ch4",
+            "cams"             
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.5202, 0.0000, 0.5869)",
+            "rgb(0.0000, 0.0000, 0.7883)",
+            "rgb(0.0000, 0.5216, 0.8667)",
+            "rgb(0.0000, 0.6667, 0.6275)",
+            "rgb(0.0000, 0.6131, 0.0000)",
+            "rgb(0.0000, 0.8536, 0.0000)",
+            "rgb(0.5176, 1.0000, 0.0000)",
+            "rgb(0.9725, 0.8549, 0.0000)",
+            "rgb(1.0000, 0.3647, 0.0000)",
+            "rgb(0.8536, 0.0000, 0.0000)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_37" : {
+        "n_colours" : "37",
+        "tags" : [
+            "37",
+            "rainbow",
+            "black",
+            "darkred",
+            "eccharts",
+            "sh_spectral_co2_500hpa",
+            "Carbon dioxide at 500 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"               
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.2788, 0.0225, 0.3153)",
+            "rgb(0.4732, 0.0000, 0.5398)",
+            "rgb(0.5098, 0.0000, 0.5765)",
+            "rgb(0.4287, 0.0000, 0.6131)",
+            "rgb(0.1359, 0.0000, 0.6497)",
+            "rgb(0.0000, 0.0000, 0.7255)",
+            "rgb(0.0000, 0.0000, 0.8353)",
+            "rgb(0.0000, 0.1830, 0.8667)",
+            "rgb(0.0000, 0.4693, 0.8667)",
+            "rgb(0.0000, 0.5425, 0.8667)",
+            "rgb(0.0000, 0.6078, 0.8432)",
+            "rgb(0.0000, 0.6445, 0.7334)",
+            "rgb(0.0000, 0.6667, 0.6379)",
+            "rgb(0.0000, 0.6667, 0.5647)",
+            "rgb(0.0000, 0.6458, 0.3660)",
+            "rgb(0.0000, 0.6092, 0.0732)",
+            "rgb(0.0000, 0.6549, 0.0000)",
+            "rgb(0.0000, 0.7385, 0.0000)",
+            "rgb(0.0000, 0.8118, 0.0000)",
+            "rgb(0.0000, 0.8850, 0.0000)",
+            "rgb(0.0000, 0.9582, 0.0000)",
+            "rgb(0.1725, 1.0000, 0.0000)",
+            "rgb(0.5751, 1.0000, 0.0000)",
+            "rgb(0.8000, 0.9778, 0.0000)",
+            "rgb(0.9098, 0.9411, 0.0000)",
+            "rgb(0.9621, 0.8758, 0.0000)",
+            "rgb(1.0000, 0.7882, 0.0000)",
+            "rgb(1.0000, 0.6784, 0.0000)",
+            "rgb(1.0000, 0.5059, 0.0000)",
+            "rgb(1.0000, 0.1765, 0.0000)",
+            "rgb(0.9660, 0.0000, 0.0000)",
+            "rgb(0.8928, 0.0000, 0.0000)",
+            "rgb(0.8432, 0.0000, 0.0000)",
+            "rgb(0.8065, 0.0000, 0.0000)",
+            "rgb(0.6196, 0.0000, 0.0541)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_black_darkred_62" : {
+        "n_colours" : "62",
+        "tags" : [
+            "62",
+            "eccharts",
+            "rainbow",
+            "black",
+            "darkred",
+            "sh_spectral_co2_850hpa",
+            "Carbon dioxide at 850 hPa",
+            "co2",
+            "carbon dioxide",
+            "cams"  
+        ],
+        "values" : [
+            "rgb(0.0500, 0.0500, 0.0500)",
+            "rgb(0.1807, 0.0343, 0.2016)",
+            "rgb(0.3115, 0.0186, 0.3532)",
+            "rgb(0.4422, 0.0029, 0.5049)",
+            "rgb(0.4837, 0.0000, 0.5503)",
+            "rgb(0.5046, 0.0000, 0.5712)",
+            "rgb(0.5307, 0.0000, 0.5974)",
+            "rgb(0.3869, 0.0000, 0.6183)",
+            "rgb(0.2196, 0.0000, 0.6392)",
+            "rgb(0.0523, 0.0000, 0.6602)",
+            "rgb(0.0000, 0.0000, 0.7098)",
+            "rgb(0.0000, 0.0000, 0.7883)",
+            "rgb(0.0000, 0.0000, 0.8510)",
+            "rgb(0.0000, 0.1098, 0.8667)",
+            "rgb(0.0000, 0.2562, 0.8667)",
+            "rgb(0.0000, 0.4026, 0.8667)",
+            "rgb(0.0000, 0.5007, 0.8667)",
+            "rgb(0.0000, 0.5425, 0.8667)",
+            "rgb(0.0000, 0.5843, 0.8667)",
+            "rgb(0.0000, 0.6131, 0.8275)",
+            "rgb(0.0000, 0.6340, 0.7647)",
+            "rgb(0.0000, 0.6602, 0.6863)",
+            "rgb(0.0000, 0.6667, 0.6379)",
+            "rgb(0.0000, 0.6667, 0.5961)",
+            "rgb(0.0000, 0.6667, 0.5542)",
+            "rgb(0.0000, 0.6562, 0.4496)",
+            "rgb(0.0000, 0.6301, 0.2405)",
+            "rgb(0.0000, 0.6092, 0.0732)",
+            "rgb(0.0000, 0.6235, 0.0000)",
+            "rgb(0.0000, 0.6653, 0.0000)",
+            "rgb(0.0000, 0.7072, 0.0000)",
+            "rgb(0.0000, 0.7595, 0.0000)",
+            "rgb(0.0000, 0.8013, 0.0000)",
+            "rgb(0.0000, 0.8432, 0.0000)",
+            "rgb(0.0000, 0.8850, 0.0000)",
+            "rgb(0.0000, 0.9268, 0.0000)",
+            "rgb(0.0000, 0.9791, 0.0000)",
+            "rgb(0.1150, 1.0000, 0.0000)",
+            "rgb(0.3451, 1.0000, 0.0000)",
+            "rgb(0.5751, 1.0000, 0.0000)",
+            "rgb(0.7529, 0.9935, 0.0000)",
+            "rgb(0.8313, 0.9673, 0.0000)",
+            "rgb(0.8941, 0.9464, 0.0000)",
+            "rgb(0.9411, 0.9176, 0.0000)",
+            "rgb(0.9621, 0.8758, 0.0000)",
+            "rgb(0.9830, 0.8340, 0.0000)",
+            "rgb(1.0000, 0.7725, 0.0000)",
+            "rgb(1.0000, 0.7098, 0.0000)",
+            "rgb(1.0000, 0.6471, 0.0000)",
+            "rgb(1.0000, 0.5529, 0.0000)",
+            "rgb(1.0000, 0.3647, 0.0000)",
+            "rgb(1.0000, 0.1294, 0.0000)",
+            "rgb(0.9869, 0.0000, 0.0000)",
+            "rgb(0.9451, 0.0000, 0.0000)",
+            "rgb(0.9033, 0.0000, 0.0000)",
+            "rgb(0.8641, 0.0000, 0.0000)",
+            "rgb(0.8379, 0.0000, 0.0000)",
+            "rgb(0.8170, 0.0000, 0.0000)",
+            "rgb(0.7765, 0.0000, 0.0071)",
+            "rgb(0.6510, 0.0000, 0.0447)",
+            "rgb(0.5255, 0.0000, 0.0824)",
+            "rgb(0.4000, 0.0000, 0.1200)"
+        ]
+    },
+    "eccharts_rainbow_purple_red_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "rainbow",
+            "categorical",
+            "purple",
+            "red",
+            "eccharts",
+            "sh_sst_fM2t36i2",
+            "Control forecast: Sea surface temperature",
+            "sst",
+            "Sea surface temperature (SST)"
+        ],
+        "values" : [
+            "RGB(0.29,0.00,0.48)",
+            "RGB(0.61,0.00,1.00)",
+            "RGB(0.80,0.47,1.00)",
+            "RGB(0.00,0.00,1.00)",
+            "RGB(0.00,0.35,1.00)",
+            "RGB(0.00,0.55,1.00)",
+            "RGB(0.04,0.49,0.00)",
+            "RGB(0.04,0.75,0.00)",
+            "RGB(0.04,1.00,0.00)",
+            "RGB(0.63,0.61,0.00)",
+            "RGB(0.84,0.81,0.00)",
+            "RGB(1.00,0.93,0.00)",
+            "RGB(0.66,0.33,0.00)",
+            "RGB(0.84,0.42,0.00)",
+            "RGB(1.00,0.52,0.00)",
+            "RGB(0.75,0.04,0.00)",
+            "RGB(1.00,0.05,0.00)",
+            "RGB(1.00,0.52,0.50)",
+            "RGB(1.00,0.84,0.83)"
+        ]
+    },
+    "eccharts_rainbow_purple_white_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "rainbow",
+            "categorical",
+            "purple",
+            "white",            
+            "eccharts",
+            "sh_sst_fM5t45",
+            "Control forecast: Sea surface temperature",
+            "sst",
+            "Sea surface temperature (SST)"
+        ],
+        "values" : [
+            "RGB(0.29,0.00,0.48)",
+            "RGB(0.80,0.47,1.00)",
+            "RGB(0.00,0.35,1.00)",
+            "RGB(0.04,0.75,0.00)",
+            "RGB(0.84,0.81,0.00)",
+            "RGB(0.9,0.6,0.00)",
+            "RGB(1.00,0.05,0.00)",
+            "RGB(1.00,0.6,0.6)",
+            "RGB(1.0,0.85,0.85)",
+            "white"
+        ]
+    },
+    "eccharts_blue_red2_15" : {
+        "n_colours" : "15",
+        "tags" : [
+            "15",
+            "blue",
+            "red",
+            "eccharts",
+            "sh_tcw_f5t100",
+            "Total column water",
+            "tcw"
+        ],
+        "values" : [
+            "#479fff",
+            "#4783ff",
+            "#475aff",
+            "#474cff",
+            "#0029a3",
+            "#ffcbc2",
+            "#ffa899",
+            "#ff745c",
+            "#ff401f",
+            "#e02200",
+            "#b81c00",
+            "#8f1500",
+            "#660f00",
+            "#3d0900",
+            "#140300"
+        ]
+    },
+    "eccharts_rainbow_grey_pink_dark_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "rainbow",
+            "dark",
+            "grey",
+            "pink",              
+            "eccharts",
+            "sh_tp_f1t30"
+        ],
+        "values" : [
+            "rgb(97,119,135)",
+            "rgb(85,124,153)",
+            "rgb(86,138,161)",
+            "rgb(85,150,165)",
+            "rgb(86,165,173)",
+            "rgb(86,166,133)",
+            "rgb(142,165,86)",
+            "rgb(175,84,84)",
+            "rgb(176,85,168)"
+        ]
+    },
+    "eccharts_violet_brown_less_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "eccharts",
+            "violet",
+            "brown",
+            "sh_viobrn_fM50t50lst_less",
+            "1000 hPa divergence",
+            "300 hPa divergence",
+            "500 hPa divergence",
+            "700 hPa divergence",
+            "925 hPa divergence",
+            "250 hPa relative vorticity",
+            "300 hPa relative vorticity",
+            "500 hPa relative vorticity",
+            "700 hPa relative vorticity",
+            "850 hPa relative vorticity",
+            "divergence",
+            "relative vorticity"            
+        ],
+        "values" : [
+            "rgb(0.32,0.1,0.5)",
+            "rgb(0.48,0.4,0.7)",
+            "rgb(0.6,0.5,0.8)",
+            "rgb(0.66,0.56,0.85)",
+            "rgb(0.72,0.62,0.9)",
+            "rgb(0.78,0.68,0.96)",
+            "rgb(0.84,0.74,1)",
+            "rgb(0.9,0.8,1)",
+            "rgb(0.95,0.85,1)",
+            "none",
+            "rgb(1,0.95,0.75)",
+            "rgb(1,0.9,0.6)",
+            "rgb(1,0.84,0.45)",
+            "rgb(1,0.77,0.3)",
+            "rgb(1,0.7,0.15)",
+            "rgb(1,0.62,0)",
+            "rgb(1,0.54,0)",
+            "rgb(0.95,0.46,0)",
+            "rgb(0.9,0.4,0)"
+        ]
+    },
+    "eccharts_violet_brown_19" : {
+        "n_colours" : "19",
+        "tags" : [
+            "19",
+            "eccharts",
+            "violet",
+            "brown",            
+            "sh_viobrn_fM5t5lst",
+            "700 hPa vertical velocity"
+        ],
+        "values" : [
+            "rgb(0.36,0.2,0.5)",
+            "rgb(0.45,0.32,0.6)",
+            "rgb(0.53,0.42,0.7)",
+            "rgb(0.6,0.5,0.78)",
+            "rgb(0.67,0.57,0.85)",
+            "rgb(0.74,0.64,0.9)",
+            "rgb(0.81,0.71,0.95)",
+            "rgb(0.88,0.78,1)",
+            "rgb(0.95,0.85,1)",
+            "none",
+            "rgb(1,0.95,0.75)",
+            "rgb(1,0.88,0.55)",
+            "rgb(1,0.81,0.35)",
+            "rgb(1,0.74,0.2)",
+            "rgb(1,0.67,0.1)",
+            "rgb(1,0.59,0)",
+            "rgb(0.97,0.51,0)",
+            "rgb(0.92,0.43,0)",
+            "rgb(0.85,0.36,0)"
+        ]
+    },
+    "eccharts_green_blue_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "green",
+            "blue",
+            "eccharts",
+            "sh_viridis_co_300hpa",
+            "sh_viridis_co_500hpa",
+            "sh_viridis_co_50hpa",
+            "sh_viridis_co_850hpa",
+            "sh_viridis_go3_300hpa",
+            "sh_viridis_go3_500hpa",
+            "sh_viridis_go3_850hpa",
+            "sh_viridis_go3_50hpa",
+            "sh_viridis_hcho_50hpa",
+            "sh_viridis_hcho_300hpa",
+            "sh_viridis_hcho_500hpa",
+            "sh_viridis_hcho_850hpa",
+            "sh_viridis_no2_50hpa",
+            "sh_viridis_no2_300hpa",
+            "sh_viridis_no2_500hpa",
+            "sh_viridis_no2_850hpa",
+            "sh_viridis_o3_50hpa",
+            "sh_viridis_o3_300hpa",
+            "sh_viridis_o3_500hpa",
+            "sh_viridis_o3_850hpa",
+            "sh_viridis_so2_50hpa",
+            "sh_viridis_so2_300hpa",
+            "sh_viridis_so2_500hpa",
+            "sh_viridis_so2_850hpa",
+            "Carbon monoxide at 50 hPa",
+            "Carbon monoxide at 300 hPa",
+            "Carbon monoxide at 500 hPa",
+            "Carbon monoxide at 850 hPa",
+            "Formaldehyde at 50 hPa",            
+            "Formaldehyde at 300 hPa",
+            "Formaldehyde at 500 hPa",
+            "Formaldehyde at 850 hPa",     
+            "Nitrogen dioxide at 850 hPa",            
+            "Nitrogen dioxide at 500 hPa",            
+            "Nitrogen dioxide at 300 hPa",
+            "Nitrogen dioxide at 50 hPa",              
+            "Ozone at 50 hPa",            
+            "Ozone at 300 hPa",
+            "Ozone at 500 hPa",
+            "Ozone at 850 hPa",
+            "Sulphur dioxide at 50 hPa",
+            "Sulphur dioxide at 30 hPa",
+            "Sulphur dioxide at 850 hPa",
+            "Sulphur dioxide at 500 hPa",
+            "co",
+            "o3",
+            "hcho",
+            "no2",
+            "so2",
+            "carbon_monoxide",
+            "nitrogen dioxide",
+            "formaldehyde",
+            "cams"            
+        ],
+        "values" : [
+            "rgb(0.9860,0.8921,0.5689)",
+            "rgb(0.8222,0.8545,0.4513)",
+            "rgb(0.6279,0.8208,0.4030)",
+            "rgb(0.4216,0.7772,0.4406)",
+            "rgb(0.2482,0.7127,0.5038)",
+            "rgb(0.1589,0.6402,0.5455)",
+            "rgb(0.1477,0.5640,0.5646)",
+            "rgb(0.1705,0.4833,0.5684)",
+            "rgb(0.2012,0.4042,0.5636)",
+            "rgb(0.2381,0.3193,0.5499)",
+            "rgb(0.2727,0.2211,0.5125)",
+            "rgb(0.2848,0.1196,0.4395)"
+        ]
+    },
+    "eccharts_rainbow_pink_grey_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "rainbow",
+            "pink",
+            "grey",
+            "eccharts",
+            "sh_vis_f0t100000",
+            "Visibility"
+        ],
+        "values" : [
+            "RGB(0.98,0.26,0.8)",
+            "red",
+            "RGB(0.97,0.41,0.0038)",
+            "RGB(0.99,0.64,0)",
+            "RGB(0.99,0.86,0)",
+            "RGB(0.76,0.99,0)",
+            "RGB(0,0.99,0.3)",
+            "RGB(0,0.96,1)",
+            "RGB(0,0.76,1)",
+            "RGB(0.0039,0.42,0.99)",
+            "RGB(0.3,0.43,0.68)",
+            "RGB(0.52,0.61,0.77)",
+            "RGB(0.74,0.80,0.92)"
+        ]
+    },
+    "eccharts_pink_green_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "pink",
+            "green",
+            "eccharts",
+            "sh_vis_f0t1500",
+            "Visibility"
+        ],
+        "values" : [
+            "RGB(0.98,0.26,0.8)",
+            "red",
+            "RGB(0.97,0.41,0.0038)",
+            "RGB(0.99,0.64,0)",
+            "RGB(0.99,0.86,0)",
+            "RGB(0.76,0.99,0)",
+            "RGB(0,0.99,0.3)"
+        ]
+    },
+    "eccharts_grey_white_8" : {
+        "n_colours" : "8",
+        "tags" : [
+            "8",
+            "grey",
+            "white",
+            "eccharts",
+            "sh_whi_f0t1lst",
+            "High cloud cover",
+            "hcc"
+        ],
+        "values" : [
+            "rgb(0.88,0.88,0.88)",
+            "rgb(0.89,0.89,0.89)",
+            "rgb(0.91,0.91,0.91)",
+            "rgb(0.93,0.93,0.93)",
+            "rgb(0.95,0.95,0.95)",
+            "rgb(0.97,0.97,0.97)",
+            "rgb(0.99,0.99,0.99)",
+            "rgb(1,1,1)"
+        ]
+    },
+    "eccharts_cyan_4" : {
+        "n_colours" : "4",
+        "tags" : [
+            "4",
+            "cyan",
+            "eccharts",
+            "sic_10to100",
+            "Sea ice cover as fraction of a grid box",
+            "sea ice"
+            
+        ],
+        "values" : [
+            "RGB(0,0.6,0.6)",
+            "RGB(0,0.75,0.75)",
+            "RGB(0,0.88,0.88)",
+            "RGB(0.0,1.0,1.0)"
+        ]
+    },
+    "eccharts_blue_grey_76" : {
+        "n_colours" : "76",
+        "tags" : [
+            "76",
+            "blue",
+            "grey",
+            "eccharts",
+            "sim_image_ir_fixed_range",
+            "sim_image_ir_fixed_values",
+            "Simulated image: Infrared (IR) channel",
+            "IR",
+            "IR 10.8",
+            "channel 9",
+            "infrared"
+        ],
+        "values" : [
+            "HSL(200,1,0.392)",
+            "HSL(200,1,0.427)",
+            "HSL(200,1,0.463)",
+            "HSL(200,1,0.498)",
+            "HSL(200,1,0.533)",
+            "HSL(200,1,0.569)",
+            "HSL(200,1,0.604)",
+            "HSL(200,1,0.639)",
+            "HSL(200,1,0.675)",
+            "HSL(200,1,0.71)",
+            "HSL(200,1,0.745)",
+            "HSL(200,1,0.78)",
+            "HSL(200,1,0.816)",
+            "HSL(200,1,0.851)",
+            "HSL(200,1,0.886)",
+            "HSL(200,1,0.922)",
+            "RGB(0.99612,0.99612,0.99612)",
+            "RGB(0.98969,0.98969,0.98969)",
+            "RGB(0.98405,0.98405,0.98405)",
+            "RGB(0.97915,0.97915,0.97915)",
+            "RGB(0.97491,0.97491,0.97491)",
+            "RGB(0.97126,0.97126,0.97126)",
+            "RGB(0.96808,0.96808,0.96808)",
+            "RGB(0.96526,0.96526,0.96526)",
+            "RGB(0.96267,0.96267,0.96267)",
+            "RGB(0.96018,0.96018,0.96018)",
+            "RGB(0.95763,0.95763,0.95763)",
+            "RGB(0.95488,0.95488,0.95488)",
+            "RGB(0.9518,0.9518,0.9518)",
+            "RGB(0.94823,0.94823,0.94823)",
+            "RGB(0.94403,0.94403,0.94403)",
+            "RGB(0.93908,0.93908,0.93908)",
+            "RGB(0.93323,0.93323,0.93323)",
+            "RGB(0.92637,0.92637,0.92637)",
+            "RGB(0.9184,0.9184,0.9184)",
+            "RGB(0.9092,0.9092,0.9092)",
+            "RGB(0.8987,0.8987,0.8987)",
+            "RGB(0.88682,0.88682,0.88682)",
+            "RGB(0.8735,0.8735,0.8735)",
+            "RGB(0.85869,0.85869,0.85869)",
+            "RGB(0.84237,0.84237,0.84237)",
+            "RGB(0.82452,0.82452,0.82452)",
+            "RGB(0.80514,0.80514,0.80514)",
+            "RGB(0.78426,0.78426,0.78426)",
+            "RGB(0.7619,0.7619,0.7619)",
+            "RGB(0.73813,0.73813,0.73813)",
+            "RGB(0.713,0.713,0.713)",
+            "RGB(0.68659,0.68659,0.68659)",
+            "RGB(0.65902,0.65902,0.65902)",
+            "RGB(0.63038,0.63038,0.63038)",
+            "RGB(0.6008,0.6008,0.6008)",
+            "RGB(0.57042,0.57042,0.57042)",
+            "RGB(0.5394,0.5394,0.5394)",
+            "RGB(0.50788,0.50788,0.50788)",
+            "RGB(0.47605,0.47605,0.47605)",
+            "RGB(0.44407,0.44407,0.44407)",
+            "RGB(0.41212,0.41212,0.41212)",
+            "RGB(0.3804,0.3804,0.3804)",
+            "RGB(0.34909,0.34909,0.34909)",
+            "RGB(0.31838,0.31838,0.31838)",
+            "RGB(0.28845,0.28845,0.28845)",
+            "RGB(0.25949,0.25949,0.25949)",
+            "RGB(0.23166,0.23166,0.23166)",
+            "RGB(0.20515,0.20515,0.20515)",
+            "RGB(0.18009,0.18009,0.18009)",
+            "RGB(0.15662,0.15662,0.15662)",
+            "RGB(0.13487,0.13487,0.13487)",
+            "RGB(0.11494,0.11494,0.11494)",
+            "RGB(0.09689,0.09689,0.09689)",
+            "RGB(0.08077,0.08077,0.08077)",
+            "RGB(0.06659,0.06659,0.06659)",
+            "RGB(0.05434,0.05434,0.05434)",
+            "RGB(0.04395,0.04395,0.04395)",
+            "RGB(0.03532,0.03532,0.03532)",
+            "RGB(0.0283,0.0283,0.0283)",
+            "RGB(0.02268,0.02268,0.02268)"
+        ]
+    },
+    "eccharts_blue_grey_68" : {
+        "n_colours" : "68",
+        "tags" : [
+            "68",
+            "blue",
+            "grey",
+            "eccharts",
+            "sim_image_wv_500",
+            "Simulated image: Water vapour (WV) ~500 hPa",
+            "meteosat 9",
+            "channel 6",
+            "WV 7.3"
+        ],
+        "values" : [
+            "HSL(200,1,0.78)",
+            "HSL(200,1,0.816)",
+            "HSL(200,1,0.851)",
+            "HSL(200,1,0.886)",
+            "HSL(200,1,0.922)",
+            "rgb(1.0,1.0,1.0)",
+            "rgb(0.98,0.98,0.98)",
+            "rgb(0.97,0.97,0.97)",
+            "rgb(0.95,0.95,0.95)",
+            "rgb(0.94,0.94,0.94)",
+            "rgb(0.92,0.92,0.92)",
+            "rgb(0.9,0.9,0.9)",
+            "rgb(0.89,0.89,0.89)",
+            "rgb(0.87,0.87,0.87)",
+            "rgb(0.86,0.86,0.86)",
+            "rgb(0.84,0.84,0.84)",
+            "rgb(0.82,0.82,0.82)",
+            "rgb(0.81,0.81,0.81)",
+            "rgb(0.79,0.79,0.79)",
+            "rgb(0.78,0.78,0.78)",
+            "rgb(0.76,0.76,0.76)",
+            "rgb(0.74,0.74,0.74)",
+            "rgb(0.73,0.73,0.73)",
+            "rgb(0.71,0.71,0.71)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.68,0.68,0.68)",
+            "rgb(0.66,0.66,0.66)",
+            "rgb(0.65,0.65,0.65)",
+            "rgb(0.63,0.63,0.63)",
+            "rgb(0.62,0.62,0.62)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.58,0.58,0.58)",
+            "rgb(0.57,0.57,0.57)",
+            "rgb(0.55,0.55,0.55)",
+            "rgb(0.54,0.54,0.54)",
+            "rgb(0.52,0.52,0.52)",
+            "rgb(0.5,0.5,0.5)",
+            "rgb(0.49,0.49,0.49)",
+            "rgb(0.47,0.47,0.47)",
+            "rgb(0.46,0.46,0.46)",
+            "rgb(0.44,0.44,0.44)",
+            "rgb(0.42,0.42,0.42)",
+            "rgb(0.41,0.41,0.41)",
+            "rgb(0.39,0.39,0.39)",
+            "rgb(0.38,0.38,0.38)",
+            "rgb(0.36,0.36,0.36)",
+            "rgb(0.34,0.34,0.34)",
+            "rgb(0.33,0.33,0.33)",
+            "rgb(0.31,0.31,0.31)",
+            "rgb(0.3,0.3,0.3)",
+            "rgb(0.28,0.28,0.28)",
+            "rgb(0.26,0.26,0.26)",
+            "rgb(0.25,0.25,0.25)",
+            "rgb(0.23,0.23,0.23)",
+            "rgb(0.22,0.22,0.22)",
+            "rgb(0.2,0.2,0.2)",
+            "rgb(0.18,0.18,0.18)",
+            "rgb(0.17,0.17,0.17)",
+            "rgb(0.15,0.15,0.15)",
+            "rgb(0.14,0.14,0.14)",
+            "rgb(0.12,0.12,0.12)",
+            "rgb(0.1,0.1,0.1)",
+            "rgb(0.09,0.09,0.09)",
+            "rgb(0.07,0.07,0.07)",
+            "rgb(0.06,0.06,0.06)",
+            "rgb(0.04,0.04,0.04)",
+            "rgb(0.02,0.02,0.02)",
+            "rgb(0.01,0.01,0.01)"
+        ]
+    },
+    "eccharts_blue_grey_45" : {
+        "n_colours" : "45",
+        "tags" : [
+            "45",
+            "blue",
+            "grey",            
+            "eccharts",
+            "sim_image_wv_fixed_range",
+            "Simulated image: Water vapour (WV) ~300 hPa",
+            "meteosat 9",
+            "channel 5",
+            "WV 6.2"
+        ],
+        "values" : [
+            "HSL(200,1,0.78)",
+            "HSL(200,1,0.816)",
+            "HSL(200,1,0.851)",
+            "HSL(200,1,0.886)",
+            "HSL(200,1,0.922)",
+            "rgb(1,1,1)",
+            "rgb(1,1,1)",
+            "rgb(0.99,0.99,0.99)",
+            "rgb(0.97,0.97,0.97)",
+            "rgb(0.95,0.95,0.95)",
+            "rgb(0.94,0.94,0.94)",
+            "rgb(0.93,0.93,0.93)",
+            "rgb(0.91,0.91,0.91)",
+            "rgb(0.89,0.89,0.89)",
+            "rgb(0.86,0.86,0.86)",
+            "rgb(0.83,0.83,0.83)",
+            "rgb(0.8,0.8,0.8)",
+            "rgb(0.77,0.77,0.77)",
+            "rgb(0.74,0.74,0.74)",
+            "rgb(0.71,0.71,0.71)",
+            "rgb(0.69,0.69,0.69)",
+            "rgb(0.66,0.66,0.66)",
+            "rgb(0.63,0.63,0.63)",
+            "rgb(0.6,0.6,0.6)",
+            "rgb(0.57,0.57,0.57)",
+            "rgb(0.54,0.54,0.54)",
+            "rgb(0.51,0.51,0.51)",
+            "rgb(0.49,0.49,0.49)",
+            "rgb(0.46,0.46,0.46)",
+            "rgb(0.43,0.43,0.43)",
+            "rgb(0.4,0.4,0.4)",
+            "rgb(0.37,0.37,0.37)",
+            "rgb(0.34,0.34,0.34)",
+            "rgb(0.31,0.31,0.31)",
+            "rgb(0.29,0.29,0.29)",
+            "rgb(0.26,0.26,0.26)",
+            "rgb(0.23,0.23,0.23)",
+            "rgb(0.2,0.2,0.2)",
+            "rgb(0.17,0.17,0.17)",
+            "rgb(0.14,0.14,0.14)",
+            "rgb(0.11,0.11,0.11)",
+            "rgb(0.09,0.09,0.09)",
+            "rgb(0.06,0.06,0.06)",
+            "rgb(0.03,0.03,0.03)",
+            "rgb(0,0,0)"
+        ]
+    },
+    "eccharts_green_purple_13" : {
+        "n_colours" : "13",
+        "tags" : [
+            "13",
+            "green",
+            "purple",
+            "eccharts",
+            "snow_1to10000",
+            "Snow depth"
+        ],
+        "values" : [
+            "rgb(0.45,0.6,0.45)",
+            "rgb(0.59,0.75,0.59)",
+            "rgb(0.73,0.84,0.73)",
+            "rgb(0.87,0.87,0.87)",
+            "rgb(0.94,0.94,0.94)",
+            "rgb(1,1,1)",
+            "rgb(0.9,0.95,1)",
+            "rgb(0.8,0.9,1)",
+            "rgb(0.67,0.83,1)",
+            "rgb(0.5,0.75,1.0)",
+            "rgb(0.85,0.8,1)",
+            "rgb(0.75,0.68,1)",
+            "rgb(0.6,0.5,1)"
+        ]
+    },
+    "eccharts_greyblue_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "greyblue",
+            "eccharts",
+            "snow_1to1000_blu"
+        ],
+        "values" : [
+            "rgb(0.54,0.64,0.64)",
+            "rgb(0.6,0.7,0.7)",
+            "rgb(0.66,0.76,0.76)",
+            "rgb(0.72,0.82,0.82)",
+            "rgb(0.78,0.88,0.88)",
+            "rgb(0.84,0.94,0.94)",
+            "rgb(0.9,1,1)"
+        ]
+    },
+    "eccharts_grey_white_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "grey",
+            "white",
+            "eccharts",
+            "snow_1to1000_whi",
+            "Snow depth"
+        ],
+        "values" : [
+            "rgb(0.64,0.64,0.64)",
+            "rgb(0.7,0.7,0.7)",
+            "rgb(0.76,0.76,0.76)",
+            "rgb(0.82,0.82,0.82)",
+            "rgb(0.88,0.88,0.88)",
+            "rgb(0.94,0.94,0.94)",
+            "rgb(1,1,1)"
+        ]
+    },
+    "eccharts_blue_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "blue",
+            "transparent",
+            "eccharts",
+            "transparency_100_blue"
+        ],
+        "values" : [
+            "none",
+            "rgba(0,0,1,0)",
+            "rgba(0,0,1,0.1)",
+            "rgba(0,0,1,0.2)",
+            "rgba(0,0,1,0.3)",
+            "rgba(0,0,1,0.4)",
+            "rgba(0,0,1,0.5)",
+            "rgba(0,0,1,0.6)",
+            "rgba(0,0,1,0.7)",
+            "rgba(0,0,1,0.8)",
+            "rgba(0,0,1,0.9)",
+            "rgba(0,0,1,1)"
+        ]
+    },
+    "eccharts_red_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "red",
+            "transparent",
+            "transparency_100_red"
+        ],
+        "values" : [
+            "none",
+            "rgba(1,0,0,0)",
+            "rgba(1,0,0,0.1)",
+            "rgba(1,0,0,0.2)",
+            "rgba(1,0,0,0.3)",
+            "rgba(1,0,0,0.4)",
+            "rgba(1,0,0,0.5)",
+            "rgba(1,0,0,0.6)",
+            "rgba(1,0,0,0.7)",
+            "rgba(1,0,0,0.8)",
+            "rgba(1,0,0,0.9)",
+            "rgba(1,0,0,1)"
+        ]
+    },
+    "eccharts_black_transparent_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "eccharts",
+            "transparent",
+            "black",
+            "transparency_black"
+        ],
+        "values" : [
+            "rgba(0,0,0,0)",
+            "rgba(0,0,0,0.1)",
+            "rgba(0,0,0,0.2)",
+            "rgba(0,0,0,0.3)",
+            "rgba(0,0,0,0.4)",
+            "rgba(0,0,0,0.5)",
+            "rgba(0,0,0,0.6)",
+            "rgba(0,0,0,0.7)",
+            "rgba(0,0,0,0.8)",
+            "rgba(0,0,0,0.9)",
+            "rgba(0,0,0,1)"
+        ]
+    },
+    "eccharts_darkgrey_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "transparent",
+            "darkgrey",
+            "transparency_darkgrey"
+        ],
+        "values" : [
+            "none",
+            "rgba(0.5,0.5,0.5,0)",
+            "rgba(0.5,0.5,0.5,0.1)",
+            "rgba(0.5,0.5,0.5,0.2)",
+            "rgba(0.5,0.5,0.5,0.3)",
+            "rgba(0.5,0.5,0.5,0.4)",
+            "rgba(0.5,0.5,0.5,0.5)",
+            "rgba(0.5,0.5,0.5,0.6)",
+            "rgba(0.5,0.5,0.5,0.7)",
+            "rgba(0.5,0.5,0.5,0.8)",
+            "rgba(0.5,0.5,0.5,0.9)",
+            "rgba(0.5,0.5,0.5,1)"
+        ]
+    },
+    "eccharts_grey_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "transparent",
+            "grey",            
+            "transparency_grey"
+        ],
+        "values" : [
+            "none",
+            "rgba(0.66,0.66,0.66,0)",
+            "rgba(0.66,0.66,0.66,0.1)",
+            "rgba(0.66,0.66,0.66,0.2)",
+            "rgba(0.66,0.66,0.66,0.3)",
+            "rgba(0.66,0.66,0.66,0.4)",
+            "rgba(0.66,0.66,0.66,0.5)",
+            "rgba(0.66,0.66,0.66,0.6)",
+            "rgba(0.66,0.66,0.66,0.7)",
+            "rgba(0.66,0.66,0.66,0.8)",
+            "rgba(0.66,0.66,0.66,0.9)",
+            "rgba(0.66,0.66,0.66,1)"
+        ]
+    },
+    "eccharts_lightgrey_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "transparent",
+            "lightgrey",            
+            "transparency_lightgrey"
+        ],
+        "values" : [
+            "none",
+            "rgba(0.8,0.8,0.8,0)",
+            "rgba(0.8,0.8,0.8,0.1)",
+            "rgba(0.8,0.8,0.8,0.2)",
+            "rgba(0.8,0.8,0.8,0.3)",
+            "rgba(0.8,0.8,0.8,0.4)",
+            "rgba(0.8,0.8,0.8,0.5)",
+            "rgba(0.8,0.8,0.8,0.6)",
+            "rgba(0.8,0.8,0.8,0.7)",
+            "rgba(0.8,0.8,0.8,0.8)",
+            "rgba(0.8,0.8,0.8,0.9)",
+            "rgba(0.8,0.8,0.8,1)"
+        ]
+    },
+    "eccharts_white_transparent_12" : {
+        "n_colours" : "12",
+        "tags" : [
+            "12",
+            "eccharts",
+            "transparent",
+            "white",
+            "transparency_white"
+        ],
+        "values" : [
+            "none",
+            "rgba(1,1,1,0)",
+            "rgba(1,1,1,0.1)",
+            "rgba(1,1,1,0.2)",
+            "rgba(1,1,1,0.3)",
+            "rgba(1,1,1,0.4)",
+            "rgba(1,1,1,0.5)",
+            "rgba(1,1,1,0.6)",
+            "rgba(1,1,1,0.7)",
+            "rgba(1,1,1,0.8)",
+            "rgba(1,1,1,0.9)",
+            "rgba(1,1,1,1)"
+        ]
+    },
+    "eccharts_blue_red3_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "eccharts",
+            "www_2t_anomaly",
+            "Extended range: 2m temperature weekly mean anomaly",
+            "Extended range: surface temperature weekly mean anomaly",
+            "surface temperature anomaly",
+            "2m T anomaly",
+            "tempearature",
+            "tempearature anomaly",
+            "anomaly"
+        ],
+        "values" : [
+            "rgb(0,59,89)",
+            "rgb(0,120,179)",
+            "rgb(48,186,255)",
+            "rgb(153,220,255)",
+            "rgb(204,238,255)",
+            "rgb(255,212,204)",
+            "rgb(255,170,153)",
+            "rgb(255,82,51)",
+            "rgb(179,27,0)",
+            "rgb(89,12,0)"
+        ]
+    },
+    "eccharts_yellow_blue_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "yellow",
+            "blue",
+            "eccharts",
+            "www_850ws"
+        ],
+        "values" : [
+            "rgb(255,255,51)",
+            "rgb(201,255,25)",
+            "rgb(133,242,23)",
+            "rgb(23,230,54)",
+            "rgb(19,191,134)",
+            "rgb(15,153,153)",
+            "rgb(15,107,153)",
+            "rgb(16,61,153)",
+            "rgb(10,10,102)"
+        ]
+    },
+    "eccharts_rainbow_red_purple_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "rainbow",
+            "red",
+            "purple",
+            "eccharts",
+            "www_genesis_probability"
+        ],
+        "values" : [
+            "rgb(245,0,80)",
+            "rgb(255,102,0)",
+            "rgb(255,166,0)",
+            "rgb(242,242,0)",
+            "rgb(195,227,23)",
+            "rgb(91,226,71)",
+            "rgb(0,203,217)",
+            "rgb(28,142,255)",
+            "rgb(21,94,230)",
+            "rgb(115,0,230)"
+        ]
+    },
+    "eccharts_green_purple_10" : {
+        "n_colours" : "10",
+        "tags" : [
+            "10",
+            "green",
+            "purple",
+            "eccharts",
+            "www_mslp_anomaly",
+            "precipitation anomaly",
+            "precipitation",
+            "anomaly"
+        ],
+        "values" : [
+            "rgb(0,74,74)",
+            "rgb(0,128,128)",
+            "rgb(18,179,179)",
+            "rgb(161,230,230)",
+            "rgb(207,255,255)",
+            "rgb(255,217,242)",
+            "rgb(255,166,225)",
+            "rgb(230,69,176)",
+            "rgb(179,0,119)",
+            "rgb(77,0,51)"
+        ]
+    },
+    "eccharts_blue_11" : {
+        "n_colours" : "11",
+        "tags" : [
+            "11",
+            "blue",
+            "eccharts",
+            "www_mwp",
+            "Mean wave direction and height",
+            "wawe"
+        ],
+        "values" : [
+            "rgb(242,250,239)",
+            "rgb(216,237,232)",
+            "rgb(179,223,226)",
+            "rgb(130,192,215)",
+            "rgb(76,157,210)",
+            "rgb(33,128,192)",
+            "rgb(39,93,163)",
+            "rgb(54,71,127)",
+            "rgb(51,50,92)",
+            "rgb(35,34,65)",
+            "rgb(25,18,36)"
+        ]
+    },
+    "eccharts_brown_green_9" : {
+        "n_colours" : "9",
+        "tags" : [
+            "9",
+            "brown",
+            "green",
+            "eccharts",
+            "www_rain_anomaly",
+            "Extended range: precipitation weekly mean anomaly",
+            "weekly precipitation anomaly",
+            "precipitation anomaly",
+            "precipitation",
+            "anomaly"
+        ],
+        "values" : [
+            "rgb(89,45,0)",
+            "rgb(176,88,0)",
+            "rgb(255,128,0)",
+            "rgb(255,179,102)",
+            "rgb(255,217,179)",
+            "rgb(219,242,170)",
+            "rgb(184,230,92)",
+            "rgb(136,204,0)",
+            "rgb(102,153,0)",
+            "rgb(59,89,0)"
+        ]
+    },
+    "eccharts_blue_purple_7" : {
+        "n_colours" : "7",
+        "tags" : [
+            "7",
+            "blue",
+            "purple",
+            "eccharts",
+            "www_tp_interval",
+            "total precipitation",
+            "tp"
+        ],
+        "values" : [
+            "rgb(173,230,230)",
+            "rgb(140,209,230)",
+            "rgb(137, 184, 230)",
+            "rgb(122,152,204)",
+            "rgb(114,114,191)",
+            "rgb(96,83,166)",
+            "rgb(83,38,128)"
+        ]
+    },
+    "eccharts_green_magenta_transparent_6" : {
+        "n_colours" : "6",
+        "tags" : [
+            "6",
+            "eccharts",
+            "transparent",
+            "green",
+            "magenta",
+            "www_transparent_rainprob",
+            "probability",
+            "Maximum 2 metre temperature probability",
+            "Minimum 2 metre temperature probability",
+            "2m temperature probability",
+            "2m temperature weighted probability",
+            "2 metre dew point temperature probability",
+            "Stratiform precipitation probability",
+            "Stratiform precipitation rate probability",
+            "Convective precipitation probability",
+            "Convective precipitation rate probability",
+            "Total precipitation probability",
+            "Total precipitation rate probability",
+            "Total precipitation weighted probability",
+            "Total snowfall probability",
+            "Total snowfall rate probability",
+            "Visibility probability",
+            "10m wind gusts probability",
+            "10m wind probability",
+            "10m wind speed weighted probability",
+            "Convective available potential energy (CAPE) probability",
+            "Mean wave period probability",
+            "Significant wave height probability",
+            "Probability of combined events of 10 metre wind speed and significant wave height",
+            "Probability of combined events of wind gust and total snowfall",
+            "Probability of combined events of wind speed and total precipitation",
+            "Probability of combined events of 2 metre Temperature and total precipitation"            
+        ],
+        "values" : [
+            "rgba(0.48,0.82,0.78,0.38)",
+            "rgba(0.42,0.79,0.27,0.38)",
+            "rgba(0.83,0.85,0.2,0.38)",
+            "rgba(0.9,0.64,0.23,0.38)",
+            "rgba(0.97,0.43,0.43,0.38)",
+            "rgba(1,0.0039,1,0.38)"
+        ]
+    },
+    "norway_lightblue": {
+        "n_colours" : "13",
+        "values": ["rgb(245,245,255)", 
+                   "rgb(235,235,255)", 
+                   "rgb(225,225,255)", 
+                   "rgb(215,215,255)", 
+                   "rgb(200,200,255)", 
+                   "rgb(175,175,255)", 
+                   "rgb(150,150,255)", 
+                   "rgb(125,125,255)", 
+                   "rgb(100,100,255)", 
+                   "rgb(75,75,255)", 
+                   "rgb(50,50,255)", 
+                   "rgb(25,25,255)", 
+                   "rgb(0,0,255)"],
+        "tags": [
+            "norway",
+            "blue",
+            "13",
+            "diverging"
+        ]
+    }, 
+    "norway_lightblue_rev": {
+        "n_colours" : "13",
+        "values": ["rgb( 0,0,255)",
+                   "rgb(25,25,255)", 
+                   "rgb(50,50,255)", 
+                   "rgb(75,75,255)", 
+                   "rgb(100,100,255)", 
+                   "rgb(125,125,255)", 
+                   "rgb(150,150,255)", 
+                   "rgb(175,175,255)", 
+                   "rgb(200,200,255)", 
+                   "rgb(215,215,255)", 
+                   "rgb(225,225,255)", 
+                   "rgb(235,235,255)",
+                   "rgb(245,245,255)"],
+        "tags": [
+            "norway",
+            "blue",
+            "13",
+            "diverging"
+        ]
+    }, 
+    "norway_darkblue": {
+        "n_colours" : "13",
+        "values": ["rgb( 0,0,255)",
+                   "rgb(0,0,245)", 
+                   "rgb(0,0,235)", 
+                   "rgb(0,0,225)", 
+                   "rgb(0,0,215)", 
+                   "rgb(0,0,200)", 
+                   "rgb(0,0,175)", 
+                   "rgb(0,0,150)", 
+                   "rgb(0,0,125)", 
+                   "rgb(0,0,100)", 
+                   "rgb(0,0,75)", 
+                   "rgb(0,0,50)", 
+                   "rgb(0,0,25)"],
+        "tags": [
+            "norway",
+            "blue",
+            "13",
+            "diverging"
+        ]
+    },
+    "norway_darkblue_rev": {
+        "n_colours" : "13",
+        "values": ["rgb(0,0,25)", 
+                   "rgb(0,0,50)", 
+                   "rgb(0,0,75)", 
+                   "rgb(0,0,100)", 
+                   "rgb(0,0,125)", 
+                   "rgb(0,0,150)", 
+                   "rgb(0,0,175)", 
+                   "rgb(0,0,200)", 
+                   "rgb(0,0,215)", 
+                   "rgb(0,0,225)", 
+                   "rgb(0,0,235)", 
+                   "rgb(0,0,245)", 
+                   "rgb(0,0,255)"],
+        "tags": [
+            "norway",
+            "blue",
+            "13",
+            "diverging"
+        ]
+    },
+    "norway_lightred": {
+        "n_colours" : "13",
+        "values": ["rgb(255,245,245)", 
+                     "rgb(255,235,235)", 
+                     "rgb(255,225,225)", 
+                     "rgb(255,215,215)", 
+                     "rgb(255,200,200)", 
+                     "rgb(255,175,175)", 
+                     "rgb(255,150,150)", 
+                     "rgb(255,125,125)", 
+                     "rgb(255,100,100)", 
+                     "rgb(255,75,75)", 
+                     "rgb(255,50,50)", 
+                     "rgb(255,25,25)", 
+                     "rgb(255,0,0)"],
+        "tags": [
+            "norway",
+            "red",
+            "13",
+            "diverging"
+        ]
+    },       
+    "norway_green_7": {
+        "n_colours" : "7",
+        "values": ["rgb(200,255,178)", 
+                   "rgb(178,235,154)", 
+                   "rgb(154,215,130)", 
+                   "rgb(130,200,109)", 
+                   "rgb(109,175,83)", 
+                   "rgb(64,135,35)", 
+                   "rgb(40,115,20)"],
+        "tags": [
+            "norway",
+            "green",
+            "7",
+            "diverging"
+        ]
+    },        
+    "norway_orange_7": {
+        "n_colours" : "7",
+        "values": ["rgb(255,255,230)", 
+                   "rgb(255,235,200)", 
+                   "rgb(255,215,170)", 
+                   "rgb(255,195,140)", 
+                   "rgb(255,175,110)", 
+                   "rgb(255,155,70)",
+                   "rgb(255,135,40)"],
+        "tags": [
+            "norway",
+            "orange",
+            "7",
+            "diverging"
+        ]
+    },    
+    "norway_blue_red_16": {
+        "n_colours" : "16",
+        "values": ["rgb(32,96,255)", 
+                   "rgb(32,159,255)", 
+                   "rgb(32,191,255)", 
+                   "rgb(0,207,255)", 
+                   "rgb(42,255,255)", 
+                   "rgb(85,255,255)", 
+                   "rgb(127,255,255)", 
+                   "rgb(170,255,255)", 
+                   "rgb(255,255,84)", 
+                   "rgb(255,240,0)", 
+                   "rgb(255,191,0)", 
+                   "rgb(255,168,0)", 
+                   "rgb(255,138,0)", 
+                   "rgb(255,112,0)", 
+                   "rgb(255,77,0)", 
+                   "rgb(255,0,0)"],
+        "tags": [
+            "norway",
+            "red",
+            "yellow",
+            "blue",
+            "16",
+            "diverging"
+        ]
+    },    
+    "norway_rainbow_purple_magenta_25": {
+        "n_colours" : "25",
+        "values": ["rgb(151,151,255)", 
+                   "rgb(100,100,255)", 
+                   "rgb(0,0,255)", 
+                   "rgb(0,28,192)", 
+                   "rgb(0,55,128)", 
+                   "rgb(0,83,64)", 
+                   "rgb(0,110,0)", 
+                   "rgb(0,159,0)", 
+                   "rgb(0,207,0)", 
+                   "rgb(0,255,0)", 
+                   "rgb(137,255,27)", 
+                   "rgb(203,255,53)", 
+                   "rgb(255,255,63)", 
+                   "rgb(245,230,50)", 
+                   "rgb(233,205,38)", 
+                   "rgb(222,179,25)", 
+                   "rgb(211,154,13)", 
+                   "rgb(200,128,0)", 
+                   "rgb(218,85,0)", 
+                   "rgb(237,43,0)", 
+                   "rgb(255,0,0)", 
+                   "rgb(195,0,0)", 
+                   "rgb(129,0,47)", 
+                   "rgb(195,0,129)", 
+                   "rgb(255,0,255)"],
+        "tags": [
+            "norway",
+            "sst",
+            "25",
+            "rainbow",
+            "purple",
+            "magenta"
+        ]
+    },    
+    "norway_yellow_red_9": {
+        "n_colours" : "9",
+        "values": ["rgb(255,255,255)", 
+                   "rgb(255,255,150)", 
+                   "rgb(255,255,84)", 
+                   "rgb(255,240,0)", 
+                   "rgb(255,191,0)", 
+                   "rgb(255,168,0)", 
+                   "rgb(255,138,0)", 
+                   "rgb(255,112,0)", 
+                   "rgb(255,77,0)"],
+    "tags": [
+            "norway",
+            "yellow",
+            "red",
+            "9"
+        ]
+    },    
+    "norway_green_navy_5": {
+        "n_colours" : "5",
+        "values": ["rgb(220,240,220)", 
+                   "rgb(6,205,128)", 
+                   "rgb(46,139,87)", 
+                   "rgb(85,107,47)", 
+                   "rgb(30,0,139)"],
+        "tags": [
+            "norway",
+            "green",
+            "navy",
+            "5",
+            "categorical"
+        ]
+    },    
+    "norway_green_brown_9": {
+        "n_colours" : "9",
+        "values": ["rgb( 178,235,154)", 
+                   "rgb(200,255,178)", 
+                   "rgb(255,255,230)", 
+                   "rgb(255,235,200)", 
+                   "rgb(255,215,170)", 
+                   "rgb(255,195,140)", 
+                   "rgb(255,175,110)", 
+                   "rgb(255,155,70)", 
+                   "rgb(255,135,40)"],
+        "tags": [
+            "norway",
+            "topography",
+            "orography",
+            "green",
+            "browns",
+            "9",
+            "diverging"
+        ]
+    },
+    "norway_light_rainbow_blue_red1_11": {
+        "n_colours" : "11",
+        "values": ["rgb(230,250,255)", 
+                   "rgb(230,255,255)", 
+                   "rgb(230,255,250)", 
+                   "rgb(230,255,242)", 
+                   "rgb(230,255,230)", 
+                   "rgb(242,255,230)", 
+                   "rgb(250,255,230)", 
+                   "rgb(255,255,230)", 
+                   "rgb(255,246,230)", 
+                   "rgb(255,238,230)", 
+                   "rgb(255,230,230)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "11",
+            "diverging"
+        ]
+    },
+    "norway_light_rainbow_blue_red2_11": {
+        "n_colours" : "11",
+            "values": ["rgb(204,245,255)", 
+                       "rgb(204,255,255)", 
+                       "rgb(204,255,245)", 
+                       "rgb(204,255,230)", 
+                       "rgb(204,255,204)", 
+                       "rgb(230,255,204)", 
+                       "rgb(245,255,204)", 
+                       "rgb(255,255,204)", 
+                       "rgb(255,238,204)", 
+                       "rgb(255,221,204)", 
+                       "rgb(255,204,204)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "11",
+            "diverging"
+        ]
+    },
+    "norway_light_rainbow_blue_red3_11": {
+        "n_colours" : "11",
+        "values": ["rgb(178,240,255)", 
+                   "rgb(178,255,255)", 
+                   "rgb(178,255,240)", 
+                   "rgb(178,255,218)", 
+                   "rgb(178,255,178)", 
+                   "rgb(218,255,178)", 
+                   "rgb(240,255,178)", 
+                   "rgb(255,255,178)", 
+                   "rgb(255,230,178)", 
+                   "rgb(255,205,178)", 
+                   "rgb(255,178,178)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "11",
+            "diverging"
+        ]
+    },
+    "norway_light_rainbow_blue_red4_11": {
+        "n_colours" : "11",
+        "values": ["rgb(153,235,255)", 
+                   "rgb(153,255,255)", 
+                   "rgb(153,255,235)", 
+                   "rgb(153,255,206)", 
+                   "rgb(153,255,153)", 
+                   "rgb(206,255,153)", 
+                   "rgb(235,255,153)", 
+                   "rgb(255,255,153)", 
+                   "rgb(255,222,153)", 
+                   "rgb(255,188,153)", 
+                   "rgb(255,153,153)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "11",
+            "diverging"
+        ]
+    },
+    "norway_light_rainbow_blue_red5_11": {
+        "n_colours" : "11",
+        "values": ["rgb(128,230,255)",
+                   "rgb(128,255,255)",
+                   "rgb(128,255,230)",
+                   "rgb(128,255,194)",
+                   "rgb(128,255,128)",
+                   "rgb(194,255,128)",
+                   "rgb(230,255,128)",
+                   "rgb(255,255,128)",
+                   "rgb(255,214,128)",
+                   "rgb(255,171,128)",
+                   "rgb(255,128,128)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "11",
+            "diverging"
+        ]
+    },
+    "norway_blue_purple_13": {
+        "n_colours" : "13",
+        "values": ["rgb(217,255,255)",
+                   "rgb(179,255,255)",
+                   "rgb(128,235,255)",
+                   "rgb(64,204,255)",
+                   "rgb(67,178,252)",
+                   "rgb(0 ,153,255)",
+                   "rgb(0 ,100,255)",
+                   "rgb(0 ,25,255)",
+                   "rgb(0,25,200)",
+                   "rgb(102,25,102)",
+                   "rgb(174,0,95)",
+                   "rgb(214,0,119)",
+                   "rgb(228,35,157)"],
+        "tags": [
+            "norway",
+            "temperature",
+            "cold",
+            "blue",
+            "purple",
+            "13",
+            "diverging"
+        ]
+    },    
+    "norway_yellow_red2_12": {
+        "n_colours" : "12",
+        "values": ["rgb(250,255,195)",
+                   "rgb(253,253,161)",
+                   "rgb(255,255,112)",
+                   "rgb(255,230,77)",
+                   "rgb(255,215,0)",
+                   "rgb(255,179,0)",
+                   "rgb(255,140,0)",
+                   "rgb(255,102,0)",
+                   "rgb(255,63,0)",
+                   "rgb(255,25,0)",
+                   "rgb(204,0,0)",
+                   "rgb(170,0,0)"],
+        "tags": [
+            "norway",
+            "temperature",
+            "warm",
+            "yellow",
+            "red",
+            "12",
+            "diverging"
+        ]
+    },
+    "norway_blue_8": {
+        "n_colours" : "8",
+        "values": ["rgb(229,229,229)",
+                   "rgb(217,255,255)",
+                   "rgb(179,255,255)",
+                   "rgb(128,235,255)",
+                   "rgb(64,204,255)",
+                   "rgb(0,153,255)",
+                   "rgb(0,25,255)",
+                   "rgb(0,0,153)"],
+        "tags": [
+            "norway",
+            "precipitation",
+            "blue",
+            "8",
+            "diverging"
+        ]
+    },    
+    "norway_categorical1_8": {
+        "n_colours" : "8",
+        "values": ["rgb(78,180,0)",
+                   "rgb(0,255,255)",
+                   "rgb(178,51,0)",
+                   "rgb(255,0,0)",
+                   "rgb(247,228,0)",
+                   "rgb(160,32,240)",
+                   "rgb(160,206,0)",
+                   "rgb(0,0,255)"],
+        "tags": [
+            "norway",
+            "categorical",
+            "8"
+        ]
+    },  
+    "norway_rainbow_purple_red_10": {
+        "n_colours" : "10",
+        "values": ["rgb(215,222,255)",
+                   "rgb(191,228,255)",
+                   "rgb(167,255,255)",
+                   "rgb(119,255,137)",
+                   "rgb(69,225,82)",
+                   "rgb(0,200,0)",
+                   "rgb(225,225,0)",
+                   "rgb(255,124,23)",
+                   "rgb(255,0,0)",
+                   "rgb(180,0,0)"],
+        "tags": [
+            "norway",
+            "rainbow",
+            "precipitation",
+            "meteoalarm",
+            "green",
+            "yellow",
+            "red",
+            "orange",
+            "10"
+        ]
+    },  
+    "norway_blue_maroon_12": {
+        "n_colours" : "12",
+        "values": ["rgb(128,235,255)",
+                   "rgb(89,204,255)",
+                   "rgb(50,162,255)",
+                   "rgb(12,107,255)",
+                   "rgb(1,64,229)",
+                   "rgb(1,34,193)",
+                   "rgb(2,12,156)",
+                   "rgb(17,2,134)",
+                   "rgb(54,1,135)",
+                   "rgb(92,1,135)",
+                   "rgb(131,0,136)",
+                   "rgb(136,0,102)"],
+        "tags": [
+            "norway",
+            "precipitation",
+            "blue",
+            "12",
+            "diverging"
+        ]
+    },  
+    "norway_purple_18": {
+        "n_colours" : "18",
+        "values": ["rgb(252,251,253)",
+                   "rgb(228,215,240)",
+                   "rgb(204,182,227)",
+                   "rgb(182,152,213)",
+                   "rgb(161,124,200)",
+                   "rgb(141,98,187)",
+                   "rgb(122,75,174)",
+                   "rgb(105,54,160)",
+                   "rgb(89,36,147)",
+                   "rgb(74,20,134)",
+                   "rgb(51,0,152)",
+                   "rgb(255,102,255)",
+                   "rgb(255,51,255)",
+                   "rgb(204,51,204)",
+                   "rgb(204,0,204)",
+                   "rgb(153,0,153)",
+                   "rgb(102,0,102)",
+                   "rgb(51,0,51)"],
+        "tags": [
+            "norway",
+            "wawe_height",
+            "purple",
+            "18",
+            "diverging"
+        ]
+    },   
+    "norway_cyan_orange_27": {
+        "n_colours" : "27",
+        "values":["rgb(0,4,42)",
+                   "rgb(0,4,43)",
+                   "rgb(0,4,44)",
+                   "rgb(0,29,64)",
+                   "rgb(0,53,85)",
+                   "rgb(0,78,105)",
+                   "rgb(0,102,126)",
+                   "rgb(0,127,146)",
+                   "rgb(0,152,167)",
+                   "rgb(0,176,187)",
+                   "rgb(0,201,207)",
+                   "rgb(0,225,228)",
+                   "rgb(43,243,235)",
+                   "rgb(149,249,223)",
+                   "rgb(255,255,210)",
+                   "rgb(255,255,166)",
+                   "rgb(255,255,122)",
+                   "rgb(255,255,79)",
+                   "rgb(255,255,35)",
+                   "rgb(253,249,0)",
+                   "rgb(241,216,0)",
+                   "rgb(229,184,0)",
+                   "rgb(218,152,0)",
+                   "rgb(206,120,0)",
+                   "rgb(194,88,0)",
+                   "rgb(183,56,0)",
+                   "rgb(171,24,0)"],
+        "tags": [
+            "norway",
+            "sst",
+            "sea surface temperature",
+            "cyan",
+            "orange",
+            "27",
+            "diverging"
+        ]
+    },    
+    "norway_cyan_purple_12": {
+        "n_colours" : "12",
+        "values":["rgb(128,235,255)",
+                   "rgb(96,219,255)",
+                   "rgb(64,204,255)",
+                   "rgb(32,178,255)",
+                   "rgb(0,153,255)",
+                   "rgb(0,89,255)",
+                   "rgb(0,25,255)",
+                   "rgb(0,0,204)",
+                   "rgb(0,0,153)",
+                   "rgb(64,0,153)",
+                   "rgb(128,0,153)",
+                   "rgb(192,0,153)"],
+        "tags": [
+            "norway",
+            "cyan",
+            "purple",
+            "blue",
+            "12",
+            "diverging"
+        ]
+    },     
+    "norway_rainbow_purple_red_11": {
+        "n_colours" : "11",
+        "values":["rgb(210,140,240)",
+                   "rgb(215,200,245)",
+                   "rgb(190,230,250)",
+                   "rgb(165,255,255)",
+                   "rgb(120,255,135)",
+                   "rgb(70,225,80)",
+                   "rgb(0,200,0)",
+                   "rgb(225,225,0)",
+                   "rgb(255,125,0)",
+                   "rgb(255,20,20)",
+                   "rgb(160,0,0)"],
+        "tags": [
+            "norway",
+            "green",
+            "purple",
+            "red",
+            "11",
+            "diverging"
+        ]
+    },    
+    "norway_rainbow1_37": {
+        "n_colours" : "37",
+        "values":["rgb(0.16,0,0.16)",
+                  "rgb(0.28,0,0.28)",
+                  "rgb(0.39,0,0.39)",
+                  "rgb(0.51,0,0.51)",
+                  "rgb(0.63,0,0.63)",
+                  "rgb(0.78,0,0.78)",
+                  "rgb(0.82,0,1)",
+                  "rgb(0.67,0,1)",
+                  "rgb(0.51,0,1)",
+                  "rgb(0.35,0,1)",
+                  "rgb(0,0.2,1)",
+                  "rgb(0,0.39,1)",
+                  "rgb(0,0.59,1)",
+                  "rgb(0,0.78,1)",
+                  "cyan",
+                  "rgb(0.16,0.9,0.63)",
+                  "rgb(0.27,0.9,0.47)",
+                  "rgb(0.39,0.90,0.31)",
+                  "rgb(0.51,0.94,0.16)",
+                  "rgb(0.63,0.98,0)",
+                  "rgb(1,1,0)",
+                  "rgb(1,0.88,0)",
+                  "rgb(1,0.78,0)",
+                  "rgb(1,0.69,0)",
+                  "rgb(1,0.59,0)",
+                  "rgb(0.9,0.49,0)",
+                  "rgb(0.9,0.39,0)",
+                  "rgb(0.86,0.29,0.12)",
+                  "rgb(0.78,0.2,0.12)",
+                  "rgb(0.71,0.1,0.12)",
+                  "rgb(0.67,0,0.12)",
+                  "rgb(0.71,0,0.20)",
+                  "rgb(0.78,0,0.39)",
+                  "rgb(1,0,0.59)",
+                  "rgb(1,0,0.78)",
+                  "rgb(1,0,0.88)",
+                  "rgb(1,0,0.98)"],
+        "tags": [
+            "rainbow",
+            "temperature",
+            "37",
+            "diverging"
+        ]
+    }        
+}
diff --git a/share/magics/table_128.xml b/share/magics/table_128.xml
index bd732ad..401bb8f 100644
--- a/share/magics/table_128.xml
+++ b/share/magics/table_128.xml
@@ -163,42 +163,6 @@ does it submit to any jurisdiction.
         <param code='251' 
                original_unit='K' derived_unit='deg C' 
                scaling='1.0' offset='-273.16'/> 
-        <param code='20000' 
-               original_unit='kg m**-3' derived_unit='ng m**-3' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20001' 
-               original_unit='kg m**-2' derived_unit='ng m**-2' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20002' 
-               original_unit='kg kg**-1' derived_unit='ppt' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20052' 
-               original_unit='mol mol**-1' derived_unit='ppt' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20197' 
-               original_unit='kg m**-2' derived_unit='ng m**-2' 
-               scaling='100000000000.0' offset='-0.0'/>
-        <param code='20198' 
-               original_unit='kg m**-2' derived_unit='ng m**-2' 
-               scaling='100000000000.0' offset='-0.0'/>
-        <param code='20199' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20200' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20201' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20202' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20203' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
-        <param code='20204' 
-               original_unit='kg m**-2 s**-1' derived_unit='ng m**-2 s**-1' 
-               scaling='1000000000000.0' offset='-0.0'/>
         <param code='260510' 
                original_unit='K' derived_unit='deg c' 
                scaling='1.0' offset='-273.16'/> 
diff --git a/src/params/ObsCloud.xml b/share/magics/table_228.xml
similarity index 63%
copy from src/params/ObsCloud.xml
copy to share/magics/table_228.xml
index 879d3a1..ff1701e 100644
--- a/src/params/ObsCloud.xml
+++ b/share/magics/table_228.xml
@@ -1,16 +1,17 @@
-<magics>
-<class directory="visualisers" action_routine="pobs" prefix="obs" xmltag="cloud" name="ObsCloud">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
 This software is licensed under the terms of the Apache Licence Version 2.0
-which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-In applying this licence, ECMWF does not waive the privileges and immunities 
+which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+In applying this licence, ECMWF does not waive the privileges and immunities
 granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-
-    	
-    	</parameter>    
-</class></magics>
+<centre code='98'>
+    <table code='228'>
+        <param code='216' 
+               original_unit='m' derived_unit='mm' 
+               scaling='1000.0' offset='-0.0'/> 
+    </table>
+<centre/>
diff --git a/share/projections.json b/share/projections.json
new file mode 100644
index 0000000..4f65977
--- /dev/null
+++ b/share/projections.json
@@ -0,0 +1,214 @@
+{
+    "north_pole": {
+        "subpage_lower_left_longitude": -45.0, 
+        "subpage_upper_right_longitude": 135.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 9.0, 
+        "subpage_lower_left_latitude": 9.0
+    }, 
+    "eurasia": {
+        "subpage_upper_right_longitude": 168, 
+        "subpage_upper_right_latitude": 31, 
+        "subpage_lower_left_longitude": 50, 
+        "subpage_vertical_longitude": 80, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 17
+    }, 
+    "global": {
+        "subpage_lower_left_longitude": -180.0, 
+        "subpage_upper_right_longitude": 180.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 90.0, 
+        "subpage_lower_left_latitude": -90.0
+    }, 
+    "south_west_europe": {
+        "subpage_lower_left_longitude": -15.0, 
+        "subpage_upper_right_longitude": 20.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 50.0, 
+        "subpage_lower_left_latitude": 27.0
+    }, 
+    "east_tropic": {
+        "subpage_lower_left_longitude": 0.0, 
+        "subpage_upper_right_longitude": 179.9, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 35.0, 
+        "subpage_lower_left_latitude": -35.0
+    }, 
+    "south_east_europe": {
+        "subpage_lower_left_longitude": 4.0, 
+        "subpage_upper_right_longitude": 49.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 40.0, 
+        "subpage_lower_left_latitude": 29.0
+    }, 
+    "south_east_asia_and_indonesia": {
+        "subpage_lower_left_longitude": 79.5, 
+        "subpage_upper_right_longitude": 164.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 30.5, 
+        "subpage_lower_left_latitude": -18.0
+    }, 
+    "northern_africa": {
+        "subpage_lower_left_longitude": -18.21, 
+        "subpage_upper_right_longitude": 60.67, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 38.46, 
+        "subpage_lower_left_latitude": 0.0
+    }, 
+    "antarctic": {
+        "subpage_upper_right_longitude": 45.0, 
+        "subpage_upper_right_latitude": -42.0, 
+        "subpage_lower_left_longitude": -135.0, 
+        "subpage_map_hemisphere": "south", 
+        "subpage_vertical_longitude": 180, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": -42.0
+    }, 
+    "central_europe": {
+        "subpage_lower_left_longitude": -6.0, 
+        "subpage_upper_right_longitude": 26.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 54.0, 
+        "subpage_lower_left_latitude": 40.0
+    }, 
+    "southern_asia": {
+        "subpage_upper_right_longitude": 140, 
+        "subpage_upper_right_latitude": 30, 
+        "subpage_lower_left_longitude": 61, 
+        "subpage_vertical_longitude": 80, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 1.0
+    }, 
+    "south_america": {
+        "subpage_lower_left_longitude": -89.3, 
+        "subpage_upper_right_longitude": -32.5, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 13.0, 
+        "subpage_lower_left_latitude": -56.0
+    }, 
+    "north_east_europe": {
+        "subpage_lower_left_longitude": 2.0, 
+        "subpage_upper_right_longitude": 68.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 50.0, 
+        "subpage_lower_left_latitude": 46.0
+    }, 
+    "southern_africa": {
+        "subpage_lower_left_longitude": 3.7, 
+        "subpage_upper_right_longitude": 51.4, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 6.4, 
+        "subpage_lower_left_latitude": -35.2
+    }, 
+    "north_west_europe": {
+        "subpage_lower_left_longitude": -18.0, 
+        "subpage_upper_right_longitude": 40.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 70.0, 
+        "subpage_lower_left_latitude": 44.0
+    }, 
+    "europe": {
+        "subpage_lower_left_longitude": -15.0, 
+        "subpage_upper_right_longitude": 68.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 50.0, 
+        "subpage_lower_left_latitude": 27.0
+    }, 
+    "arctic": {
+        "subpage_lower_left_longitude": -45.0, 
+        "subpage_upper_right_longitude": 135.0, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_upper_right_latitude": 42.0, 
+        "subpage_lower_left_latitude": 42.0
+    }, 
+    "central_america": {
+        "subpage_lower_left_longitude": -121.0, 
+        "subpage_upper_right_longitude": -53.5, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 36.0, 
+        "subpage_lower_left_latitude": -5.0
+    }, 
+    "pacific": {
+        "subpage_lower_left_longitude": 109.0, 
+        "subpage_upper_right_longitude": 296.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 69.0, 
+        "subpage_lower_left_latitude": -69.0
+    }, 
+    "eastern_asia": {
+        "subpage_upper_right_longitude": 178.2, 
+        "subpage_upper_right_latitude": 60.2, 
+        "subpage_lower_left_longitude": 92.8, 
+        "subpage_vertical_longitude": 118.6, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 15.8
+    }, 
+    "middle_east_and_india": {
+        "subpage_lower_left_longitude": 29.0, 
+        "subpage_upper_right_longitude": 94.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 40.5, 
+        "subpage_lower_left_latitude": -2.0
+    }, 
+    "west_tropic": {
+        "subpage_lower_left_longitude": -180.0, 
+        "subpage_upper_right_longitude": 0.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 35.0, 
+        "subpage_lower_left_latitude": -35.0
+    }, 
+    "south_pole": {
+        "subpage_upper_right_longitude": 45.0, 
+        "subpage_upper_right_latitude": -9.0, 
+        "subpage_lower_left_longitude": -135.0, 
+        "subpage_map_hemisphere": "south", 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": -9.0
+    }, 
+    "south_atlantic_and_indian_ocean": {
+        "subpage_lower_left_longitude": -65.0, 
+        "subpage_upper_right_longitude": 122.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 25.0, 
+        "subpage_lower_left_latitude": -69.0
+    }, 
+    "equatorial_pacific": {
+        "subpage_lower_left_longitude": 130.0, 
+        "subpage_upper_right_longitude": 285.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": 50.0, 
+        "subpage_lower_left_latitude": -50.0
+    }, 
+    "australasia": {
+        "subpage_lower_left_longitude": 109.7, 
+        "subpage_upper_right_longitude": 179.0, 
+        "subpage_map_projection": "cylindrical", 
+        "subpage_upper_right_latitude": -6.0, 
+        "subpage_lower_left_latitude": -47.6
+    }, 
+    "north_atlantic": {
+        "subpage_upper_right_longitude": 40.0, 
+        "subpage_upper_right_latitude": 62.0, 
+        "subpage_lower_left_longitude": -50.0, 
+        "subpage_vertical_longitude": -20, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 23.0
+    }, 
+    "western_asia": {
+        "subpage_upper_right_longitude": 133.29, 
+        "subpage_upper_right_latitude": 54.56, 
+        "subpage_lower_left_longitude": 49.51, 
+        "subpage_vertical_longitude": 69.42, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 18.85
+    }, 
+    "north_america": {
+        "subpage_upper_right_longitude": -41.6, 
+        "subpage_upper_right_latitude": 42.0, 
+        "subpage_lower_left_longitude": -118.1, 
+        "subpage_vertical_longitude": -100, 
+        "subpage_map_projection": "polar_stereographic", 
+        "subpage_lower_left_latitude": 20.0
+    }
+}
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4717c2e..d5c871d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,17 +8,17 @@ install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/magics_config.h  DESTINATION ${INSTA
 
 
 function( add_metview_definition_file )
-   
-    set( single_value_args ACTION BASENAME FILE ) 
+
+    set( single_value_args ACTION BASENAME FILE )
     cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
-     
-    add_custom_command( 
+
+    add_custom_command(
             OUTPUT ${_p_BASENAME}Def ${_p_BASENAME}Rules
             COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../tools/xml2mv.py ${CMAKE_CURRENT_SOURCE_DIR} ${_p_FILE}  ${_p_BASENAME}Def ${_p_ACTION} ${_p_BASENAME}Rules
             DEPENDS ${_p_FILE}
       )
-     
-     
+
+
     add_custom_target( ${_p_BASENAME} ALL DEPENDS ${_p_BASENAME}Def)
     install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_p_BASENAME}Def ${CMAKE_CURRENT_BINARY_DIR}/${_p_BASENAME}Rules DESTINATION ${INSTALL_DATA_DIR}/../magics/metview)
 
@@ -34,11 +34,11 @@ foreach( file ${magics_xmls} )
       get_filename_component( basefile ${file} NAME_WE )
 
       set( ouputfiles ${path}/${basefile}Attributes.h ${path}/${basefile}Attributes.cc )
-      
+
       # generate the code
-      add_custom_command( 
+      add_custom_command(
             OUTPUT  ${ouputfiles}
-            COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/xml2cc.pl ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${CMAKE_CURRENT_BINARY_DIR}/params nosubdir
+            COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/xml2cc.py ${CMAKE_CURRENT_SOURCE_DIR}/../tools/ ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${CMAKE_CURRENT_BINARY_DIR}/params nosubdir
             DEPENDS ${file}
       )
 
@@ -48,18 +48,18 @@ foreach( file ${magics_xmls} )
       list( APPEND magics_params_srcs ${ouputfiles} )
 
 endforeach()
-     
+
 if ( metview )
 
 	foreach( file ${metview_xmls} )
 	      get_filename_component( path     ${file} PATH   )
           get_filename_component( basefile ${file} NAME_WE )
-		  
+
 		  set( metviewfiles ${path}/${basefile}Wrapper.h ${path}/${basefile}Wrapper.cc )
-		  
-		  
+
+
 		# generate the code
-		  add_custom_command( 
+		  add_custom_command(
 				OUTPUT  ${metviewfiles}
 				COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/xml2mv.pl ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${CMAKE_CURRENT_BINARY_DIR}/params nosubdir
 				DEPENDS ${file}
@@ -76,7 +76,7 @@ if ( metview )
           QT5_WRAP_CPP(qt_drivers_HEADERS_MOC ${qt_drivers_HEADERS})
         else()
           QT4_WRAP_CPP(qt_drivers_HEADERS_MOC ${qt_drivers_HEADERS})
-        endif()        
+        endif()
         list( APPEND drivers_srcs  drivers/MgQ/MgQPlotScene.cc  ${qt_drivers_HEADERS_MOC})
      endif()
 endif()
@@ -93,6 +93,7 @@ add_subdirectory( visualisers )
 add_subdirectory( drivers )
 add_subdirectory( decoders )
 add_subdirectory( terralib )
+add_subdirectory( clipper )
 add_subdirectory( eckit_readers )
 
 if( metview )
@@ -109,8 +110,8 @@ ecbuild_add_library( TARGET    MagPlus
                      DEPENDS   magics_params
                      SOURCES
                         magics.h
-                        ${magics_params_srcs} 
-                        ${common_srcs} 
+                        ${magics_params_srcs}
+                        ${common_srcs}
                         ${basic_srcs}
                         ${web_srcs}
                         ${visualisers_srcs}
@@ -118,7 +119,8 @@ ecbuild_add_library( TARGET    MagPlus
                         ${drivers_srcs}
                         ${qt_srcs}
                         ${decoders_srcs}
-                        ${terralib_srcs} 
+                        ${clipper_srcs}
+                        ${terralib_srcs}
                         ${odb_srcs}
                      TEMPLATES
                         ${common_templates}
@@ -143,8 +145,8 @@ ecbuild_add_library( TARGET    MagPlusStatic
                      DEPENDS   magics_params
                      SOURCES
                         magics.h
-                        ${magics_params_srcs} 
-                        ${common_srcs} 
+                        ${magics_params_srcs}
+                        ${common_srcs}
                         ${basic_srcs}
                         ${web_srcs}
                         ${visualisers_srcs}
@@ -152,18 +154,19 @@ ecbuild_add_library( TARGET    MagPlusStatic
                         ${drivers_srcs}
                         ${qt_srcs}
                         ${decoders_srcs}
-                        ${terralib_srcs} 
+                        ${clipper_srcs}
+                        ${terralib_srcs}
                         ${odb_srcs}
                      TEMPLATES
                         ${common_templates}
                      DEFINITIONS
-                        ${MAGICS_EXTRA_DEFINITIONS}  
+                        ${MAGICS_EXTRA_DEFINITIONS}
                      LIBS
-                        ${MAGICS_EXTRA_LIBRARIES} 
+                        ${MAGICS_EXTRA_LIBRARIES}
                      TYPE STATIC
                      OUTPUT_NAME MagPlus )
 
-ecbuild_add_library( TARGET      MagPlusSingleStatic 
+ecbuild_add_library( TARGET      MagPlusSingleStatic
                      SOURCES     MagicsSingle.cc
                      LIBS        MagPlusStatic
                      TYPE        STATIC
@@ -178,48 +181,48 @@ ecbuild_add_library( TARGET      MagPlusDoubleStatic
 endif()
 
 if( metview )
- include_directories(  ${CMAKE_CURRENT_SOURCE_DIR} 
-                        ${CMAKE_CURRENT_BINARY_DIR} 
-                        ${CMAKE_CURRENT_BINARY_DIR}/params 
-                        ${CMAKE_CURRENT_SOURCE_DIR}/common  
+ include_directories(  ${CMAKE_CURRENT_SOURCE_DIR}
+                        ${CMAKE_CURRENT_BINARY_DIR}
+                        ${CMAKE_CURRENT_BINARY_DIR}/params
+                        ${CMAKE_CURRENT_SOURCE_DIR}/common
                         ${CMAKE_CURRENT_SOURCE_DIR}/basic
                         ${CMAKE_CURRENT_SOURCE_DIR}/web
                         ${CMAKE_CURRENT_SOURCE_DIR}/visualisers
                         ${CMAKE_CURRENT_SOURCE_DIR}/drivers
                         ${CMAKE_CURRENT_SOURCE_DIR}/decoders
-                        ${CMAKE_CURRENT_SOURCE_DIR}/terralib
-                        ${CMAKE_CURRENT_SOURCE_DIR}/terralib/kernel 
+                        ${CMAKE_CURRENT_SOURCE_DIR}/clipper
+                        ${CMAKE_CURRENT_SOURCE_DIR}/terralib/kernel
                         ${CMAKE_CURRENT_SOURCE_DIR}/libMagWrapper )
-  
 
-                        
+
+
   ecbuild_add_library( TARGET    MagWrapper
                      DEPENDS   mv_params magics_params
                      SOURCES
                         magics.h
-                        ${metview_srcs} 
-                        ${metview_wrappers_srcs} 
+                        ${metview_srcs}
+                        ${metview_wrappers_srcs}
                      DEFINITIONS
-                        ${MAGICS_EXTRA_DEFINITIONS}                   
+                        ${MAGICS_EXTRA_DEFINITIONS}
                     LIBS
                         ${MAGICS_EXTRA_LIBRARIES}
-                    TYPE STATIC		
+                    TYPE STATIC
                     )
    list( APPEND attributes_include
-				OutputHandlerAttributes.h 
-				FortranRootSceneNodeAttributes.h  
+				OutputHandlerAttributes.h
+				FortranRootSceneNodeAttributes.h
                 BinningObjectAttributes.h
                 GribDecoderAttributes.h
                 DateGribLoopStepAttributes.h
                 GribLoopAttributes.h
                 GeoRectangularProjectionAttributes.h
                 LegendVisitorAttributes.h
-				XmlRootNodeAttributes.h 
+				XmlRootNodeAttributes.h
 				WrepRootNodeAttributes.h
                 ContinuousLegendMethodAttributes.h
                 HistogramLegendMethodAttributes.h
                 XmlBasicNodeAttributes.h
-                ImagePlottingAttributes.h
+                #ImagePlottingAttributes.h
                 LookupTableModeAttributes.h
                 FixedTableModeAttributes.h
 				)
@@ -229,14 +232,14 @@ if( metview )
    endif()
 
    install( FILES terralib/kernel/TeProjection.h
-				   terralib/kernel/TeCoord2D.h 
-				   terralib/kernel/TeDefines.h 
-				   terralib/kernel/TePrecision.h 
-				   terralib/kernel/TeSingleton.h 
-				   terralib/kernel/TeDatum.h 
+				   terralib/kernel/TeCoord2D.h
+				   terralib/kernel/TeDefines.h
+				   terralib/kernel/TePrecision.h
+				   terralib/kernel/TeSingleton.h
+				   terralib/kernel/TeDatum.h
 				   terralib/kernel/TeUtils.h
-				   
-				   
+
+
 				   DESTINATION ${INSTALL_INCLUDE_DIR})
    install( FILES VectorOfPointers.h  DESTINATION ${INSTALL_INCLUDE_DIR})
    foreach( file ${attributes_include} )
diff --git a/src/basic/BasicGraphicsObject.h b/src/basic/BasicGraphicsObject.h
index dcf1304..e657602 100644
--- a/src/basic/BasicGraphicsObject.h
+++ b/src/basic/BasicGraphicsObject.h
@@ -127,10 +127,7 @@ public:
 
 	void visit(const BaseDriver&) const;
 
-	double absoluteX() const //absolute position from the root
-	{
-		ASSERT(parent_); return parent_->absoluteX();
-	}
+    
 	
 	virtual void getDriverInfo(double& x, double& y, double& width, double& height)
 	{
@@ -153,12 +150,12 @@ public:
 		ASSERT(parent_); return parent_->absoluteHeight();
 	}
 	
-	virtual double absoluteWidth(double width)  const //absolute position from the root
+	virtual double absoluteWidth(double width) //absolute position from the root
 	{
 		ASSERT(parent_); return parent_->absoluteWidth(width);
 	}
 
-	virtual double absoluteHeight(double height) const //absolute position from the root
+	virtual double absoluteHeight(double height) //absolute position from the root
 	{
 		ASSERT(parent_); return parent_->absoluteHeight(height);
 	}
diff --git a/src/basic/FortranMagics.cc b/src/basic/FortranMagics.cc
index 28e9b5e..83296a5 100644
--- a/src/basic/FortranMagics.cc
+++ b/src/basic/FortranMagics.cc
@@ -139,33 +139,41 @@ void FortranMagics::popen()
   Here is where the real magics is happen. Everything is dispatched, followed
   by a comprehensive clean-up.
 */
-void FortranMagics::pclose()
+int FortranMagics::pclose()
 {
 	MagLog::info()<< "pclose()" << endl;
-	if (!empty_) {
-		finish();
-		dispatch();
-	}
+	try {
+		if (!empty_) {
+			finish();
+			dispatch();
+		}
 
-	if ( root_ && drivers_ ) {
+		if ( root_ && drivers_ ) {
 
-		BasicGraphicsObject* object = root_->close();
-		if ( object ) {
+			BasicGraphicsObject* object = root_->close();
+			if ( object ) {
 
 			/***   Start clean-up  ***/
-			drivers_->dispatch(object);
-			drivers_->closeDrivers();
+				drivers_->dispatch(object);
+				drivers_->closeDrivers();
 
-			delete root_;
-			delete drivers_;
-			delete output_;
+				delete root_;
+				delete drivers_;
+				delete output_;
 
-			drivers_ = 0;
-			root_ = 0;
-			output_ = 0;
-		}
+				drivers_ = 0;
+				root_ = 0;
+				output_ = 0;
+			}
 
+		}
 	}
+	catch ( MagicsException e) {
+		MagLog::error() << "Errors reported:" << e.what() << " - No plot produced  " << endl;
+		MagLog::error().flush();
+		return -1;
+	}
+
 
 	// the Magics log messages are not broadcast until the next log event - therefore, the
 	// last log message will not be broadcast. We fix that by flushing the message streams
@@ -176,6 +184,7 @@ void FortranMagics::pclose()
 	// then a consecutive call to popen will not be affected by the current values.
 	ParameterManager::reset();
 
+	Layout::reset();
 
 	if(getEnvVariable("MAGPLUS_QUIET").empty() )
 	{
@@ -188,6 +197,7 @@ void FortranMagics::pclose()
 		{
 			MagLog::userInfo() << "  - "<<(*it)<<"\n";
 		}
+		
 		MagLog::userInfo() << "\n";
 	*/
 		MagLog::userInfo() << "------------------------------------------------------------------\n";
@@ -197,6 +207,7 @@ void FortranMagics::pclose()
 		MagLog::userInfo() << "                   magics at ecmwf.int\n";
 		MagLog::userInfo() << "------------------------------------------------------------------\n";
 	}
+	return 0;
 }
 
 void FortranMagics::drivers()
diff --git a/src/basic/FortranMagics.h b/src/basic/FortranMagics.h
index 42fcad2..e420995 100644
--- a/src/basic/FortranMagics.h
+++ b/src/basic/FortranMagics.h
@@ -47,7 +47,7 @@ public:
 	~FortranMagics();
 	typedef void (FortranMagics::*Action)();
 	void popen();
-	void pclose();
+	int pclose();
 	void pnew(const string&);
 	void pcoast();
 	void ptephi();
diff --git a/src/basic/Layer.cc b/src/basic/Layer.cc
index 8aed461..2108a9c 100644
--- a/src/basic/Layer.cc
+++ b/src/basic/Layer.cc
@@ -140,7 +140,7 @@ void Layer:: execute(const BaseDriver& ) const
 
 void Layer::collectText(vector<TextVisitor*>& texts, LegendVisitor* legend)
 {
-	if ( !visibility_) return; 
+	
 	if ( !object_) 
 		return;
 
@@ -232,8 +232,8 @@ void SingleLayer::magnify(const BaseDriver& driver, float ,float )
 
 void SingleLayer::execute(const BaseDriver& driver) const
 {
-	if ( !parentLayer_->visibility() )
-		return;
+//	if ( !parentLayer_->visibility() )
+//		return;
 
 	ASSERT(objects_);
 	objects_->redisplay(driver);
@@ -257,8 +257,8 @@ void SingleLayer::update(const Layout& parent)
 
 void SingleLayer::getReady() const
 {
-	if ( !parentLayer_->visibility() )
-		return;
+//	if ( !parentLayer_->visibility() )
+//		return;
 	if ( parentLayer_->parent()->state() == geometry_changed) {
 		ASSERT(objects_);
 		objects_->clear();
@@ -314,7 +314,7 @@ void StepLayer::redisplay(const BaseDriver& driver) const
 
 void StepLayer::execute(int i, const BaseDriver& driver, const Layout& layout) const
 {  
-	if ( visibility_ && i < steps_.size() ) {
+	if ( i < steps_.size() ) {
 		steps_[i]->update(layout);
 		steps_[i]->execute(driver);
 	}
@@ -322,8 +322,8 @@ void StepLayer::execute(int i, const BaseDriver& driver, const Layout& layout) c
 
 void StepLayer::getReady(int i) const
 {  
-	if ( visibility_ )
-		steps_[i]->getReady();
+	
+	steps_[i]->getReady();
 }
 
 void StepLayer::newLayer(const BaseDriver& driver)
@@ -395,8 +395,8 @@ void StaticLayer::redisplay(const BaseDriver& driver) const
 void StaticLayer::execute(const BaseDriver& driver) const
 {  
 
-	if ( visibility_ ) 
-		redisplay(driver);
+	
+	redisplay(driver);
 }
 
 void StaticLayer::getReady() const
@@ -407,7 +407,6 @@ void StaticLayer::collect(MetaDataCollector& infos)
 {
 	if(object_)
 		object_->visit(infos);
-	//layer_->transformation().collect(infos);
 }
 
 void StaticLayer::collect(ValuesCollector& values)
@@ -544,6 +543,34 @@ void TextLayer::execute(const BaseDriver& driver) const
 	layout->redisplay(driver); 
 }
 
+void LegendLayer::getReady() const {}
+void LegendLayer::execute(const BaseDriver&) const {}
+void LegendLayer::execute(int, const BaseDriver&) const {}
+
+void LegendLayer::getInfo(int, const BaseDriver& driver) const 
+{
+	// We assume hat "TextLayer::getInfo" has been called before!
+	Layout parent;
+	parent.parent(parent_);
+	parent.name("Clone for legend");
+
+	parent.width(parent_->layoutPtr()->width());
+	parent.height(parent_->layoutPtr()->height());
+	parent.x(parent_->layoutPtr()->x());
+	parent.y(parent_->layoutPtr()->y());
+
+	LegendVisitor* legend = this->parent()->legend();
+
+	if ( legend ) {
+		Layout* layout = new Layout();
+		layout->parent(parent_);
+		legend->finish(*layout);
+		parent.push_back(layout);
+	}
+	parent.redisplay(driver);
+	
+}
+	
 
 
 void TextLayer::getInfo(int i, const BaseDriver&  driver) const
@@ -564,16 +591,7 @@ void TextLayer::getInfo(int i, const BaseDriver&  driver) const
 	layout->parent(parent_);
 	parent_->finishText(*layout);
 	parent->push_back(layout);
-
-	LegendVisitor* legend = this->parent()->legend();
-
-	if ( legend ) {
-		Layout* layout = new Layout();
-		layout->parent(parent_);
-
-		legend->finish(*layout);
-		parent->push_back(layout);
-	}
+	
 	parent->redisplay(driver);
 	delete parent;
 }
@@ -605,12 +623,26 @@ SceneLayer::~SceneLayer()
 	}
 }
 
+void SceneLayer::text(TextVisitor* text) 
+{ 
+	textVisitors_.push_back(text); 
+	textHandler_.icon(*text); 
+}
+
+void SceneLayer::legend(LegendVisitor* legend)
+{ 
+	legend_ = legend; 
+	if ( legend )
+		legendHandler_.icon(*legend);
+}
+
 bool SceneLayer::buildTree(const Layout& parent,  unsigned int frame, const BaseDriver& out) const
 {
 	if (frame >= numberOfSteps() ) return false;
 	if ( !currentFrame_ ) {
 		textHandler_.name("Titles");
 		textHandler_.parent(const_cast<SceneLayer*>(this));
+		legendHandler_.parent(const_cast<SceneLayer*>(this));
 	}
 	// we need to copy the attributes from the parent!
 
@@ -625,7 +657,9 @@ bool SceneLayer::buildTree(const Layout& parent,  unsigned int frame, const Base
 
 	getReady(frame);
 	execute(frame, out);
+
 	textHandler_.getInfo(frame, out);
+	legendHandler_.getInfo(frame, out);
 	layout_->frameIt();
 	out.redisplay(*layout_);
 	return ( frame+1 < numberOfSteps() );
@@ -638,14 +672,17 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
 	unsigned int nb = frames.size();
 	switch ( mode_) {
 	case paper: {
-		textHandler_.name("Titles");
+		
 		textHandler_.parent(const_cast<SceneLayer*>(this));
+		legendHandler_.name("Legend");
+		legendHandler_.parent(const_cast<SceneLayer*>(this));
 		if ( nb == 0) {
 			for ( int i = 0; i < numberOfSteps(); i++ )
 			{
 				getReady(i);
 				execute(i, driver);
 				textHandler_.getInfo(i, driver);
+				legendHandler_.getInfo(i, driver);
 			}
 		}
 		else {
@@ -659,20 +696,23 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
 				getReady(i);
 				execute(i, driver);
 				textHandler_.getInfo(i, driver);
+				legendHandler_.getInfo(i, driver);
 			}
 		}
 	}
 	break;
 	case basic:
-		textHandler_.name("Titles");
+		
 		textHandler_.parent(const_cast<SceneLayer*>(this));
-
+		legendHandler_.name("Legend");
+		legendHandler_.parent(const_cast<SceneLayer*>(this));
 		if ( nb == 0) {
 			for ( int i = 0; i < numberOfSteps(); i++ )
 			{
 				getReady(i);
 				execute(i, driver);
 				textHandler_.getInfo(i, driver);
+				legendHandler_.getInfo(i, driver);
 			}
 		}
 		else  {
@@ -681,14 +721,16 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
 				getReady(f);
 				execute(f, driver);
 				textHandler_.getInfo(f, driver);
+				legendHandler_.getInfo(f, driver);
 			}
 		}
 		break;
 	case interactif:
 		visit(driver);
-		textHandler_.name("Titles");
+		
 		textHandler_.parent(const_cast<SceneLayer*>(this));
 		const_cast<SceneLayer*>(this)->add(&textHandler_);
+		const_cast<SceneLayer*>(this)->add(&legendHandler_);
 		// here we add the Layer dedicated to the text ! ...
 		driver.redisplay(*this);
 		break;
@@ -1012,13 +1054,9 @@ void MetviewIcon::visit(Layer& layer)
 {
 	if ( !iconClass_.empty() && !iconName_.empty() )
 	{
-		layer.icon(iconName_,iconClass_,iconId_);
+		layer.icon(*this);
 	}
 
-	//if ( !iconClass_.empty() && !iconName_.empty() )
-	//	layer.icon(iconName_, iconClass_);
-
-	layer.id(iconId_);
 }
 
 void MetviewIcon::visit(MetaDataCollector& collector)
diff --git a/src/basic/Layer.h b/src/basic/Layer.h
index a06e525..7ec902e 100644
--- a/src/basic/Layer.h
+++ b/src/basic/Layer.h
@@ -110,7 +110,17 @@ public:
 	vector<MetviewIcon >::const_iterator iconsEnd() { return icons_.end(); }
 	void  icon(const string& iconname, const string& iconclass,const string& iconid) 
 			{  icons_.push_back(MetviewIcon(iconname, iconclass,iconid)); }
-	
+	void  icon(const MetviewIcon& icon)
+			{  MetviewIcon add; 
+				add.icon(icon); 
+				icons_.push_back(add); 
+				visibility_ = icon.visibility(); 
+				transparency_ = icon.transparency();
+//F20161116				zindex_ = icon.zindex();  
+				id_ = icon.id(); 
+				name_ = icon.name();
+			}
+
 	//void setInfo(const string& name, const string& value) { information_[name]=value; }
 	//virtual const map<string, string>& getInfos(bool =false) const { return information_; }
 
@@ -266,13 +276,24 @@ public:
 	TextLayer() {}
 	~TextLayer() {}
 	void getReady() const;
+    void getReady(int i) const { Layer::getReady(i); }
 	void execute(const BaseDriver&) const;
 	void execute(int, const BaseDriver&) const;
 	void getInfo(int, const BaseDriver&) const;
 	void collectText(vector<TextVisitor*>&, LegendVisitor*); // update the text informations!
 };
 
-
+class LegendLayer : public StepLayer
+{
+public:
+	LegendLayer() {}
+	~LegendLayer() {}
+	void getReady() const;
+	void execute(const BaseDriver&) const;
+	void execute(int, const BaseDriver&) const;
+	void getInfo(int, const BaseDriver&) const;
+	
+};
 /*
  * A SceneLayer is attach to a SceneNode...
  * It contains the list of layers needed to perform a plot.
@@ -294,8 +315,9 @@ public:
 
 	Layer*  findLayer(Layer*,int) const; 
 	
-	void legend(LegendVisitor* legend) { legend_ = legend; }
-	void text(TextVisitor* text) { textVisitors_.push_back(text); }
+	void legend(LegendVisitor* legend);
+	void text(TextVisitor* text);
+
 	
 	void getReady(int) const;
 
@@ -335,6 +357,7 @@ protected:
 	mutable std::set<LayoutVisitor*> visitors_;
 	mutable  vector<TextVisitor*> textVisitors_;
 	mutable TextLayer textHandler_;
+	mutable LegendLayer legendHandler_;
 
 	mutable LegendVisitor* legend_;
 	MagicsMode mode_;
diff --git a/src/basic/LegendVisitor.cc b/src/basic/LegendVisitor.cc
index 6e1ff11..6b44023 100644
--- a/src/basic/LegendVisitor.cc
+++ b/src/basic/LegendVisitor.cc
@@ -154,6 +154,15 @@ void RainbowEntry::rowBox(const PaperPoint& point, BasicGraphicsObjectContainer&
 	line_->push_back(PaperPoint(x+0.5, y+0.5));
 	out.push_back(line_);
 }
+void RainbowEntry::columnBox(const PaperPoint& point, BasicGraphicsObjectContainer& out)
+{
+	double x = point.x();
+	double y = point.y();
+
+	line_->push_back(PaperPoint(x-0.9, y));
+	line_->push_back(PaperPoint(x-0.2, y));
+	out.push_back(line_);
+}
 void LineEntry::columnBox(const PaperPoint& point, BasicGraphicsObjectContainer& out)
 {
 	double x = point.x();
@@ -217,9 +226,13 @@ void LegendVisitor::build()
 	if ( !empty() ) {
 		if ( use_min_ ) {
 			front()->userText(use_min_text_, "user");
+			front()->minText(use_min_text_);
+			
 		}
 		if ( use_max_ ) {
 			back()->userText(use_max_text_, "user");
+			back()->maxText(use_max_text_);
+			
 		}
 	
 		back()->units(units_text_);
@@ -785,9 +798,13 @@ void BoxEntry::rowBox(const PaperPoint& point, BasicGraphicsObjectContainer& leg
 		from->setAngle(angle_);
 		legend.push_back(from);
 		if ( automatic_ ) {
-			ostringstream bottom;
-			bottom << MagicsFormat(format_, from_);
-			from->addText(bottom.str(), font_);
+			if ( minText_.empty() ) {
+				ostringstream bottom;
+				bottom << MagicsFormat(format_, from_);
+				minText_ = bottom.str();
+			}
+			
+			from->addText(minText_, font_);
 		}
 		else 
 			if ( !last_ ) 
@@ -805,9 +822,12 @@ void BoxEntry::rowBox(const PaperPoint& point, BasicGraphicsObjectContainer& leg
 		to->push_back(PaperPoint(x+width, y - height- 0.25));
 		legend.push_back(to);
 		if ( automatic_  ) {
-			ostringstream top, bottom;
-			top << MagicsFormat(format_, to_);
-			to->addText(top.str(), font_);
+			if ( maxText_.empty() ) {
+				ostringstream to;
+				to << MagicsFormat(format_, to_);
+				maxText_ = to.str();
+			}
+			to->addText(maxText_, font_);
 		}
 		else 
 			to->addText(userText_, font_);
@@ -1054,13 +1074,22 @@ void BoxEntry::columnBox(const PaperPoint& point, BasicGraphicsObjectContainer&
 		from->setJustification(MLEFT);
 		from->setVerticalAlign(MHALF);
 		if ( automatic_ ) {
-			ostringstream bottom;
-			bottom << MagicsFormat(format_, from_);
-			from->addText(bottom.str(), font_);
+			if ( minText_.empty() ) {
+				ostringstream bottom;
+				bottom << MagicsFormat(format_, from_);
+				minText_ = bottom.str();
+			}
+			
+			from->addText(minText_, font_);
 		}
 		else 
 			if ( !last_ ) 
 				from->addText(userText_, font_);
+			else {
+				ostringstream bottom;
+				bottom << MagicsFormat(format_, from_);
+				from->addText(bottom.str(), font_);
+			}
 		PaperPoint pfrom(pt);
 		pfrom.y_ = y - height;
 		from->push_back(pfrom);
@@ -1072,12 +1101,16 @@ void BoxEntry::columnBox(const PaperPoint& point, BasicGraphicsObjectContainer&
 		to->setVerticalAlign(MHALF);
 		to->setJustification(MLEFT);
 		to->setAngle(angle_);
+		
 		if ( automatic_  ) {
-			ostringstream top, bottom;
-			top << MagicsFormat(format_, to_);
-			to->addText(top.str(), font_);
+			if ( maxText_.empty() ) {
+				ostringstream to;
+				to << MagicsFormat(format_, to_);
+				maxText_ = to.str();
+			}
+			to->addText(maxText_, font_);
 		}
-		else
+		else 
 			to->addText(userText_, font_);
 		PaperPoint pto(pt);
 		pto.y_ =  y + height;
@@ -1375,9 +1408,17 @@ void SimpleSymbolEntry::set(const PaperPoint& point, BasicGraphicsObjectContaine
 
 const string& LegendEntry::label() const
 {
-	if ( !label_.empty() || !fromto_)
+	if ( !label_.empty() || !fromto_ )
 		return label_;
-
+	if ( minText_.size() ) {
+		label_ = minText_;
+		return label_;
+	}
+	if ( maxText_.size() ){
+		label_ = maxText_;
+		return label_;
+	}
+		
 	if ( from_ == to_ )
 	{
 		ostringstream nice;
diff --git a/src/basic/LegendVisitor.h b/src/basic/LegendVisitor.h
index f06d4ed..4a4e0ea 100644
--- a/src/basic/LegendVisitor.h
+++ b/src/basic/LegendVisitor.h
@@ -74,7 +74,9 @@ public:
 		{ if ( userText_.size() )
 			return;
 		   userText_ = text; 
+
 		   automatic_ = magCompare(automatic, "automatic_text_only"); 
+		  
 		}
 	const string& userText() { return userText_; }
 	const string& units() { return units_; }
@@ -103,6 +105,8 @@ public:
 	void  mean(double mean)  { meanValue_ = mean; meanSet_ = true; }
 	void  histogramInformation(HistogramLegendMethod* histo) {histogram_ = histo;}
 	void  borderColour(const Colour& colour)  {  borderColour_ = colour; }
+	void  minText(const string& text)  {  minText_ = text; label_ = text; }
+	void  maxText(const string& text)  {  maxText_ = text; label_ = text; }
 	
 protected:
 	bool last_;
@@ -117,7 +121,9 @@ protected:
 
     string userText_;
     string units_;
-	
+	string minText_;
+	string maxText_;
+
 	double from_;
 	double to_;
 
@@ -226,6 +232,7 @@ public:
 		LineEntry(label, line) { }
 	bool needContinuousText(Text&) { return true;  }
 	void rowBox(const PaperPoint&, BasicGraphicsObjectContainer&);
+	void columnBox(const PaperPoint&, BasicGraphicsObjectContainer&);
 
 	~RainbowEntry();
 };
diff --git a/src/basic/MagicsEvent.h b/src/basic/MagicsEvent.h
index d8951dd..dd664df 100644
--- a/src/basic/MagicsEvent.h
+++ b/src/basic/MagicsEvent.h
@@ -260,13 +260,22 @@ struct MetviewIcon
 {
 public:
 	MetviewIcon(const string& name = "", const string& cname = "", const string& id="unknown") :
-		iconName_(name), iconClass_(cname), iconId_(id) {};
+		iconName_(name), iconClass_(cname), iconId_(id), visibilityLayer_(true), zindexLayer_(-1), transparencyLayer_(0) {};
 		
 	void icon(const string& name, const string& cname, const string& id="unknown") {
 		iconName_ = name;
 		iconClass_ = cname;
 		iconId_ = id;
 	}
+
+	void layerInfo(bool visibility, int zindex, int transparency, const string& id, const string& name) {
+		visibilityLayer_ = visibility;
+		zindexLayer_ = zindex;
+		transparencyLayer_ = transparency;
+		idLayer_ = id;
+		nameLayer_ = name;
+	}
+	
 	virtual void visit(Layer& layer);
 
 	virtual void visit(MetaDataCollector& collector);
@@ -279,18 +288,34 @@ public:
 		iconName_ = other.iconName_;
 		iconClass_ = other.iconClass_;
 		iconId_ = other.iconId_;
-	}	
-	string iconName() const {return iconName_;}
-        string iconClass() const {return iconClass_;}
-        string iconId() const {return iconId_;}
+		visibilityLayer_ = other.visibilityLayer_;
+  		zindexLayer_ = other.zindexLayer_;
+  		transparencyLayer_ = other.transparencyLayer_;
+		idLayer_ = other.idLayer_;
+		nameLayer_ = other.nameLayer_;
 
+	}	
+	string iconName() const   { return iconName_;     }
+    string iconClass() const  { return iconClass_;    }
+    string iconId() const     { return iconId_;       }
+    int zindex() const        { return zindexLayer_;       }
+ 	int visibility() const    { return visibilityLayer_;   } 
+	int transparency() const  { return transparencyLayer_; }
+	const string& id() const  { return idLayer_; }
+	const string& name() const  { return nameLayer_; }
 
-			
 protected:
 	string iconName_;
 	string iconClass_;
 	string iconId_;
+	bool visibilityLayer_;
+    int zindexLayer_;
+    int transparencyLayer_;
+    string idLayer_;
+    string nameLayer_;
+	
 	map<string, string> information_;
+
 };
 
 } // namespace magics
diff --git a/src/basic/ViewNode.cc b/src/basic/ViewNode.cc
index 958a07a..59116e6 100644
--- a/src/basic/ViewNode.cc
+++ b/src/basic/ViewNode.cc
@@ -39,7 +39,7 @@
 using namespace magics;
 
 
-ViewNode::ViewNode() : viewTransformation_(0), animation_("basic"), vaxis_(2.), haxis_(1.),  rules_(0), legend_(0)
+ViewNode::ViewNode() : viewTransformation_(0), animation_("basic"), vaxis_(2.), haxis_(1.),  rules_(0), legend_(0), needLegend_(false)
 {
 	static int i = 0;
 	ostringstream n;
@@ -68,6 +68,7 @@ void ViewNode::text(TextVisitor* text)
 void ViewNode::legend(LegendVisitor* legend)
 {
 	legend_ = legend;
+	needLegend_ = true;
 }
 
 void ViewNode::visit(MetaDataVisitor& metadata)
@@ -179,14 +180,16 @@ void ViewNode::prepareLayout(SceneLayer& tree)
 
 	// Then the axis!
 	leftAxis_ = new LeftAxisVisitor(*drawing_);
-		leftAxis_->width(vaxis);
-		leftAxis_->frameIt();
+	leftAxis_->width(vaxis);
+	leftAxis_->frameIt();
+	
 	components_.push_back(leftAxis_);
 	helper.attachLeft(leftAxis_);
 
 	rightAxis_ = new RightAxisVisitor(*drawing_);
-		rightAxis_->width(vaxis);
-		rightAxis_->frameIt();
+	rightAxis_->width(vaxis);
+	rightAxis_->frameIt();
+	
 	helper.attachRight(rightAxis_);
 	components_.push_back(rightAxis_);
 
@@ -197,23 +200,25 @@ void ViewNode::prepareLayout(SceneLayer& tree)
 	topAxis_ = new TopAxisVisitor(*drawing_);
 	topAxis_->height(topaxis);
 	topAxis_->frameIt();
+	
 	helper.attachTop(topAxis_);
 	components_.push_back(topAxis_);
 	helper.add(topAxis_);
 
 
-
 	bottomAxis_ = new BottomAxisVisitor(*drawing_);
-		bottomAxis_->height(bottomaxis);
-		bottomAxis_->frameIt();
+	bottomAxis_->height(bottomaxis);
+	bottomAxis_->frameIt();
+	
 	components_.push_back(bottomAxis_);
 	helper.attachBottom(bottomAxis_);
 	helper.add(leftAxis_);
 	helper.add(rightAxis_);
 		
-	if ( legend_)
+	
+	tree.legend(legend_);
+	if ( needLegend_ && legend_ )
 	{
-		tree.legend(legend_);
 		if ( !legend_->positional() ) {
 			if ( legend_->top() ) {
 				legend_->height(5);
@@ -230,10 +235,13 @@ void ViewNode::prepareLayout(SceneLayer& tree)
 			helper.add(legend_);
 		}
 		((BasicSceneObject*)legend_)->parent((BasicSceneObject*)this);
-		legend_->getReady();
-
-		components_.push_back(legend_);
+	    legend_->getReady();
+	    components_.push_back(legend_);
 	}
+	else 
+		needLegend_ = false;
+   
+	
 
 	for (vector<TextVisitor*>::iterator text = texts_.begin(); text != texts_.end(); ++text)
 	{
@@ -285,27 +293,27 @@ void ViewNode::visit(SceneLayer& tree)
 
 	tree.rules(rules_);
 	// Here we checkeing for the legend!
-	bool legend = false;
+	needLegend_ = false;
 	for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item)  {
-			legend = (*item)->needLegend();
-			if ( legend ) break;
+			needLegend_ = (*item)->needLegend();
+			if ( needLegend_ ) break;
 	}
 
-	if ( !legend ) {
-		legend_ = 0;
-	}
+	
 	
 	//Here we have the steps! 	
 	prepareLayout(tree);	
+	
 	if ( items_.empty() )
 	{
 		push_back(new EmptySceneObject() );
 	}
-	if (legend_) {
-	for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item)  {
-		(*item)->getReady(*legend_);
-	}
+	if ( needLegend_ ) {
+		for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item)  {
+			(*item)->getReady(*legend_);
+		}
 	}
+
 	for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item)  {
 		(*item)->visit(tree, components_);
 	}
@@ -556,7 +564,9 @@ void FortranViewNode::getReady()
 
 	if ( predefined_ ) {
 			StyleLibrary library("projections");
-			const map<string, string>& area = library.get(predefined_name_);
+			Style::Definition area;
+
+			library.find(predefined_name_, area);
 			
 			viewTransformation_ = MagTranslator<string, Transformation>()(area.find("subpage_map_projection")->second);
 			viewTransformation_->set(area);
diff --git a/src/basic/ViewNode.h b/src/basic/ViewNode.h
index 3a6a9e7..feabe50 100644
--- a/src/basic/ViewNode.h
+++ b/src/basic/ViewNode.h
@@ -89,7 +89,7 @@ protected:
 	 string animation_; 
 	 
 	 DrawingVisitor* 		drawing_;
-	 FrameVisitor* 		frameHelper_;
+	 FrameVisitor* 		    frameHelper_;
 	 TopAxisVisitor*    	topAxis_;
 	 BottomAxisVisitor*     bottomAxis_;
 	 LeftAxisVisitor*    	leftAxis_;
@@ -99,7 +99,8 @@ protected:
 
 	 AnimationRules*        rules_;
 
-	 LegendVisitor* 		legend_;
+	 bool 				    needLegend_;
+	 LegendVisitor*         legend_;
 	 vector<TextVisitor*>   texts_;
 	 vector<LayoutVisitor*> components_;
 	
diff --git a/src/basic/VisualAction.cc b/src/basic/VisualAction.cc
index 94e277b..44906ac 100644
--- a/src/basic/VisualAction.cc
+++ b/src/basic/VisualAction.cc
@@ -248,9 +248,8 @@ void VisualAnimation::prepare()
 		return;
 	
 	layer_ = new StepLayer();
-	layer_->name(loop_->name());
-	layer_->id(loop_->name()); 
-	layer_->uniqueId(loop_->iconId());
+	layer_->id(loop_->id());
+	
 	loop_->visit(*layer_);
 	
 	for ( vector<Visdef* >::iterator visdef = this->visdefs_.begin(); visdef != this->visdefs_.end(); ++visdef)
@@ -322,8 +321,17 @@ bool VisualAction::needLegend()
 
 void VisualAction::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
 {
+
+	if ( !data_ || ( data_ && !data_->valid() ) || visdefs_.empty() )
+	{
+		MagLog::warning() << " Check data or visual action!" << endl;
+		return;
+	}
+	
 	layer_ = new StaticLayer(this);
 
+	
+	layer_->icon(*data_);
 	if ( data_ ) 
 		data_->visit(*layer_);
  	layer.add(layer_);
diff --git a/src/boost/range/adaptor/adjacent_filtered.hpp b/src/boost/range/adaptor/adjacent_filtered.hpp
deleted file mode 100644
index f717cb3..0000000
--- a/src/boost/range/adaptor/adjacent_filtered.hpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
-#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
-
-#include <boost/config.hpp>
-#ifdef BOOST_MSVC
-#pragma warning( push )
-#pragma warning( disable : 4355 )
-#endif
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/next_prior.hpp>
-
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class Iter, class Pred, bool default_pass >
-        class skip_iterator
-          : public boost::iterator_adaptor<
-                    skip_iterator<Iter,Pred,default_pass>,
-                    Iter,
-                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
-                    boost::forward_traversal_tag,
-                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
-                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
-                >
-          , private Pred
-        {
-        private:
-            typedef boost::iterator_adaptor<
-                        skip_iterator<Iter,Pred,default_pass>,
-                        Iter,
-                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
-                        boost::forward_traversal_tag,
-                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
-                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
-                    > base_t;
-
-        public:
-            typedef Pred pred_t;
-            typedef Iter iter_t;
-
-            skip_iterator() : m_last() {}
-
-            skip_iterator(iter_t it, iter_t last, const Pred& pred)
-                : base_t(it)
-                , pred_t(pred)
-                , m_last(last)
-            {
-                move_to_next_valid();
-            }
-
-            template<class OtherIter>
-            skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
-            : base_t(other.base())
-            , pred_t(other)
-            , m_last(other.m_last) {}
-
-            void move_to_next_valid()
-            {
-                iter_t& it = this->base_reference();
-                pred_t& bi_pred = *this;
-                if (it != m_last)
-                {
-                    if (default_pass)
-                    {
-                        iter_t nxt = ::boost::next(it);
-                        while (nxt != m_last && !bi_pred(*it, *nxt))
-                        {
-                            ++it;
-                            ++nxt;
-                        }
-                    }
-                    else
-                    {
-                        iter_t nxt = ::boost::next(it);
-                        for(; nxt != m_last; ++it, ++nxt)
-                        {
-                            if (bi_pred(*it, *nxt))
-                            {
-                                break;
-                            }
-                        }
-                        if (nxt == m_last)
-                        {
-                            it = m_last;
-                        }
-                    }
-                }
-            }
-
-            void increment()
-            {
-                iter_t& it = this->base_reference();
-                BOOST_ASSERT( it != m_last );
-                ++it;
-                move_to_next_valid();
-            }
-
-            iter_t m_last;
-        };
-
-        template< class P, class R, bool default_pass >
-        struct adjacent_filtered_range
-            : iterator_range< skip_iterator<
-                                BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
-                                P,
-                                default_pass
-                            >
-                        >
-        {
-        private:
-            typedef skip_iterator<
-                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
-                        P,
-                        default_pass
-                     >
-                skip_iter;
-
-            typedef iterator_range<skip_iter>
-                base_range;
-
-            typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
-
-        public:
-            adjacent_filtered_range( const P& p, R& r )
-            : base_range(skip_iter(boost::begin(r), boost::end(r), p),
-                         skip_iter(boost::end(r), boost::end(r), p))
-            {
-            }
-        };
-
-        template< class T >
-        struct adjacent_holder : holder<T>
-        {
-            adjacent_holder( T r ) : holder<T>(r)
-            { }
-        };
-
-        template< class T >
-        struct adjacent_excl_holder : holder<T>
-        {
-            adjacent_excl_holder( T r ) : holder<T>(r)
-            { }
-        };
-
-        template< class ForwardRng, class BinPredicate >
-        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
-        operator|( ForwardRng& r,
-                   const adjacent_holder<BinPredicate>& f )
-        {
-            return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
-        }
-
-        template< class ForwardRng, class BinPredicate >
-        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
-        operator|( const ForwardRng& r,
-                   const adjacent_holder<BinPredicate>& f )
-        {
-            return adjacent_filtered_range<BinPredicate,
-                                           const ForwardRng, true>( f.val, r );
-        }
-
-        template< class ForwardRng, class BinPredicate >
-        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
-        operator|( ForwardRng& r,
-                   const adjacent_excl_holder<BinPredicate>& f )
-        {
-            return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
-        }
-
-        template< class ForwardRng, class BinPredicate >
-        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
-        operator|( const ForwardRng& r,
-                   const adjacent_excl_holder<BinPredicate>& f )
-        {
-            return adjacent_filtered_range<BinPredicate,
-                                           const ForwardRng, false>( f.val, r );
-        }
-
-    } // 'range_detail'
-
-    // Bring adjacent_filter_range into the boost namespace so that users of
-    // this library may specify the return type of the '|' operator and
-    // adjacent_filter()
-    using range_detail::adjacent_filtered_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::forwarder<range_detail::adjacent_holder>
-                adjacent_filtered =
-                   range_detail::forwarder<range_detail::adjacent_holder>();
-
-            const range_detail::forwarder<range_detail::adjacent_excl_holder>
-                adjacent_filtered_excl =
-                    range_detail::forwarder<range_detail::adjacent_excl_holder>();
-        }
-
-        template<class ForwardRng, class BinPredicate>
-        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
-        adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
-        {
-            return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
-        }
-
-        template<class ForwardRng, class BinPredicate>
-        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
-        adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
-        {
-            return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
-        }
-
-    } // 'adaptors'
-
-}
-
-#ifdef BOOST_MSVC
-#pragma warning( pop )
-#endif
-
-#endif
diff --git a/src/boost/range/adaptor/argument_fwd.hpp b/src/boost/range/adaptor/argument_fwd.hpp
deleted file mode 100644
index fbfd40c..0000000
--- a/src/boost/range/adaptor/argument_fwd.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
-#define BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
-
-#include <boost/config.hpp>
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable : 4512) // assignment operator could not be generated
-#endif
-
-namespace boost
-{
-    namespace range_detail
-    {  
-        template< class T >
-        struct holder
-        {
-            T val;
-            holder( T t ) : val(t)
-            { }
-        };
-
-        template< class T >
-        struct holder2
-        {
-            T val1, val2;
-            holder2( T t, T u ) : val1(t), val2(u)
-            { }
-        };
-        
-        template< template<class> class Holder >
-        struct forwarder
-        {
-            template< class T >
-            Holder<T> operator()( T t ) const
-            {
-                return Holder<T>(t);
-            }
-        };
-
-        template< template<class> class Holder >
-        struct forwarder2
-        {
-            template< class T >
-            Holder<T> operator()( T t, T u ) const
-            {
-                return Holder<T>(t,u);
-            }
-        };
-
-        template< template<class,class> class Holder >
-        struct forwarder2TU
-        {
-            template< class T, class U >
-            Holder<T, U> operator()( T t, U u ) const
-            {
-                return Holder<T, U>(t, u);
-            }
-        };
-
-
-    } 
-        
-}
-
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-
-#endif
diff --git a/src/boost/range/adaptor/copied.hpp b/src/boost/range/adaptor/copied.hpp
deleted file mode 100644
index f4cf2d1..0000000
--- a/src/boost/range/adaptor/copied.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_COPIED_HPP
-#define BOOST_RANGE_ADAPTOR_COPIED_HPP
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/adaptor/sliced.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace adaptors
-    {
-        struct copied
-        {
-            copied(std::size_t t_, std::size_t u_)
-                : t(t_), u(u_) {}
-
-            std::size_t t;
-            std::size_t u;
-        };
-
-        template< class CopyableRandomAccessRng >
-        inline CopyableRandomAccessRng
-        operator|( const CopyableRandomAccessRng& r, const copied& f )
-        {
-            iterator_range<
-                BOOST_DEDUCED_TYPENAME range_iterator<const
-                                               CopyableRandomAccessRng>::type >
-            temp( adaptors::slice( r, f.t, f.u ) );
-            return CopyableRandomAccessRng( temp.begin(), temp.end() );
-        }
-
-        template<class CopyableRandomAccessRange>
-        inline CopyableRandomAccessRange
-        copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u)
-        {
-            iterator_range<
-                BOOST_DEDUCED_TYPENAME range_iterator<const
-                    CopyableRandomAccessRange>::type> temp(
-                        adaptors::slice(rng, t, u));
-
-            return CopyableRandomAccessRange( temp.begin(), temp.end() );
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptor/define_adaptor.hpp b/src/boost/range/adaptor/define_adaptor.hpp
deleted file mode 100644
index b228df3..0000000
--- a/src/boost/range/adaptor/define_adaptor.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
-#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
-
-#include <boost/tuple/tuple.hpp>
-
-#define BOOST_DEFINE_RANGE_ADAPTOR( adaptor_name, range_adaptor ) \
-    struct adaptor_name##_forwarder {}; \
-    \
-    template<typename Range> range_adaptor <Range> \
-        operator|(Range& rng, adaptor_name##_forwarder) \
-    { \
-        return range_adaptor <Range>( rng ); \
-    } \
-    \
-    template<typename Range> range_adaptor <const Range> \
-        operator|(const Range& rng, adaptor_name##_forwarder) \
-    { \
-        return range_adaptor <const Range>( rng ); \
-    } \
-    \
-    static adaptor_name##_forwarder adaptor_name = adaptor_name##_forwarder(); \
-    \
-    template<typename Range> \
-    range_adaptor <Range> \
-    make_##adaptor_name(Range& rng) \
-    { \
-        return range_adaptor <Range>(rng); \
-    } \
-    \
-    template<typename Range> \
-    range_adaptor <const Range> \
-    make_##adaptor_name(const Range& rng) \
-    { \
-        return range_adaptor <const Range>(rng); \
-    }
-
-#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \
-    struct adaptor_name \
-    { \
-        explicit adaptor_name (arg1_type arg1_) \
-            : arg1(arg1_) {} \
-        arg1_type arg1; \
-    }; \
-    \
-    template<typename Range> range_adaptor <Range> \
-        operator|(Range& rng, adaptor_name args) \
-    { \
-        return range_adaptor <Range>(rng, args.arg1); \
-    } \
-    \
-    template<typename Range> range_adaptor <const Range> \
-        operator|(const Range& rng, adaptor_name args) \
-    { \
-        return range_adaptor <const Range>(rng, args.arg1); \
-    } \
-    \
-    template<typename Range> \
-    range_adaptor <Range> \
-    make_##adaptor_name(Range& rng, arg1_type arg1) \
-    { \
-        return range_adaptor <Range>(rng, arg1); \
-    } \
-    \
-    template<typename Range> \
-    range_adaptor <const Range> \
-    make_##adaptor_name(const Range& rng, arg1_type arg1) \
-    { \
-        return range_adaptor <const Range>(rng, arg1); \
-    }
-
-#define BOOST_RANGE_ADAPTOR_2( adaptor_name, range_adaptor, arg1_type, arg2_type ) \
-    struct adaptor_name \
-    { \
-        explicit adaptor_name (arg1_type arg1_, arg2_type arg2_) \
-            : arg1(arg1_), arg2(arg2_) {} \
-        arg1_type arg1; \
-        arg2_type arg2; \
-    }; \
-    \
-    template<typename Range> range_adaptor <Range> \
-    operator|(Range& rng, adaptor_name args) \
-    { \
-        return range_adaptor <Range>(rng, args.arg1, args.arg2); \
-    } \
-    template<typename Range> \
-    range_adaptor <Range> \
-    make_##adaptor_name(Range& rng, arg1_type arg1, arg2_type arg2) \
-    { \
-        return range_adaptor <Range>(rng, arg1, arg2); \
-    } \
-    template<typename Range> \
-    range_adaptor <const Range> \
-    make_##adaptor_name(const Range& rng, arg1_type arg1, arg2_type arg2) \
-    { \
-        return range_adaptor <const Range>(rng, arg1, arg2); \
-    }
-
-
-#endif // include guard
diff --git a/src/boost/range/adaptor/filtered.hpp b/src/boost/range/adaptor/filtered.hpp
deleted file mode 100644
index d9315bd..0000000
--- a/src/boost/range/adaptor/filtered.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_FILTERED_HPP
-#define BOOST_RANGE_ADAPTOR_FILTERED_HPP
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/filter_iterator.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class P, class R >
-        struct filtered_range :
-            boost::iterator_range<
-                boost::filter_iterator< P,
-                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                >
-            >
-        {
-        private:
-            typedef boost::iterator_range<
-                        boost::filter_iterator< P,
-                            BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                        >
-                    > base;
-        public:
-            filtered_range( P p, R& r )
-            : base( make_filter_iterator( p, boost::begin(r), boost::end(r) ),
-                    make_filter_iterator( p, boost::end(r), boost::end(r) ) )
-            { }
-        };
-
-        template< class T >
-        struct filter_holder : holder<T>
-        {
-            filter_holder( T r ) : holder<T>(r)
-            { }
-        };
-
-        template< class InputRng, class Predicate >
-        inline filtered_range<Predicate, InputRng>
-        operator|( InputRng& r,
-                   const filter_holder<Predicate>& f )
-        {
-            return filtered_range<Predicate, InputRng>( f.val, r );
-        }
-
-        template< class InputRng, class Predicate >
-        inline filtered_range<Predicate, const InputRng>
-        operator|( const InputRng& r,
-                   const filter_holder<Predicate>& f )
-        {
-            return filtered_range<Predicate, const InputRng>( f.val, r );
-        }
-
-    } // 'range_detail'
-
-    // Unusual use of 'using' is intended to bring filter_range into the boost namespace
-    // while leaving the mechanics of the '|' operator in range_detail and maintain
-    // argument dependent lookup.
-    // filter_range logically needs to be in the boost namespace to allow user of
-    // the library to define the return type for filter()
-    using range_detail::filtered_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::forwarder<range_detail::filter_holder>
-                    filtered =
-                       range_detail::forwarder<range_detail::filter_holder>();
-        }
-
-        template<class InputRange, class Predicate>
-        inline filtered_range<Predicate, InputRange>
-        filter(InputRange& rng, Predicate filter_pred)
-        {
-            return range_detail::filtered_range<Predicate, InputRange>( filter_pred, rng );
-        }
-
-        template<class InputRange, class Predicate>
-        inline filtered_range<Predicate, const InputRange>
-        filter(const InputRange& rng, Predicate filter_pred)
-        {
-            return range_detail::filtered_range<Predicate, const InputRange>( filter_pred, rng );
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptor/indexed.hpp b/src/boost/range/adaptor/indexed.hpp
deleted file mode 100644
index 5a523ce..0000000
--- a/src/boost/range/adaptor/indexed.hpp
+++ /dev/null
@@ -1,156 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
-#define BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
-
-#include <boost/config.hpp>
-#ifdef BOOST_MSVC
-#pragma warning( push )
-#pragma warning( disable : 4355 )
-#endif
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-
-
-
-namespace boost
-{
-    namespace adaptors
-    {
-        // This structure exists to carry the parameters from the '|' operator
-        // to the index adapter. The expression rng | indexed(1) instantiates
-        // this structure and passes it as the right-hand operand to the
-        // '|' operator.
-        struct indexed
-        {
-            explicit indexed(std::size_t x) : val(x) {}
-            std::size_t val;
-        };
-    }
-
-    namespace range_detail
-    {
-        template< class Iter >
-        class indexed_iterator
-            : public boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
-        {
-        private:
-            typedef boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
-                  base;
-
-            typedef BOOST_DEDUCED_TYPENAME base::difference_type index_type;
-
-            index_type m_index;
-
-        public:
-            explicit indexed_iterator( Iter i, index_type index )
-            : base(i), m_index(index)
-            {
-                BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
-            }
-
-            index_type index() const
-            {
-                return m_index;
-            }
-
-         private:
-            friend class boost::iterator_core_access;
-
-            void increment()
-            {
-                ++m_index;
-                ++(this->base_reference());
-            }
-
-
-            void decrement()
-            {
-                BOOST_ASSERT( m_index > 0 && "Indexed Iterator out of bounds" );
-                --m_index;
-                --(this->base_reference());
-            }
-
-            void advance( index_type n )
-            {
-                m_index += n;
-                BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
-                this->base_reference() += n;
-            }
-        };
-
-        template< class Rng >
-        struct indexed_range :
-            iterator_range< indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> >
-        {
-        private:
-            typedef indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type>
-                iter_type;
-            typedef iterator_range<iter_type>
-                base;
-        public:
-            template< class Index >
-            indexed_range( Index i, Rng& r )
-              : base( iter_type(boost::begin(r), i), iter_type(boost::end(r),i) )
-            { }
-        };
-
-    } // 'range_detail'
-
-    // Make this available to users of this library. It will sometimes be
-    // required since it is the return type of operator '|' and
-    // index().
-    using range_detail::indexed_range;
-
-    namespace adaptors
-    {
-        template< class SinglePassRange >
-        inline indexed_range<SinglePassRange>
-        operator|( SinglePassRange& r,
-                   const indexed& f )
-        {
-            return indexed_range<SinglePassRange>( f.val, r );
-        }
-
-        template< class SinglePassRange >
-        inline indexed_range<const SinglePassRange>
-        operator|( const SinglePassRange& r,
-                   const indexed& f )
-        {
-            return indexed_range<const SinglePassRange>( f.val, r );
-        }
-
-        template<class SinglePassRange, class Index>
-        inline indexed_range<SinglePassRange>
-        index(SinglePassRange& rng, Index index_value)
-        {
-            return indexed_range<SinglePassRange>(index_value, rng);
-        }
-
-        template<class SinglePassRange, class Index>
-        inline indexed_range<const SinglePassRange>
-        index(const SinglePassRange& rng, Index index_value)
-        {
-            return indexed_range<const SinglePassRange>(index_value, rng);
-        }
-    } // 'adaptors'
-
-}
-
-#ifdef BOOST_MSVC
-#pragma warning( pop )
-#endif
-
-#endif
diff --git a/src/boost/range/adaptor/indirected.hpp b/src/boost/range/adaptor/indirected.hpp
deleted file mode 100644
index d7edc18..0000000
--- a/src/boost/range/adaptor/indirected.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
-#define BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
-
-#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/indirect_iterator.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class R >
-        struct indirected_range :
-            public boost::iterator_range<
-                        boost::indirect_iterator<
-                            BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                        >
-                    >
-        {
-        private:
-            typedef boost::iterator_range<
-                        boost::indirect_iterator<
-                            BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                        >
-                    >
-                base;
-
-        public:
-            explicit indirected_range( R& r )
-                : base( r )
-            { }
-        };
-
-        struct indirect_forwarder {};
-
-        template< class InputRng >
-        inline indirected_range<InputRng>
-        operator|( InputRng& r, indirect_forwarder )
-        {
-            return indirected_range<InputRng>( r );
-        }
-
-        template< class InputRng >
-        inline indirected_range<const InputRng>
-        operator|( const InputRng& r, indirect_forwarder )
-        {
-            return indirected_range<const InputRng>( r );
-        }
-
-    } // 'range_detail'
-
-    using range_detail::indirected_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::indirect_forwarder indirected =
-                                            range_detail::indirect_forwarder();
-        }
-
-        template<class InputRange>
-        inline indirected_range<InputRange>
-        indirect(InputRange& rng)
-        {
-            return indirected_range<InputRange>(rng);
-        }
-
-        template<class InputRange>
-        inline indirected_range<const InputRange>
-        indirect(const InputRange& rng)
-        {
-            return indirected_range<const InputRange>(rng);
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptor/map.hpp b/src/boost/range/adaptor/map.hpp
deleted file mode 100644
index ff8b97e..0000000
--- a/src/boost/range/adaptor/map.hpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_MAP_HPP
-#define BOOST_RANGE_ADAPTOR_MAP_HPP
-
-#include <boost/range/adaptor/transformed.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/reference.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        struct map_keys_forwarder {};
-        struct map_values_forwarder {};
-
-        template< class Map >
-        struct select_first
-        {
-            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
-            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type;
-
-            result_type operator()( argument_type r ) const
-            {
-                return r.first;
-            }
-        };
-
-        template< class Map >
-        struct select_second_mutable
-        {
-            typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type;
-            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type;
-
-            result_type operator()( argument_type r ) const
-            {
-                return r.second;
-            }
-        };
-
-        template< class Map >
-        struct select_second_const
-        {
-            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
-            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type;
-
-            result_type operator()( argument_type r ) const
-            {
-                return r.second;
-            }
-        };
-
-        template<class StdPairRng>
-        class select_first_range
-            : public transformed_range<
-                        select_first<StdPairRng>,
-                        const StdPairRng>
-        {
-            typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base;
-        public:
-            typedef select_first<StdPairRng> transform_fn_type;
-            typedef const StdPairRng source_range_type;
-
-            select_first_range(transform_fn_type fn, source_range_type& rng)
-                : base(fn, rng)
-            {
-            }
-
-            select_first_range(const base& other) : base(other) {}
-        };
-
-        template<class StdPairRng>
-        class select_second_mutable_range
-            : public transformed_range<
-                        select_second_mutable<StdPairRng>,
-                        StdPairRng>
-        {
-            typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base;
-        public:
-            typedef select_second_mutable<StdPairRng> transform_fn_type;
-            typedef StdPairRng source_range_type;
-
-            select_second_mutable_range(transform_fn_type fn, source_range_type& rng)
-                : base(fn, rng)
-            {
-            }
-
-            select_second_mutable_range(const base& other) : base(other) {}
-        };
-
-        template<class StdPairRng>
-        class select_second_const_range
-            : public transformed_range<
-                        select_second_const<StdPairRng>,
-                        const StdPairRng>
-        {
-            typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base;
-        public:
-            typedef select_second_const<StdPairRng> transform_fn_type;
-            typedef const StdPairRng source_range_type;
-
-            select_second_const_range(transform_fn_type fn, source_range_type& rng)
-                : base(fn, rng)
-            {
-            }
-
-            select_second_const_range(const base& other) : base(other) {}
-        };
-
-        template< class StdPairRng >
-        inline select_first_range<StdPairRng>
-        operator|( const StdPairRng& r, map_keys_forwarder )
-        {
-            return operator|( r,
-                boost::adaptors::transformed( select_first<StdPairRng>() ) );
-        }
-
-        template< class StdPairRng >
-        inline select_second_mutable_range<StdPairRng>
-        operator|( StdPairRng& r, map_values_forwarder )
-        {
-            return operator|( r,
-                boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
-        }
-
-        template< class StdPairRng >
-        inline select_second_const_range<StdPairRng>
-        operator|( const StdPairRng& r, map_values_forwarder )
-        {
-            return operator|( r,
-                boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
-        }
-
-    } // 'range_detail'
-
-    using range_detail::select_first_range;
-    using range_detail::select_second_mutable_range;
-    using range_detail::select_second_const_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::map_keys_forwarder map_keys =
-                                            range_detail::map_keys_forwarder();
-
-            const range_detail::map_values_forwarder map_values =
-                                           range_detail::map_values_forwarder();
-        }
-
-        template<class StdPairRange>
-        inline select_first_range<StdPairRange>
-        keys(const StdPairRange& rng)
-        {
-            return select_first_range<StdPairRange>(
-                range_detail::select_first<StdPairRange>(), rng );
-        }
-
-        template<class StdPairRange>
-        inline select_second_const_range<StdPairRange>
-        values(const StdPairRange& rng)
-        {
-            return select_second_const_range<StdPairRange>(
-                range_detail::select_second_const<StdPairRange>(), rng );
-        }
-
-        template<class StdPairRange>
-        inline select_second_mutable_range<StdPairRange>
-        values(StdPairRange& rng)
-        {
-            return select_second_mutable_range<StdPairRange>(
-                range_detail::select_second_mutable<StdPairRange>(), rng );
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptor/replaced.hpp b/src/boost/range/adaptor/replaced.hpp
deleted file mode 100644
index deeb8da..0000000
--- a/src/boost/range/adaptor/replaced.hpp
+++ /dev/null
@@ -1,134 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2007. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
-#define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/iterator/transform_iterator.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class Value >
-        class replace_value
-        {
-        public:
-            typedef const Value& result_type;
-            typedef const Value& first_argument_type;
-
-            replace_value(const Value& from, const Value& to)
-                :   m_from(from), m_to(to)
-            {
-            }
-
-            const Value& operator()(const Value& x) const
-            {
-                return (x == m_from) ? m_to : x;
-            }
-
-        private:
-            Value m_from;
-            Value m_to;
-        };
-
-        template< class R >
-        class replaced_range :
-            public boost::iterator_range<
-                boost::transform_iterator<
-                    replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
-                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
-        {
-        private:
-            typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
-
-            typedef boost::iterator_range<
-                boost::transform_iterator<
-                    replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
-                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
-
-        public:
-            typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
-
-            replaced_range( R& r, value_type from, value_type to )
-                : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
-                          make_transform_iterator( boost::end(r), Fn(from, to) ) )
-            { }
-        };
-
-        template< class T >
-        class replace_holder : public holder2<T>
-        {
-        public:
-            replace_holder( const T& from, const T& to )
-                : holder2<T>(from, to)
-            { }
-        private:
-            // not assignable
-            void operator=(const replace_holder&);
-        };
-
-        template< class InputRng >
-        inline replaced_range<InputRng>
-        operator|( InputRng& r,
-                   const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
-        {
-            return replaced_range<InputRng>(r, f.val1, f.val2);
-        }
-
-        template< class InputRng >
-        inline replaced_range<const InputRng>
-        operator|( const InputRng& r,
-                   const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
-        {
-            return replaced_range<const InputRng>(r, f.val1, f.val2);
-        }
-    } // 'range_detail'
-
-    using range_detail::replaced_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::forwarder2<range_detail::replace_holder>
-                replaced =
-                    range_detail::forwarder2<range_detail::replace_holder>();
-        }
-
-        template<class InputRange>
-        inline replaced_range<InputRange>
-        replace(InputRange& rng,
-                BOOST_DEDUCED_TYPENAME range_value<InputRange>::type from,
-                BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
-        {
-            return replaced_range<InputRange>(rng, from, to);
-        }
-
-        template<class InputRange>
-        inline replaced_range<const InputRange>
-        replace(const InputRange& rng,
-                BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type from,
-                BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
-        {
-            return replaced_range<const InputRange>(rng, from ,to);
-        }
-
-    } // 'adaptors'
-} // 'boost'
-
-#endif // include guard
diff --git a/src/boost/range/adaptor/replaced_if.hpp b/src/boost/range/adaptor/replaced_if.hpp
deleted file mode 100644
index b514354..0000000
--- a/src/boost/range/adaptor/replaced_if.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2007. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
-#define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/iterator/transform_iterator.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class Pred, class Value >
-        class replace_value_if
-        {
-        public:
-            typedef const Value& result_type;
-            typedef const Value& first_argument_type;
-
-            replace_value_if(const Pred& pred, const Value& to)
-                :   m_pred(pred), m_to(to)
-            {
-            }
-
-            const Value& operator()(const Value& x) const
-            {
-                return m_pred(x) ? m_to : x;
-            }
-
-        private:
-            Pred  m_pred;
-            Value m_to;
-        };
-
-        template< class Pred, class R >
-        class replaced_if_range :
-            public boost::iterator_range<
-                boost::transform_iterator<
-                    replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
-                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
-        {
-        private:
-            typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
-
-            typedef boost::iterator_range<
-                boost::transform_iterator<
-                    replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
-                    BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
-
-        public:
-            typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
-
-            replaced_if_range( R& r, const Pred& pred, value_type to )
-                : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
-                          make_transform_iterator( boost::end(r), Fn(pred, to) ) )
-            { }
-        };
-
-        template< class Pred, class T >
-        class replace_if_holder
-        {
-        public:
-            replace_if_holder( const Pred& pred, const T& to )
-                : m_pred(pred), m_to(to)
-            { }
-
-            const Pred& pred() const { return m_pred; }
-            const T& to() const { return m_to; }
-
-        private:
-            Pred m_pred;
-            T m_to;
-        };
-
-        template< class Pred, class InputRng >
-        inline replaced_if_range<Pred, InputRng>
-        operator|( InputRng& r,
-                   const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
-        {
-            return replaced_if_range<Pred, InputRng>(r, f.pred(), f.to());
-        }
-
-        template< class Pred, class InputRng >
-        inline replaced_if_range<Pred, const InputRng>
-        operator|( const InputRng& r,
-                   const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
-        {
-            return replaced_if_range<Pred, const InputRng>(r, f.pred(), f.to());
-        }
-    } // 'range_detail'
-
-    using range_detail::replaced_if_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::forwarder2TU<range_detail::replace_if_holder>
-                replaced_if =
-                    range_detail::forwarder2TU<range_detail::replace_if_holder>();
-        }
-        
-        template<class Pred, class InputRange>
-        inline replaced_if_range<Pred, InputRange>
-        replace_if(InputRange& rng, Pred pred,
-                   BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
-        {
-            return range_detail::replaced_if_range<Pred, InputRange>(rng, pred, to);
-        }
-
-        template<class Pred, class InputRange>
-        inline replaced_if_range<Pred, const InputRange>
-        replace_if(const InputRange& rng, Pred pred,
-                   BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
-        {
-            return range_detail::replaced_if_range<Pred, const InputRange>(rng, pred, to);
-        }
-    } // 'adaptors'
-    
-} // 'boost'
-
-#endif // include guard
diff --git a/src/boost/range/adaptor/reversed.hpp b/src/boost/range/adaptor/reversed.hpp
deleted file mode 100644
index c85eda8..0000000
--- a/src/boost/range/adaptor/reversed.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_REVERSED_HPP
-#define BOOST_RANGE_ADAPTOR_REVERSED_HPP
-
-#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/reverse_iterator.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class R >
-        struct reversed_range : 
-            public boost::iterator_range< 
-                      boost::reverse_iterator<
-                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
-                                              >
-                                         >
-        {
-        private:
-            typedef boost::iterator_range< 
-                      boost::reverse_iterator<
-                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
-                                              >
-                                         >
-                base;
-            
-        public:
-            typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator;
-
-            explicit reversed_range( R& r ) 
-                : base( iterator(boost::end(r)), iterator(boost::begin(r)) )
-            { }
-        };
-
-        struct reverse_forwarder {};
-        
-        template< class BidirectionalRng >
-        inline reversed_range<BidirectionalRng> 
-        operator|( BidirectionalRng& r, reverse_forwarder )
-        {
-            return reversed_range<BidirectionalRng>( r );   
-        }
-    
-        template< class BidirectionalRng >
-        inline reversed_range<const BidirectionalRng> 
-        operator|( const BidirectionalRng& r, reverse_forwarder )
-        {
-            return reversed_range<const BidirectionalRng>( r );   
-        }
-        
-    } // 'range_detail'
-    
-    using range_detail::reversed_range;
-
-    namespace adaptors
-    { 
-        namespace
-        {
-            const range_detail::reverse_forwarder reversed = 
-                                            range_detail::reverse_forwarder();
-        }
-        
-        template<class BidirectionalRange>
-        inline reversed_range<BidirectionalRange>
-        reverse(BidirectionalRange& rng)
-        {
-            return reversed_range<BidirectionalRange>(rng);
-        }
-        
-        template<class BidirectionalRange>
-        inline reversed_range<const BidirectionalRange>
-        reverse(const BidirectionalRange& rng)
-        {
-            return reversed_range<const BidirectionalRange>(rng);
-        }
-    } // 'adaptors'
-    
-} // 'boost'
-
-#endif
diff --git a/src/boost/range/adaptor/sliced.hpp b/src/boost/range/adaptor/sliced.hpp
deleted file mode 100644
index 14ad986..0000000
--- a/src/boost/range/adaptor/sliced.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_SLICED_HPP
-#define BOOST_RANGE_ADAPTOR_SLICED_HPP
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace adaptors
-    {
-        struct sliced
-        {
-            sliced(std::size_t t_, std::size_t u_)
-                : t(t_), u(u_) {}
-            std::size_t t;
-            std::size_t u;
-        };
-
-        template< class RandomAccessRange >
-        class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
-        {
-            typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
-        public:
-            template<typename Rng, typename T, typename U>
-            sliced_range(Rng& rng, T t, U u)
-                : base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
-            {
-            }
-        };
-
-        template< class RandomAccessRange >
-        inline sliced_range<RandomAccessRange>
-        slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
-        {
-            BOOST_ASSERT( t <= u && "error in slice indices" );
-            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
-                          "second slice index out of bounds" );
-
-            return sliced_range<RandomAccessRange>(rng, t, u);
-        }
-
-        template< class RandomAccessRange >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
-        slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
-        {
-            BOOST_ASSERT( t <= u && "error in slice indices" );
-            BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
-                          "second slice index out of bounds" );
-
-            return sliced_range<const RandomAccessRange>(rng, t, u);
-        }
-
-        template< class RandomAccessRange >
-        inline sliced_range<RandomAccessRange>
-        operator|( RandomAccessRange& r, const sliced& f )
-        {
-            return sliced_range<RandomAccessRange>( r, f.t, f.u );
-        }
-
-        template< class RandomAccessRange >
-        inline sliced_range<const RandomAccessRange>
-        operator|( const RandomAccessRange& r, const sliced& f )
-        {
-            return sliced_range<const RandomAccessRange>( r, f.t, f.u );
-        }
-
-    } // namespace adaptors
-    using adaptors::sliced_range;
-} // namespace boost
-
-#endif
diff --git a/src/boost/range/adaptor/strided.hpp b/src/boost/range/adaptor/strided.hpp
deleted file mode 100644
index e843f62..0000000
--- a/src/boost/range/adaptor/strided.hpp
+++ /dev/null
@@ -1,350 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2007. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
-#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <iterator>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        // strided_iterator for wrapping a forward traversal iterator
-        template<class BaseIterator, class Category>
-        class strided_iterator
-            : public iterator_adaptor<
-                strided_iterator<BaseIterator, Category>
-              , BaseIterator
-              , use_default
-              , boost::forward_traversal_tag
-            >
-        {
-            friend class ::boost::iterator_core_access;
-
-            typedef iterator_adaptor<
-                        strided_iterator<BaseIterator, Category>
-                      , BaseIterator
-                      , use_default
-                      , boost::forward_traversal_tag
-                    > super_t;
-
-        public:
-            typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
-            typedef BaseIterator base_iterator;
-
-            strided_iterator()
-                : m_last()
-                , m_stride()
-            {
-            }
-
-            strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
-                : super_t(it)
-                , m_last(last)
-                , m_stride(stride)
-            {
-            }
-
-            template<class OtherIterator>
-            strided_iterator(const strided_iterator<OtherIterator, Category>& other,
-                             BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
-                : super_t(other)
-                , m_last(other.base_end())
-                , m_stride(other.get_stride())
-            {
-            }
-
-            base_iterator base_end() const { return m_last; }
-            difference_type get_stride() const { return m_stride; }
-
-        private:
-            void increment()
-            {
-                base_iterator& it = this->base_reference();
-                for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
-                    ++it;
-            }
-
-            base_iterator m_last;
-            difference_type m_stride;
-        };
-
-        // strided_iterator for wrapping a bidirectional iterator
-        template<class BaseIterator>
-        class strided_iterator<BaseIterator, bidirectional_traversal_tag>
-            : public iterator_adaptor<
-                strided_iterator<BaseIterator, bidirectional_traversal_tag>
-              , BaseIterator
-              , use_default
-              , bidirectional_traversal_tag
-            >
-        {
-            friend class ::boost::iterator_core_access;
-
-            typedef iterator_adaptor<
-                        strided_iterator<BaseIterator, bidirectional_traversal_tag>
-                      , BaseIterator
-                      , use_default
-                      , bidirectional_traversal_tag
-                    > super_t;
-        public:
-            typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
-            typedef BaseIterator base_iterator;
-
-            strided_iterator()
-                : m_first()
-                , m_last()
-                , m_stride()
-            {
-            }
-
-            strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
-                : super_t(it)
-                , m_first(first)
-                , m_last(last)
-                , m_stride(stride)
-            {
-            }
-
-            template<class OtherIterator>
-            strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other,
-                             BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
-                : super_t(other.base())
-                , m_first(other.base_begin())
-                , m_last(other.base_end())
-                , m_stride(other.get_stride())
-            {
-            }
-
-            base_iterator base_begin() const { return m_first; }
-            base_iterator base_end() const { return m_last; }
-            difference_type get_stride() const { return m_stride; }
-
-        private:
-            void increment()
-            {
-                base_iterator& it = this->base_reference();
-                for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
-                    ++it;
-            }
-
-            void decrement()
-            {
-                base_iterator& it = this->base_reference();
-                for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i)
-                    --it;
-            }
-
-            base_iterator m_first;
-            base_iterator m_last;
-            difference_type m_stride;
-        };
-
-        // strided_iterator implementation for wrapping a random access iterator
-        template<class BaseIterator>
-        class strided_iterator<BaseIterator, random_access_traversal_tag>
-            : public iterator_adaptor<
-                        strided_iterator<BaseIterator, random_access_traversal_tag>
-                      , BaseIterator
-                      , use_default
-                      , random_access_traversal_tag
-                    >
-        {
-            friend class ::boost::iterator_core_access;
-
-            typedef iterator_adaptor<
-                        strided_iterator<BaseIterator, random_access_traversal_tag>
-                      , BaseIterator
-                      , use_default
-                      , random_access_traversal_tag
-                    > super_t;
-        public:
-            typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type;
-            typedef BaseIterator base_iterator;
-
-            strided_iterator()
-                : m_first()
-                , m_last()
-                , m_index(0)
-                , m_stride()
-            {
-            }
-
-            strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride)
-                : super_t(it)
-                , m_first(first)
-                , m_last(last)
-                , m_index(stride ? (it - first) / stride : 0)
-                , m_stride(stride)
-            {
-            }
-
-            template<class OtherIterator>
-            strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
-                             BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
-                : super_t(other.base())
-                , m_first(other.base_begin())
-                , m_last(other.base_end())
-                , m_index(other.get_index())
-                , m_stride(other.get_stride())
-            {
-            }
-
-            base_iterator base_begin() const { return m_first; }
-            base_iterator base_end() const { return m_last; }
-            difference_type get_stride() const { return m_stride; }
-            difference_type get_index() const { return m_index; }
-
-        private:
-            void increment()
-            {
-                m_index += m_stride;
-                if (m_index < (m_last - m_first))
-                    this->base_reference() = m_first + m_index;
-                else
-                    this->base_reference() = m_last;
-            }
-
-            void decrement()
-            {
-                m_index -= m_stride;
-                if (m_index >= 0)
-                    this->base_reference() = m_first + m_index;
-                else
-                    this->base_reference() = m_first;
-            }
-
-            void advance(difference_type offset)
-            {
-                offset *= m_stride;
-                m_index += offset;
-                if (m_index < 0)
-                    this->base_reference() = m_first;
-                else if (m_index > (m_last - m_first))
-                    this->base_reference() = m_last;
-                else
-                    this->base_reference() = m_first + m_index;
-            }
-
-            template<class OtherIterator>
-            difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
-                                        BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
-            {
-                if (other.base() >= this->base())
-                    return (other.base() - this->base() + (m_stride - 1)) / m_stride;
-                return (other.base() - this->base() - (m_stride - 1)) / m_stride;
-            }
-
-            bool equal(const strided_iterator& other) const
-            {
-                return this->base() == other.base();
-            }
-
-        private:
-            base_iterator m_first;
-            base_iterator m_last;
-            difference_type m_index;
-            difference_type m_stride;
-        };
-
-        template<class BaseIterator, class Difference> inline
-        strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type>
-        make_strided_iterator(BaseIterator first, BaseIterator it,
-                              BaseIterator last, Difference stride)
-        {
-            BOOST_ASSERT( stride >= 0 );
-            typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag;
-            return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride);
-        }
-
-        template< class Rng
-                , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal<
-                                    BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type
-                                   >::type
-         >
-        class strided_range
-            : public iterator_range<
-                        range_detail::strided_iterator<
-                            BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
-                            Category
-                        >
-                     >
-        {
-            typedef range_detail::strided_iterator<
-                        BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
-                        Category
-                    > iter_type;
-            typedef iterator_range<iter_type> super_t;
-        public:
-            template<class Difference>
-            strided_range(Difference stride, Rng& rng)
-                : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride),
-                          make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride))
-            {
-                BOOST_ASSERT( stride >= 0 );
-            }
-        };
-
-        template<class Difference>
-        class strided_holder : public holder<Difference>
-        {
-        public:
-            explicit strided_holder(Difference value) : holder<Difference>(value) {}
-        };
-
-        template<class Rng, class Difference>
-        inline strided_range<Rng>
-        operator|(Rng& rng, const strided_holder<Difference>& stride)
-        {
-            return strided_range<Rng>(stride.val, rng);
-        }
-
-        template<class Rng, class Difference>
-        inline strided_range<const Rng>
-        operator|(const Rng& rng, const strided_holder<Difference>& stride)
-        {
-            return strided_range<const Rng>(stride.val, rng);
-        }
-
-    } // namespace range_detail
-
-    using range_detail::strided_range;
-
-    namespace adaptors
-    {
-
-        namespace
-        {
-            const range_detail::forwarder<range_detail::strided_holder>
-                strided = range_detail::forwarder<range_detail::strided_holder>();
-        }
-
-        template<class Range, class Difference>
-        inline strided_range<Range>
-        stride(Range& rng, Difference step)
-        {
-            return strided_range<Range>(step, rng);
-        }
-
-        template<class Range, class Difference>
-        inline strided_range<const Range>
-        stride(const Range& rng, Difference step)
-        {
-            return strided_range<const Range>(step, rng);
-        }
-
-    } // namespace 'adaptors'
-} // namespace 'boost'
-
-#endif
diff --git a/src/boost/range/adaptor/tokenized.hpp b/src/boost/range/adaptor/tokenized.hpp
deleted file mode 100644
index 8a7402a..0000000
--- a/src/boost/range/adaptor/tokenized.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
-#define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
-
-#include <boost/regex.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-        template< class R >
-        struct tokenized_range : 
-            public boost::iterator_range< 
-                      boost::regex_token_iterator< 
-                          BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
-                                              >
-                                         >
-        {
-        private:
-            typedef           
-                boost::regex_token_iterator< 
-                          BOOST_DEDUCED_TYPENAME range_iterator<R>::type 
-                                            >
-                regex_iter;
-            
-            typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type 
-                regex_type;
-        
-            typedef boost::iterator_range<regex_iter> 
-                base;
-
-        public:
-            template< class Regex, class Submatch, class Flag >
-            tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f )
-              : base( regex_iter( boost::begin(r), boost::end(r), 
-                                  regex_type(re), sub, f ),
-                      regex_iter() )
-            { }
-        };
-
-        template< class T, class U, class V >
-        struct regex_holder
-        {
-            const T&  re;
-            const U&  sub;
-            V         f;
-
-            regex_holder( const T& rex, const U& subm, V flag ) :
-                re(rex), sub(subm), f(flag)
-            { }
-        private:
-            // Not assignable
-            void operator=(const regex_holder&);
-        };
-
-        struct regex_forwarder
-        {           
-            template< class Regex >
-            regex_holder<Regex,int,regex_constants::match_flag_type>
-            operator()( const Regex& re, 
-                        int submatch = 0,    
-                        regex_constants::match_flag_type f = 
-                            regex_constants::match_default ) const
-            {
-                return regex_holder<Regex,int,
-                           regex_constants::match_flag_type>( re, submatch, f );
-            }
-             
-            template< class Regex, class Submatch >
-            regex_holder<Regex,Submatch,regex_constants::match_flag_type> 
-            operator()( const Regex& re, 
-                        const Submatch& sub, 
-                        regex_constants::match_flag_type f = 
-                            regex_constants::match_default ) const
-            {
-                return regex_holder<Regex,Submatch,
-                           regex_constants::match_flag_type>( re, sub, f ); 
-            }
-        };
-        
-        template< class BidirectionalRng, class R, class S, class F >
-        inline tokenized_range<BidirectionalRng> 
-        operator|( BidirectionalRng& r, 
-                   const regex_holder<R,S,F>& f )
-        {
-            return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );   
-        }
-
-        template< class BidirectionalRng, class R, class S, class F  >
-        inline tokenized_range<const BidirectionalRng> 
-        operator|( const BidirectionalRng& r, 
-                   const regex_holder<R,S,F>& f )
-        {
-            return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
-        }
-        
-    } // 'range_detail'
-
-    using range_detail::tokenized_range;
-
-    namespace adaptors
-    { 
-        namespace
-        {
-            const range_detail::regex_forwarder tokenized = 
-                    range_detail::regex_forwarder();
-        }
-        
-        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
-        inline tokenized_range<BidirectionalRange>
-        tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
-        {
-            return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
-        }
-        
-        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
-        inline tokenized_range<const BidirectionalRange>
-        tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
-        {
-            return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
-        }
-    } // 'adaptors'
-    
-}
-
-#endif
diff --git a/src/boost/range/adaptor/transformed.hpp b/src/boost/range/adaptor/transformed.hpp
deleted file mode 100644
index 96d2dab..0000000
--- a/src/boost/range/adaptor/transformed.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
-#define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
-
-#include <boost/range/adaptor/argument_fwd.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/transform_iterator.hpp>
-#include <boost/utility/result_of.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-        template< class F, class R >
-        struct transformed_range :
-            public boost::iterator_range<
-                      boost::transform_iterator< F,
-                          BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                                              >
-                                         >
-        {
-        private:
-            typedef boost::iterator_range<
-                      boost::transform_iterator< F,
-                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type
-                                              >
-                                         >
-                base;
-
-        public:
-            typedef F transform_fn_type;
-            typedef R source_range_type;
-
-            transformed_range( F f, R& r )
-                : base( boost::make_transform_iterator( boost::begin(r), f ),
-                        boost::make_transform_iterator( boost::end(r), f ) )
-
-            { }
-        };
-
-        template< class T >
-        struct transform_holder : holder<T>
-        {
-            transform_holder( T r ) : holder<T>(r)
-            { }
-        };
-
-        template< class InputRng, class UnaryFunction >
-        inline transformed_range<UnaryFunction,InputRng>
-        operator|( InputRng& r,
-                   const transform_holder<UnaryFunction>& f )
-        {
-            return transformed_range<UnaryFunction,InputRng>( f.val, r );
-        }
-
-        template< class InputRng, class UnaryFunction >
-        inline transformed_range<UnaryFunction, const InputRng>
-        operator|( const InputRng& r,
-                   const transform_holder<UnaryFunction>& f )
-        {
-           return transformed_range<UnaryFunction, const InputRng>( f.val, r );
-        }
-
-    } // 'range_detail'
-
-    using range_detail::transformed_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::forwarder<range_detail::transform_holder>
-                    transformed =
-                      range_detail::forwarder<range_detail::transform_holder>();
-        }
-
-        template<class UnaryFunction, class InputRange>
-        inline transformed_range<UnaryFunction, InputRange>
-        transform(InputRange& rng, UnaryFunction fn)
-        {
-            return transformed_range<UnaryFunction, InputRange>(fn, rng);
-        }
-
-        template<class UnaryFunction, class InputRange>
-        inline transformed_range<UnaryFunction, const InputRange>
-        transform(const InputRange& rng, UnaryFunction fn)
-        {
-            return transformed_range<UnaryFunction, const InputRange>(fn, rng);
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptor/type_erased.hpp b/src/boost/range/adaptor/type_erased.hpp
deleted file mode 100644
index 80bc712..0000000
--- a/src/boost/range/adaptor/type_erased.hpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
-#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
-
-#include <boost/range/reference.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/iterator_range_core.hpp>
-#include <boost/range/any_range.hpp>
-#include <boost/cast.hpp>
-
-namespace boost
-{
-    namespace adaptors
-    {
-        template<
-            class Value = use_default
-          , class Traversal = use_default
-          , class Reference = use_default
-          , class Difference = use_default
-          , class Buffer = use_default
-        >
-        struct type_erased
-        {
-        };
-
-        template<
-            class SinglePassRange
-          , class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        typename any_range_type_generator<
-            SinglePassRange
-          , Value
-          , Traversal
-          , Reference
-          , Difference
-          , Buffer
-        >::type
-        operator|(SinglePassRange& rng,
-                  type_erased<
-                        Value
-                      , Traversal
-                      , Reference
-                      , Difference
-                      , Buffer
-                    >)
-        {
-            typedef typename any_range_type_generator<
-                SinglePassRange
-              , Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >::type range_type;
-            return range_type(boost::begin(rng), boost::end(rng));
-        }
-
-        template<
-            class SinglePassRange
-          , class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        typename any_range_type_generator<
-            const SinglePassRange
-          , Value
-          , Traversal
-          , Reference
-          , Difference
-          , Buffer
-        >::type
-        operator|(const SinglePassRange& rng,
-                  type_erased<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                    >)
-        {
-            typedef typename any_range_type_generator<
-                const SinglePassRange
-              , Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >::type range_type;
-            return range_type(boost::begin(rng), boost::end(rng));
-        }
-
-        template<
-            class SinglePassRange
-          , class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        typename any_range_type_generator<
-            SinglePassRange
-          , Value
-          , Traversal
-          , Reference
-          , Difference
-          , Buffer
-        >::type
-        type_erase(SinglePassRange& rng
-                 , type_erased<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                    > = type_erased<>()
-                )
-        {
-            typedef typename any_range_type_generator<
-                SinglePassRange
-              , Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >::type range_type;
-
-            return range_type(boost::begin(rng), boost::end(rng));
-        }
-
-        template<
-            class SinglePassRange
-          , class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        typename any_range_type_generator<
-            const SinglePassRange
-          , Value
-          , Traversal
-          , Reference
-          , Difference
-          , Buffer
-        >::type
-        type_erase(const SinglePassRange& rng
-                 , type_erased<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                    > = type_erased<>()
-                )
-        {
-            typedef typename any_range_type_generator<
-                const SinglePassRange
-              , Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >::type range_type;
-
-            return range_type(boost::begin(rng), boost::end(rng));
-        }
-    }
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/adaptor/uniqued.hpp b/src/boost/range/adaptor/uniqued.hpp
deleted file mode 100644
index 40c8249..0000000
--- a/src/boost/range/adaptor/uniqued.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
-#define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
-
-#include <boost/range/adaptor/adjacent_filtered.hpp>
-
-namespace boost
-{
-
-    namespace range_detail
-    {
-        struct unique_forwarder { };
-
-        struct unique_not_equal_to
-        {
-            typedef bool result_type;
-
-            template< class T >
-            bool operator()( const T& l, const T& r ) const
-            {
-                return !(l == r);
-            }
-        };
-
-        template<class ForwardRng>
-        class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
-        {
-            typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
-        public:
-            explicit uniqued_range(ForwardRng& rng)
-                : base(unique_not_equal_to(), rng)
-            {
-            }
-        };
-
-        template< class ForwardRng >
-        inline uniqued_range<ForwardRng>
-        operator|( ForwardRng& r,
-                   unique_forwarder )
-        {
-            return uniqued_range<ForwardRng>(r);
-        }
-
-        template< class ForwardRng >
-        inline uniqued_range<const ForwardRng>
-        operator|( const ForwardRng& r,
-                   unique_forwarder )
-        {
-            return uniqued_range<const ForwardRng>(r);
-        }
-
-    } // 'range_detail'
-
-    using range_detail::uniqued_range;
-
-    namespace adaptors
-    {
-        namespace
-        {
-            const range_detail::unique_forwarder uniqued =
-                       range_detail::unique_forwarder();
-        }
-
-        template<class ForwardRange>
-        inline uniqued_range<ForwardRange>
-        unique(ForwardRange& rng)
-        {
-            return uniqued_range<ForwardRange>(rng);
-        }
-
-        template<class ForwardRange>
-        inline uniqued_range<const ForwardRange>
-        unique(const ForwardRange& rng)
-        {
-            return uniqued_range<const ForwardRange>(rng);
-        }
-    } // 'adaptors'
-
-}
-
-#endif
diff --git a/src/boost/range/adaptors.hpp b/src/boost/range/adaptors.hpp
deleted file mode 100644
index 92062a9..0000000
--- a/src/boost/range/adaptors.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2007.
-//  Copyright Thorsten Ottosen 2006.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ADAPTORS_HPP
-#define BOOST_RANGE_ADAPTORS_HPP
-
-#include <boost/range/adaptor/adjacent_filtered.hpp>
-#include <boost/range/adaptor/copied.hpp>
-#include <boost/range/adaptor/filtered.hpp>
-#include <boost/range/adaptor/indexed.hpp>
-#include <boost/range/adaptor/indirected.hpp>
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/adaptor/replaced.hpp>
-#include <boost/range/adaptor/replaced_if.hpp>
-#include <boost/range/adaptor/reversed.hpp>
-#include <boost/range/adaptor/sliced.hpp>
-#include <boost/range/adaptor/strided.hpp>
-#include <boost/range/adaptor/tokenized.hpp>
-#include <boost/range/adaptor/transformed.hpp>
-#include <boost/range/adaptor/uniqued.hpp>
-
-#endif
diff --git a/src/boost/range/algorithm.hpp b/src/boost/range/algorithm.hpp
deleted file mode 100644
index b7d8dd7..0000000
--- a/src/boost/range/algorithm.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file algorithm.hpp
-///   Includes the range-based versions of the algorithms in the
-///   C++ standard header file <algorithm>
-//
-/////////////////////////////////////////////////////////////////////////////
-
-// Copyright 2009 Neil Groves.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// Acknowledgements:
-// This code uses combinations of ideas, techniques and code snippets
-// from: Thorsten Ottosen, Eric Niebler, Jeremy Siek,
-// and Vladimir Prus'
-//
-// The original mutating algorithms that served as the first version
-// were originally written by Vladimir Prus'
-// <ghost at cs.msu.su> code from Boost Wiki
-
-#if defined(_MSC_VER) && _MSC_VER >= 1000
-#pragma once
-#endif
-
-#ifndef BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
-#define BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
-
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include <boost/next_prior.hpp>
-#include <algorithm>
-
-// Non-mutating algorithms
-#include <boost/range/algorithm/adjacent_find.hpp>
-#include <boost/range/algorithm/count.hpp>
-#include <boost/range/algorithm/count_if.hpp>
-#include <boost/range/algorithm/equal.hpp>
-#include <boost/range/algorithm/for_each.hpp>
-#include <boost/range/algorithm/find.hpp>
-#include <boost/range/algorithm/find_end.hpp>
-#include <boost/range/algorithm/find_first_of.hpp>
-#include <boost/range/algorithm/find_if.hpp>
-#include <boost/range/algorithm/lexicographical_compare.hpp>
-#include <boost/range/algorithm/mismatch.hpp>
-#include <boost/range/algorithm/search.hpp>
-#include <boost/range/algorithm/search_n.hpp>
-
-// Mutating algorithms
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/range/algorithm/copy_backward.hpp>
-#include <boost/range/algorithm/fill.hpp>
-#include <boost/range/algorithm/fill_n.hpp>
-#include <boost/range/algorithm/generate.hpp>
-#include <boost/range/algorithm/inplace_merge.hpp>
-#include <boost/range/algorithm/merge.hpp>
-#include <boost/range/algorithm/nth_element.hpp>
-#include <boost/range/algorithm/partial_sort.hpp>
-#include <boost/range/algorithm/partial_sort_copy.hpp>
-#include <boost/range/algorithm/partition.hpp>
-#include <boost/range/algorithm/random_shuffle.hpp>
-#include <boost/range/algorithm/remove.hpp>
-#include <boost/range/algorithm/remove_copy.hpp>
-#include <boost/range/algorithm/remove_copy_if.hpp>
-#include <boost/range/algorithm/remove_if.hpp>
-#include <boost/range/algorithm/replace.hpp>
-#include <boost/range/algorithm/replace_copy.hpp>
-#include <boost/range/algorithm/replace_copy_if.hpp>
-#include <boost/range/algorithm/replace_if.hpp>
-#include <boost/range/algorithm/reverse.hpp>
-#include <boost/range/algorithm/reverse_copy.hpp>
-#include <boost/range/algorithm/rotate.hpp>
-#include <boost/range/algorithm/rotate_copy.hpp>
-#include <boost/range/algorithm/sort.hpp>
-#include <boost/range/algorithm/stable_partition.hpp>
-#include <boost/range/algorithm/stable_sort.hpp>
-#include <boost/range/algorithm/transform.hpp>
-#include <boost/range/algorithm/unique.hpp>
-#include <boost/range/algorithm/unique_copy.hpp>
-
-// Binary search
-#include <boost/range/algorithm/binary_search.hpp>
-#include <boost/range/algorithm/equal_range.hpp>
-#include <boost/range/algorithm/lower_bound.hpp>
-#include <boost/range/algorithm/upper_bound.hpp>
-
-// Set operations of sorted ranges
-#include <boost/range/algorithm/set_algorithm.hpp>
-
-// Heap operations
-#include <boost/range/algorithm/heap_algorithm.hpp>
-
-// Minimum and Maximum
-#include <boost/range/algorithm/max_element.hpp>
-#include <boost/range/algorithm/min_element.hpp>
-
-// Permutations
-#include <boost/range/algorithm/permutation.hpp>
-
-#endif // include guard
-
diff --git a/src/boost/range/algorithm/adjacent_find.hpp b/src/boost/range/algorithm/adjacent_find.hpp
deleted file mode 100644
index 1b88dae..0000000
--- a/src/boost/range/algorithm/adjacent_find.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function adjacent_find
-///
-/// range-based version of the adjacent_find std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< typename ForwardRange >
-inline typename range_iterator<ForwardRange>::type
-adjacent_find(ForwardRange & rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return std::adjacent_find(boost::begin(rng),boost::end(rng));
-}
-
-/// \overload
-template< typename ForwardRange >
-inline typename range_iterator<const ForwardRange>::type
-adjacent_find(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return std::adjacent_find(boost::begin(rng),boost::end(rng));
-}
-
-/// \overload
-template< typename ForwardRange, typename BinaryPredicate >
-inline typename range_iterator<ForwardRange>::type
-adjacent_find(ForwardRange & rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        typename range_value<ForwardRange>::type,
-        typename range_value<ForwardRange>::type>));
-    return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
-}
-
-/// \overload
-template< typename ForwardRange, typename BinaryPredicate >
-inline typename range_iterator<const ForwardRange>::type
-adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        typename range_value<const ForwardRange>::type,
-        typename range_value<const ForwardRange>::type>));
-    return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
-}
-
-//  range_return overloads
-
-/// \overload
-template< range_return_value re, typename ForwardRange >
-inline typename range_return<ForwardRange,re>::type
-adjacent_find(ForwardRange & rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return range_return<ForwardRange,re>::
-        pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, typename ForwardRange >
-inline typename range_return<const ForwardRange,re>::type
-adjacent_find(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return range_return<const ForwardRange,re>::
-        pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
-inline typename range_return<ForwardRange,re>::type
-adjacent_find(ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        typename range_value<ForwardRange>::type,
-        typename range_value<ForwardRange>::type>));
-    return range_return<ForwardRange,re>::
-        pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
-inline typename range_return<const ForwardRange,re>::type
-adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return range_return<const ForwardRange,re>::
-        pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
-             rng);
-}
-
-    } // namespace range
-    using range::adjacent_find;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/binary_search.hpp b/src/boost/range/algorithm/binary_search.hpp
deleted file mode 100644
index bb64ec8..0000000
--- a/src/boost/range/algorithm/binary_search.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function binary_search
-///
-/// range-based version of the binary_search std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class ForwardRange, class Value>
-inline bool binary_search(const ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::binary_search(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template<class ForwardRange, class Value, class BinaryPredicate>
-inline bool binary_search(const ForwardRange& rng, const Value& val,
-                          BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::binary_search(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-    } // namespace range
-    using range::binary_search;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/copy.hpp b/src/boost/range/algorithm/copy.hpp
deleted file mode 100644
index f15b31f..0000000
--- a/src/boost/range/algorithm/copy.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function copy
-///
-/// range-based version of the copy std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre OutputIterator is a model of the OutputIteratorConcept
-template< class SinglePassRange, class OutputIterator >
-inline OutputIterator copy(const SinglePassRange& rng, OutputIterator out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::copy(boost::begin(rng),boost::end(rng),out);
-}
-
-    } // namespace range
-    using range::copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/copy_backward.hpp b/src/boost/range/algorithm/copy_backward.hpp
deleted file mode 100644
index c95c6f1..0000000
--- a/src/boost/range/algorithm/copy_backward.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function copy_backward
-///
-/// range-based version of the copy_backwards std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-/// \pre BidirectionalTraversalWriteableIterator is a model of the BidirectionalIteratorConcept
-/// \pre BidirectionalTraversalWriteableIterator is a model of the WriteableIteratorConcept
-template< class BidirectionalRange, class BidirectionalTraversalWriteableIterator >
-inline BidirectionalTraversalWriteableIterator
-copy_backward(const BidirectionalRange& rng,
-              BidirectionalTraversalWriteableIterator out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::copy_backward(boost::begin(rng), boost::end(rng), out);
-}
-
-    } // namespace range
-    using range::copy_backward;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/count.hpp b/src/boost/range/algorithm/count.hpp
deleted file mode 100644
index 8316ce0..0000000
--- a/src/boost/range/algorithm/count.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function count
-///
-/// range-based version of the count std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-template< class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
-count(SinglePassRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return std::count(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
-count(const SinglePassRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::count(boost::begin(rng), boost::end(rng), val);
-}
-
-    } // namespace range
-    using range::count;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/count_if.hpp b/src/boost/range/algorithm/count_if.hpp
deleted file mode 100644
index ae17b0e..0000000
--- a/src/boost/range/algorithm/count_if.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function count_if
-///
-/// range-based version of the count_if std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
-template< class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
-count_if(SinglePassRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return std::count_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template< class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
-count_if(const SinglePassRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::count_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-    } // namespace range
-    using range::count_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/equal.hpp b/src/boost/range/algorithm/equal.hpp
deleted file mode 100644
index 4472bb1..0000000
--- a/src/boost/range/algorithm/equal.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <iterator>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        // An implementation of equality comparison that is optimized for iterator
-        // traversal categories less than RandomAccessTraversal.
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2,
-                  class IteratorCategoryTag1,
-                  class IteratorCategoryTag2 >
-        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
-                                SinglePassTraversalReadableIterator1 last1,
-                                SinglePassTraversalReadableIterator2 first2,
-                                SinglePassTraversalReadableIterator2 last2,
-                                IteratorCategoryTag1,
-                                IteratorCategoryTag2 )
-        {
-            while (true)
-            {
-                // If we have reached the end of the left range then this is
-                // the end of the loop. They are equal if and only if we have
-                // simultaneously reached the end of the right range.
-                if (first1 == last1)
-                    return first2 == last2;
-
-                // If we have reached the end of the right range at this line
-                // it indicates that the right range is shorter than the left
-                // and hence the result is false.
-                if (first2 == last2)
-                    return false;
-
-                // continue looping if and only if the values are equal
-                if (*first1 != *first2)
-                    break;
-
-                ++first1;
-                ++first2;
-            }
-
-            // Reaching this line in the algorithm indicates that a value
-            // inequality has been detected.
-            return false;
-        }
-
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2,
-                  class IteratorCategoryTag1,
-                  class IteratorCategoryTag2,
-                  class BinaryPredicate >
-        inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
-                                SinglePassTraversalReadableIterator1 last1,
-                                SinglePassTraversalReadableIterator2 first2,
-                                SinglePassTraversalReadableIterator2 last2,
-                                BinaryPredicate                      pred,
-                                IteratorCategoryTag1,
-                                IteratorCategoryTag2 )
-        {
-            while (true)
-            {
-                // If we have reached the end of the left range then this is
-                // the end of the loop. They are equal if and only if we have
-                // simultaneously reached the end of the right range.
-                if (first1 == last1)
-                    return first2 == last2;
-
-                // If we have reached the end of the right range at this line
-                // it indicates that the right range is shorter than the left
-                // and hence the result is false.
-                if (first2 == last2)
-                    return false;
-
-                // continue looping if and only if the values are equal
-                if (!pred(*first1, *first2))
-                    break;
-
-                ++first1;
-                ++first2;
-            }
-
-            // Reaching this line in the algorithm indicates that a value
-            // inequality has been detected.
-            return false;
-        }
-
-        // An implementation of equality comparison that is optimized for
-        // random access iterators.
-        template< class RandomAccessTraversalReadableIterator1,
-                  class RandomAccessTraversalReadableIterator2 >
-        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
-                                RandomAccessTraversalReadableIterator1 last1,
-                                RandomAccessTraversalReadableIterator2 first2,
-                                RandomAccessTraversalReadableIterator2 last2,
-                                std::random_access_iterator_tag,
-                                std::random_access_iterator_tag )
-        {
-            return ((last1 - first1) == (last2 - first2))
-                && std::equal(first1, last1, first2);
-        }
-
-        template< class RandomAccessTraversalReadableIterator1,
-                  class RandomAccessTraversalReadableIterator2,
-                  class BinaryPredicate >
-        inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
-                                RandomAccessTraversalReadableIterator1 last1,
-                                RandomAccessTraversalReadableIterator2 first2,
-                                RandomAccessTraversalReadableIterator2 last2,
-                                BinaryPredicate                        pred )
-        {
-            return ((last1 - first1) == (last2 - first2))
-                && std::equal(first1, last1, first2, pred);
-        }
-
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2 >
-        inline bool equal( SinglePassTraversalReadableIterator1 first1,
-                           SinglePassTraversalReadableIterator1 last1,
-                           SinglePassTraversalReadableIterator2 first2,
-                           SinglePassTraversalReadableIterator2 last2 )
-        {
-            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
-            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
-
-            return equal_impl(first1, last1, first2, last2, tag1, tag2);
-        }
-
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2,
-                  class BinaryPredicate >
-        inline bool equal( SinglePassTraversalReadableIterator1 first1,
-                           SinglePassTraversalReadableIterator1 last1,
-                           SinglePassTraversalReadableIterator2 first2,
-                           SinglePassTraversalReadableIterator2 last2,
-                           BinaryPredicate                      pred )
-        {
-            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
-            BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
-
-            return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
-        }
-
-    } // namespace range_detail
-
-    namespace range
-    {
-
-        /// \brief template function equal
-        ///
-        /// range-based version of the equal std algorithm
-        ///
-        /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-        /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-        /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-        template< class SinglePassRange1, class SinglePassRange2 >
-        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-            return ::boost::range_detail::equal(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2) );
-        }
-
-        /// \overload
-        template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
-        inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
-                           BinaryPredicate pred )
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-            return ::boost::range_detail::equal(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2),
-                pred);
-        }
-
-    } // namespace range
-    using ::boost::range::equal;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/equal_range.hpp b/src/boost/range/algorithm/equal_range.hpp
deleted file mode 100644
index 4aa4a54..0000000
--- a/src/boost/range/algorithm/equal_range.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function equal_range
-///
-/// range-based version of the equal_range std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre SortPredicate is a model of the BinaryPredicateConcept
-template<class ForwardRange, class Value>
-inline std::pair<
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
-       >
-equal_range(ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::equal_range(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template<class ForwardRange, class Value>
-inline std::pair<
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
-       >
-equal_range(const ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::equal_range(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template<class ForwardRange, class Value, class SortPredicate>
-inline std::pair<
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
-       >
-equal_range(ForwardRange& rng, const Value& val, SortPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-/// \overload
-template<class ForwardRange, class Value, class SortPredicate>
-inline std::pair<
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
-        BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
-       >
-equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-    } // namespace range
-    using range::equal_range;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/fill.hpp b/src/boost/range/algorithm/fill.hpp
deleted file mode 100644
index 95231a8..0000000
--- a/src/boost/range/algorithm/fill.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function fill
-///
-/// range-based version of the fill std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class Value >
-inline ForwardRange& fill(ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    std::fill(boost::begin(rng), boost::end(rng), val);
-    return rng;
-}
-
-/// \overload
-template< class ForwardRange, class Value >
-inline const ForwardRange& fill(const ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    std::fill(boost::begin(rng), boost::end(rng), val);
-    return rng;
-}
-
-    } // namespace range
-    using range::fill;
-}
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/fill_n.hpp b/src/boost/range/algorithm/fill_n.hpp
deleted file mode 100644
index 02a0c2a..0000000
--- a/src/boost/range/algorithm/fill_n.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
-
-#include <boost/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function fill_n
-///
-/// range-based version of the fill_n std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre n <= std::distance(boost::begin(rng), boost::end(rng))
-template< class ForwardRange, class Size, class Value >
-inline ForwardRange& fill_n(ForwardRange& rng, Size n, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
-    std::fill_n(boost::begin(rng), n, val);
-    return rng;
-}
-
-/// \overload
-template< class ForwardRange, class Size, class Value >
-inline const ForwardRange& fill_n(const ForwardRange& rng, Size n, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
-    std::fill_n(boost::begin(rng), n, val);
-    return rng;
-}
-
-    } // namespace range
-    using range::fill_n;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/find.hpp b/src/boost/range/algorithm/find.hpp
deleted file mode 100644
index 72c5cf1..0000000
--- a/src/boost/range/algorithm/find.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function find
-///
-/// range-based version of the find std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-template< class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
->::type
-find( SinglePassRange& rng, const Value& val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return std::find(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
-find( const SinglePassRange& rng, const Value& val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::find(boost::begin(rng), boost::end(rng), val);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange>,
-    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
->::type
-find( SinglePassRange& rng, const Value& val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return range_return<SinglePassRange,re>::
-        pack(std::find(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class SinglePassRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
-find( const SinglePassRange& rng, const Value& val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return range_return<const SinglePassRange,re>::
-        pack(std::find(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-    } // namespace range
-    using range::find;
-}
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/find_end.hpp b/src/boost/range/algorithm/find_end.hpp
deleted file mode 100644
index 757e999..0000000
--- a/src/boost/range/algorithm/find_end.hpp
+++ /dev/null
@@ -1,152 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function find_end
-///
-/// range-based version of the find_end std algorithm
-///
-/// \pre ForwardRange1 is a model of the ForwardRangeConcept
-/// \pre ForwardRange2 is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange1>,
-    BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type
->::type
-find_end(ForwardRange1 & rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_end(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type
-find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_end(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange1>,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
->::type
-find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_end(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2),pred);
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
-find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_end(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2),pred);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange1>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
->::type
-find_end(ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<ForwardRange1,re>::
-        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
-                           boost::begin(rng2), boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
-find_end(const ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<const ForwardRange1,re>::
-        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
-                           boost::begin(rng2), boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange1>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
->::type
-find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<ForwardRange1,re>::
-        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
-                           boost::begin(rng2), boost::end(rng2), pred),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
-find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<const ForwardRange1,re>::
-        pack(std::find_end(boost::begin(rng1), boost::end(rng1),
-                           boost::begin(rng2), boost::end(rng2), pred),
-             rng1);
-}
-
-    } // namespace range
-    using range::find_end;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/find_first_of.hpp b/src/boost/range/algorithm/find_first_of.hpp
deleted file mode 100644
index 4cb5989..0000000
--- a/src/boost/range/algorithm/find_first_of.hpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function find_first_of
-///
-/// range-based version of the find_first_of std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre ForwardRange2 is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< class SinglePassRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange1>,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
->::type
-find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
-                              boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template< class SinglePassRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
-find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
-                              boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange1>,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
->::type
-find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
-                              boost::begin(rng2),boost::end(rng2),pred);
-}
-
-/// \overload
-template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
-find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return std::find_first_of(boost::begin(rng1),boost::end(rng1),
-                              boost::begin(rng2),boost::end(rng2),pred);
-}
-
-// range return overloads
-/// \overload
-template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange1>,
-    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
->::type
-find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<SinglePassRange1,re>::
-        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
-                                boost::begin(rng2), boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
-find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<const SinglePassRange1,re>::
-        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
-                                boost::begin(rng2), boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class SinglePassRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange1>,
-    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
->::type
-find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2,
-              BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<SinglePassRange1,re>::
-        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
-                                boost::begin(rng2), boost::end(rng2), pred),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class SinglePassRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
-find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2,
-              BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-
-    return range_return<const SinglePassRange1,re>::
-        pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
-                                boost::begin(rng2), boost::end(rng2), pred),
-             rng1);
-}
-
-    } // namespace range
-    using range::find_first_of;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/find_if.hpp b/src/boost/range/algorithm/find_if.hpp
deleted file mode 100644
index 2d1926d..0000000
--- a/src/boost/range/algorithm/find_if.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function find_if
-///
-/// range-based version of the find_if std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
-template< class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
->::type
-find_if( SinglePassRange& rng, UnaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return std::find_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template< class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
-find_if( const SinglePassRange& rng, UnaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::find_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<SinglePassRange>,
-    BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
->::type
-find_if( SinglePassRange& rng, UnaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    return range_return<SinglePassRange,re>::
-        pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class SinglePassRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
-find_if( const SinglePassRange& rng, UnaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return range_return<const SinglePassRange,re>::
-        pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
-             rng);
-}
-
-    } // namespace range
-    using range::find_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/for_each.hpp b/src/boost/range/algorithm/for_each.hpp
deleted file mode 100644
index 4f5108d..0000000
--- a/src/boost/range/algorithm/for_each.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/ref.hpp>
-#include <algorithm>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
-#include <xutility>
-#endif
-
-namespace boost
-{
-    namespace range
-    {
-
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
-        namespace for_each_detail
-        {
-            template<typename Iterator, typename UnaryFunction>
-            inline UnaryFunction
-            for_each_impl(Iterator first, Iterator last, UnaryFunction fun,
-                          typename enable_if<
-                            is_reference_wrapper<UnaryFunction>,
-                            void
-                          >::type* = 0)
-            {
-                    typedef typename std::_Get_unchecked_type<Iterator>::type
-                                unchecked_iterator;
-
-                    unchecked_iterator unchecked_last = std::_Unchecked(last);
-                    for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first)
-                            fun.get()(*unchecked_first);
-
-                    return fun;
-            }
-
-            template<typename Iterator, typename UnaryFunction>
-            inline UnaryFunction
-            for_each_impl(Iterator first, Iterator last, UnaryFunction fn,
-                          typename disable_if<
-                            is_reference_wrapper<UnaryFunction>,
-                            void
-                          >::type* = 0)
-            {
-                return std::for_each<Iterator, UnaryFunction>(first, last, fn);
-            }
-        }
-#endif
-
-/// \brief template function for_each
-///
-/// range-based version of the for_each std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre UnaryFunction is a model of the UnaryFunctionConcept
-template< class SinglePassRange, class UnaryFunction >
-inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-    
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
-        return for_each_detail::for_each_impl<
-                typename range_iterator<SinglePassRange>::type,
-                UnaryFunction
-        >(boost::begin(rng), boost::end(rng), fun);
-#else
-    return std::for_each<
-        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
-        UnaryFunction
-    >(boost::begin(rng),boost::end(rng),fun);
-#endif    
-}
-
-/// \overload
-template< class SinglePassRange, class UnaryFunction >
-inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
-        return for_each_detail::for_each_impl<
-                typename range_iterator<const SinglePassRange>::type,
-                UnaryFunction
-        >(boost::begin(rng), boost::end(rng), fun);
-#else    
-    return std::for_each<
-        BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type,
-        UnaryFunction
-    >(boost::begin(rng), boost::end(rng), fun);
-#endif    
-}
-
-    } // namespace range
-    using range::for_each;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/generate.hpp b/src/boost/range/algorithm/generate.hpp
deleted file mode 100644
index 324412c..0000000
--- a/src/boost/range/algorithm/generate.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-/// \brief template function generate
-///
-/// range-based version of the generate std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre Generator is a model of the UnaryFunctionConcept
-template< class ForwardRange, class Generator >
-inline ForwardRange& generate( ForwardRange& rng, Generator gen )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    std::generate(boost::begin(rng), boost::end(rng), gen);
-    return rng;
-}
-
-/// \overload
-template< class ForwardRange, class Generator >
-inline const ForwardRange& generate( const ForwardRange& rng, Generator gen )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    std::generate(boost::begin(rng), boost::end(rng), gen);
-    return rng;
-}
-
-    } // namespace range
-    using range::generate;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/heap_algorithm.hpp b/src/boost/range/algorithm/heap_algorithm.hpp
deleted file mode 100644
index 584920d..0000000
--- a/src/boost/range/algorithm/heap_algorithm.hpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function push_heap
-///
-/// range-based version of the push_heap std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& push_heap(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::push_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& push_heap(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::push_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \brief template function pop_heap
-///
-/// range-based version of the pop_heap std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& pop_heap(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::pop_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::pop_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \brief template function make_heap
-///
-/// range-based version of the make_heap std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& make_heap(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::make_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& make_heap(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::make_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \brief template function sort_heap
-///
-/// range-based version of the sort_heap std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& sort_heap(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::sort_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::sort_heap(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Compare>
-inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::push_heap;
-    using range::pop_heap;
-    using range::make_heap;
-    using range::sort_heap;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/inplace_merge.hpp b/src/boost/range/algorithm/inplace_merge.hpp
deleted file mode 100644
index dfadbaa..0000000
--- a/src/boost/range/algorithm/inplace_merge.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function inplace_merge
-///
-/// range-based version of the inplace_merge std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class BidirectionalRange>
-inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class BidirectionalRange>
-inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
-    BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class BidirectionalRange, class BinaryPredicate>
-inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
-    BOOST_DEDUCED_TYPENAME boost::range_iterator<BidirectionalRange>::type middle,
-    BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
-    return rng;
-}
-
-/// \overload
-template<class BidirectionalRange, class BinaryPredicate>
-inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
-    BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle,
-    BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::inplace_merge;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/lexicographical_compare.hpp b/src/boost/range/algorithm/lexicographical_compare.hpp
deleted file mode 100644
index c6e4bc8..0000000
--- a/src/boost/range/algorithm/lexicographical_compare.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function lexicographic_compare
-///
-/// range-based version of the lexicographic_compare std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-template<class SinglePassRange1, class SinglePassRange2>
-inline bool lexicographical_compare(const SinglePassRange1& rng1,
-                                    const SinglePassRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::lexicographical_compare(
-        boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2));
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class BinaryPredicate>
-inline bool lexicographical_compare(const SinglePassRange1& rng1,
-                                    const SinglePassRange2& rng2,
-                                    BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::lexicographical_compare(
-        boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2), pred);
-}
-
-    } // namespace range
-    using range::lexicographical_compare;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/lower_bound.hpp b/src/boost/range/algorithm/lower_bound.hpp
deleted file mode 100644
index cb5e639..0000000
--- a/src/boost/range/algorithm/lower_bound.hpp
+++ /dev/null
@@ -1,124 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function lower_bound
-///
-/// range-based version of the lower_bound std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
->::type
-lower_bound( ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::lower_bound(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-lower_bound( const ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::lower_bound(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
->::type
-lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-/// \overload
-template< class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
->::type
-lower_bound( ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-lower_bound( const ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
->::type
-lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
-             rng);
-}
-
-    } // namespace range
-    using range::lower_bound;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/max_element.hpp b/src/boost/range/algorithm/max_element.hpp
deleted file mode 100644
index a0c1ffd..0000000
--- a/src/boost/range/algorithm/max_element.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function max_element
-///
-/// range-based version of the max_element std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-max_element(ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::max_element(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-max_element(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::max_element(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-max_element(ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::max_element(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template<class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-max_element(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::max_element(boost::begin(rng), boost::end(rng), pred);
-}
-
-// range_return overloads
-
-/// \overload
-template<range_return_value re, class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-max_element(ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::max_element(boost::begin(rng), boost::end(rng)),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-max_element(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::max_element(boost::begin(rng), boost::end(rng)),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-max_element(ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::max_element(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-max_element(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::max_element(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-    } // namespace range
-    using range::max_element;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/merge.hpp b/src/boost/range/algorithm/merge.hpp
deleted file mode 100644
index c81b8c7..0000000
--- a/src/boost/range/algorithm/merge.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function merge
-///
-/// range-based version of the merge std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-///
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator>
-inline OutputIterator merge(const SinglePassRange1& rng1,
-                            const SinglePassRange2& rng2,
-                            OutputIterator          out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::merge(boost::begin(rng1), boost::end(rng1),
-                      boost::begin(rng2), boost::end(rng2), out);
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator, class BinaryPredicate>
-inline OutputIterator merge(const SinglePassRange1& rng1,
-                            const SinglePassRange2& rng2,
-                            OutputIterator          out,
-                            BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::merge(boost::begin(rng1), boost::end(rng1),
-                      boost::begin(rng2), boost::end(rng2), out, pred);
-}
-
-    } // namespace range
-    using range::merge;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/min_element.hpp b/src/boost/range/algorithm/min_element.hpp
deleted file mode 100644
index c966b1e..0000000
--- a/src/boost/range/algorithm/min_element.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function min_element
-///
-/// range-based version of the min_element std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-min_element(ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::min_element(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-min_element(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::min_element(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-min_element(ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::min_element(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template<class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-min_element(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::min_element(boost::begin(rng), boost::end(rng), pred);
-}
-
-// range_return overloads
-
-/// \overload
-template<range_return_value re, class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-min_element(ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::min_element(boost::begin(rng), boost::end(rng)),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange>
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-min_element(const ForwardRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::min_element(boost::begin(rng), boost::end(rng)),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-min_element(ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::min_element(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class ForwardRange, class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-min_element(const ForwardRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::min_element(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-    } // namespace range
-    using range::min_element;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/mismatch.hpp b/src/boost/range/algorithm/mismatch.hpp
deleted file mode 100644
index 2819c33..0000000
--- a/src/boost/range/algorithm/mismatch.hpp
+++ /dev/null
@@ -1,195 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2 >
-        inline std::pair<SinglePassTraversalReadableIterator1,
-                         SinglePassTraversalReadableIterator2>
-        mismatch_impl(SinglePassTraversalReadableIterator1 first1,
-                      SinglePassTraversalReadableIterator1 last1,
-                      SinglePassTraversalReadableIterator2 first2,
-                      SinglePassTraversalReadableIterator2 last2)
-        {
-            while (first1 != last1 && first2 != last2 && *first1 == *first2)
-            {
-                ++first1;
-                ++first2;
-            }
-            return std::pair<SinglePassTraversalReadableIterator1,
-                             SinglePassTraversalReadableIterator2>(first1, first2);
-        }
-
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2,
-                  class BinaryPredicate >
-        inline std::pair<SinglePassTraversalReadableIterator1,
-                         SinglePassTraversalReadableIterator2>
-        mismatch_impl(SinglePassTraversalReadableIterator1 first1,
-                      SinglePassTraversalReadableIterator1 last1,
-                      SinglePassTraversalReadableIterator2 first2,
-                      SinglePassTraversalReadableIterator2 last2,
-                      BinaryPredicate pred)
-        {
-            while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
-            {
-                ++first1;
-                ++first2;
-            }
-            return std::pair<SinglePassTraversalReadableIterator1,
-                             SinglePassTraversalReadableIterator2>(first1, first2);
-        }
-    } // namespace range_detail
-
-    namespace range
-    {
-/// \brief template function mismatch
-///
-/// range-based version of the mismatch std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< class SinglePassRange1, class SinglePassRange2 >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
-mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2));
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
-mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2));
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
-mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2));
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
-mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2));
-}
-
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
-mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2), pred);
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
-mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2), pred);
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
-mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2), pred);
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
-inline std::pair<
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
-mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return ::boost::range_detail::mismatch_impl(
-        ::boost::begin(rng1), ::boost::end(rng1),
-        ::boost::begin(rng2), ::boost::end(rng2), pred);
-}
-
-    } // namespace range
-    using range::mismatch;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/nth_element.hpp b/src/boost/range/algorithm/nth_element.hpp
deleted file mode 100644
index a605595..0000000
--- a/src/boost/range/algorithm/nth_element.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function nth_element
-///
-/// range-based version of the nth_element std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& nth_element(RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::nth_element(boost::begin(rng), nth, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::nth_element(boost::begin(rng), nth, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline RandomAccessRange& nth_element(RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth,
-    BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth,
-    BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::nth_element;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/partial_sort.hpp b/src/boost/range/algorithm/partial_sort.hpp
deleted file mode 100644
index d7044cd..0000000
--- a/src/boost/range/algorithm/partial_sort.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function partial_sort
-///
-/// range-based version of the partial_sort std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::partial_sort(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
-    BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
-                        sort_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
-    BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::partial_sort(boost::begin(rng), middle, boost::end(rng),
-                        sort_pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::partial_sort;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/partial_sort_copy.hpp b/src/boost/range/algorithm/partial_sort_copy.hpp
deleted file mode 100644
index 9129389..0000000
--- a/src/boost/range/algorithm/partial_sort_copy.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/value_type.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function partial_sort_copy
-///
-/// range-based version of the partial_sort_copy std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre RandomAccessRange is a model of the Mutable_RandomAccessRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange, class RandomAccessRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
-partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-
-    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2));
-}
-
-/// \overload
-template<class SinglePassRange, class RandomAccessRange>
-inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
-partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-
-    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2));
-}
-
-/// \overload
-template<class SinglePassRange, class RandomAccessRange,
-         class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
-partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2,
-    BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-
-    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2), pred);
-}
-
-/// \overload
-template<class SinglePassRange, class RandomAccessRange,
-         class BinaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type
-partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2,
-    BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-
-    return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2), pred);
-}
-
-    } // namespace range
-    using range::partial_sort_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/partition.hpp b/src/boost/range/algorithm/partition.hpp
deleted file mode 100644
index b814a24..0000000
--- a/src/boost/range/algorithm/partition.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function partition
-///
-/// range-based version of the partition std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template<class ForwardRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-partition(ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::partition(boost::begin(rng),boost::end(rng),pred);
-}
-
-/// \overload
-template<class ForwardRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-partition(const ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::partition(boost::begin(rng),boost::end(rng),pred);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class ForwardRange,
-          class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-partition(ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return boost::range_return<ForwardRange,re>::
-        pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange,
-          class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-partition(const ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return boost::range_return<const ForwardRange,re>::
-        pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
-}
-
-    } // namespace range
-    using range::partition;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/permutation.hpp b/src/boost/range/algorithm/permutation.hpp
deleted file mode 100644
index 75388cc..0000000
--- a/src/boost/range/algorithm/permutation.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function next_permutation
-///
-/// range-based version of the next_permutation std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class BidirectionalRange>
-inline bool next_permutation(BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return std::next_permutation(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class BidirectionalRange>
-inline bool next_permutation(const BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::next_permutation(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class BidirectionalRange, class Compare>
-inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return std::next_permutation(boost::begin(rng), boost::end(rng),
-                                 comp_pred);
-}
-
-/// \overload
-template<class BidirectionalRange, class Compare>
-inline bool next_permutation(const BidirectionalRange& rng,
-                             Compare                   comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::next_permutation(boost::begin(rng), boost::end(rng),
-                                 comp_pred);
-}
-
-/// \brief template function prev_permutation
-///
-/// range-based version of the prev_permutation std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-/// \pre Compare is a model of the BinaryPredicateConcept
-template<class BidirectionalRange>
-inline bool prev_permutation(BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return std::prev_permutation(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class BidirectionalRange>
-inline bool prev_permutation(const BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::prev_permutation(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class BidirectionalRange, class Compare>
-inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return std::prev_permutation(boost::begin(rng), boost::end(rng),
-                                 comp_pred);
-}
-
-/// \overload
-template<class BidirectionalRange, class Compare>
-inline bool prev_permutation(const BidirectionalRange& rng,
-                             Compare                   comp_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::prev_permutation(boost::begin(rng), boost::end(rng),
-                                 comp_pred);
-}
-
-    } // namespace range
-    using range::next_permutation;
-    using range::prev_permutation;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/random_shuffle.hpp b/src/boost/range/algorithm/random_shuffle.hpp
deleted file mode 100644
index 95bbd97..0000000
--- a/src/boost/range/algorithm/random_shuffle.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function random_shuffle
-///
-/// range-based version of the random_shuffle std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre Generator is a model of the UnaryFunctionConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::random_shuffle(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::random_shuffle(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Generator>
-inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class Generator>
-inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
-    return rng;
-}
-
-    } // namespace range
-    using range::random_shuffle;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/remove.hpp b/src/boost/range/algorithm/remove.hpp
deleted file mode 100644
index 699a7cd..0000000
--- a/src/boost/range/algorithm/remove.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function remove
-///
-/// range-based version of the remove std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-remove(ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::remove(boost::begin(rng),boost::end(rng),val);
-}
-
-/// \overload
-template< class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-remove(const ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::remove(boost::begin(rng),boost::end(rng),val);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-remove(ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::remove(boost::begin(rng), boost::end(rng), val),
-        rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-remove(const ForwardRange& rng, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::remove(boost::begin(rng), boost::end(rng), val),
-        rng);
-}
-
-    } // namespace range
-    using range::remove;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/remove_copy.hpp b/src/boost/range/algorithm/remove_copy.hpp
deleted file mode 100644
index b65747e..0000000
--- a/src/boost/range/algorithm/remove_copy.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function remove_copy
-///
-/// range-based version of the remove_copy std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre OutputIterator is a model of the OutputIteratorConcept
-/// \pre Value is a model of the EqualityComparableConcept
-/// \pre Objects of type Value can be compared for equality with objects of
-/// InputIterator's value type.
-template< class SinglePassRange, class OutputIterator, class Value >
-inline OutputIterator
-remove_copy(const SinglePassRange& rng, OutputIterator out_it, const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::remove_copy(boost::begin(rng), boost::end(rng), out_it, val);
-}
-
-    } // namespace range
-    using range::remove_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/remove_copy_if.hpp b/src/boost/range/algorithm/remove_copy_if.hpp
deleted file mode 100644
index 8d9c37b..0000000
--- a/src/boost/range/algorithm/remove_copy_if.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    /// \brief template function remove_copy_if
-    ///
-    /// range-based version of the remove_copy_if std algorithm
-    ///
-    /// \pre SinglePassRange is a model of the SinglePassRangeConcept
-    /// \pre OutputIterator is a model of the OutputIteratorConcept
-    /// \pre Predicate is a model of the PredicateConcept
-    /// \pre InputIterator's value type is convertible to Predicate's argument type
-    /// \pre out_it is not an iterator in the range rng
-    template< class SinglePassRange, class OutputIterator, class Predicate >
-    inline OutputIterator
-    remove_copy_if(const SinglePassRange& rng, OutputIterator out_it, Predicate pred)
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred);
-    }
-}
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/remove_if.hpp b/src/boost/range/algorithm/remove_if.hpp
deleted file mode 100644
index a965df0..0000000
--- a/src/boost/range/algorithm/remove_if.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function remove_if
-///
-/// range-based version of the remove_if std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
-template< class ForwardRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
-remove_if(ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::remove_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template< class ForwardRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
-remove_if(const ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::remove_if(boost::begin(rng), boost::end(rng), pred);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class ForwardRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-remove_if(ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::pack(
-        std::remove_if(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class UnaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-remove_if(const ForwardRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::pack(
-        std::remove_if(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-    } // namespace range
-    using range::remove_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/replace.hpp b/src/boost/range/algorithm/replace.hpp
deleted file mode 100644
index 44d3e4c..0000000
--- a/src/boost/range/algorithm/replace.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function replace
-///
-/// range-based version of the replace std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class Value >
-inline ForwardRange&
-replace(ForwardRange& rng, const Value& what,
-        const Value& with_what)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    std::replace(boost::begin(rng), boost::end(rng), what, with_what);
-    return rng;
-}
-
-/// \overload
-template< class ForwardRange, class Value >
-inline const ForwardRange&
-replace(const ForwardRange& rng, const Value& what,
-        const Value& with_what)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    std::replace(boost::begin(rng), boost::end(rng), what, with_what);
-    return rng;
-}
-
-    } // namespace range
-    using range::replace;
-} // namespace boost;
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/replace_copy.hpp b/src/boost/range/algorithm/replace_copy.hpp
deleted file mode 100644
index 0c02005..0000000
--- a/src/boost/range/algorithm/replace_copy.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function replace_copy
-///
-/// range-based version of the replace_copy std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class OutputIterator, class Value >
-inline OutputIterator
-replace_copy(const ForwardRange& rng, OutputIterator out_it, const Value& what,
-        const Value& with_what)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
-        what, with_what);
-}
-
-    } // namespace range
-    using range::replace_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/replace_copy_if.hpp b/src/boost/range/algorithm/replace_copy_if.hpp
deleted file mode 100644
index d313151..0000000
--- a/src/boost/range/algorithm/replace_copy_if.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function replace_copy_if
-///
-/// range-based version of the replace_copy_if std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre Predicate is a model of the PredicateConcept
-/// \pre Value is convertible to Predicate's argument type
-/// \pre Value is Assignable
-/// \pre Value is convertible to a type in OutputIterator's set of value types.
-template< class ForwardRange, class OutputIterator, class Predicate, class Value >
-inline OutputIterator
-replace_copy_if(const ForwardRange& rng, OutputIterator out_it, Predicate pred,
-        const Value& with_what)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::replace_copy_if(boost::begin(rng), boost::end(rng), out_it,
-        pred, with_what);
-}
-
-    } // namespace range
-    using range::replace_copy_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/replace_if.hpp b/src/boost/range/algorithm/replace_if.hpp
deleted file mode 100644
index 93d5a1f..0000000
--- a/src/boost/range/algorithm/replace_if.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function replace_if
-///
-/// range-based version of the replace_if std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
-template< class ForwardRange, class UnaryPredicate, class Value >
-inline ForwardRange&
-    replace_if(ForwardRange& rng, UnaryPredicate pred,
-               const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
-    return rng;
-}
-
-/// \overload
-template< class ForwardRange, class UnaryPredicate, class Value >
-inline const ForwardRange&
-    replace_if(const ForwardRange& rng, UnaryPredicate pred,
-               const Value& val)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
-    return rng;
-}
-
-    } // namespace range
-    using range::replace_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/reverse.hpp b/src/boost/range/algorithm/reverse.hpp
deleted file mode 100644
index 20a7eb1..0000000
--- a/src/boost/range/algorithm/reverse.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function reverse
-///
-/// range-based version of the reverse std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-template<class BidirectionalRange>
-inline BidirectionalRange& reverse(BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    std::reverse(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class BidirectionalRange>
-inline const BidirectionalRange& reverse(const BidirectionalRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    std::reverse(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-    } // namespace range
-    using range::reverse;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/reverse_copy.hpp b/src/boost/range/algorithm/reverse_copy.hpp
deleted file mode 100644
index f1990ad..0000000
--- a/src/boost/range/algorithm/reverse_copy.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/iterator/iterator_concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function reverse_copy
-///
-/// range-based version of the reverse_copy std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-template<class BidirectionalRange, class OutputIterator>
-inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::reverse_copy(boost::begin(rng), boost::end(rng), out);
-}
-
-    } // namespace range
-    using range::reverse_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/rotate.hpp b/src/boost/range/algorithm/rotate.hpp
deleted file mode 100644
index ca4b223..0000000
--- a/src/boost/range/algorithm/rotate.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function rotate
-///
-/// range-based version of the rotate std algorithm
-///
-/// \pre Rng meets the requirements for a Forward range
-template<class ForwardRange>
-inline ForwardRange& rotate(ForwardRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    std::rotate(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class ForwardRange>
-inline const ForwardRange& rotate(const ForwardRange& rng,
-    BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    std::rotate(boost::begin(rng), middle, boost::end(rng));
-    return rng;
-}
-
-    } // namespace range
-    using range::rotate;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/rotate_copy.hpp b/src/boost/range/algorithm/rotate_copy.hpp
deleted file mode 100644
index 0409ac5..0000000
--- a/src/boost/range/algorithm/rotate_copy.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-    /// \brief template function rotate
-    ///
-    /// range-based version of the rotate std algorithm
-    ///
-    /// \pre Rng meets the requirements for a Forward range
-    template<typename ForwardRange, typename OutputIterator>
-    inline OutputIterator rotate_copy(
-        const ForwardRange&                                             rng,
-        BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle,
-        OutputIterator                                                  target
-        )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-        return std::rotate_copy(boost::begin(rng), middle, boost::end(rng), target);
-    }
-
-    } // namespace range
-    using range::rotate_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/search.hpp b/src/boost/range/algorithm/search.hpp
deleted file mode 100644
index 28cc6e6..0000000
--- a/src/boost/range/algorithm/search.hpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function search
-///
-/// range-based version of the search std algorithm
-///
-/// \pre ForwardRange1 is a model of the ForwardRangeConcept
-/// \pre ForwardRange2 is a model of the ForwardRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
-search(ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return std::search(boost::begin(rng1),boost::end(rng1),
-                       boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
-search(const ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return std::search(boost::begin(rng1), boost::end(rng1),
-                       boost::begin(rng2), boost::end(rng2));
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
-search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return std::search(boost::begin(rng1),boost::end(rng1),
-                       boost::begin(rng2),boost::end(rng2),pred);
-}
-
-/// \overload
-template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
-search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return std::search(boost::begin(rng1), boost::end(rng1),
-                       boost::begin(rng2), boost::end(rng2), pred);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
-search(ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return range_return<ForwardRange1,re>::
-        pack(std::search(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2 >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
-search(const ForwardRange1& rng1, const ForwardRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return range_return<const ForwardRange1,re>::
-        pack(std::search(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2)),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
-search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return range_return<ForwardRange1,re>::
-        pack(std::search(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2),pred),
-             rng1);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange1, class ForwardRange2,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
-search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
-    return range_return<const ForwardRange1,re>::
-        pack(std::search(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2),pred),
-             rng1);
-}
-
-    } // namespace range
-    using range::search;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/search_n.hpp b/src/boost/range/algorithm/search_n.hpp
deleted file mode 100644
index ca2b6ef..0000000
--- a/src/boost/range/algorithm/search_n.hpp
+++ /dev/null
@@ -1,360 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <boost/range/value_type.hpp>
-#include <iterator>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-namespace range_detail
-{
-    // Rationale: search_n is implemented rather than delegate to
-    // the standard library implementation because some standard
-    // library implementations are broken eg. MSVC.
-
-    // search_n forward iterator version
-    template<typename ForwardIterator, typename Integer, typename Value>
-    inline ForwardIterator
-    search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
-                  const Value& value, std::forward_iterator_tag)
-    {
-        first = std::find(first, last, value);
-        while (first != last)
-        {
-            typename std::iterator_traits<ForwardIterator>::difference_type n = count;
-            ForwardIterator i = first;
-            ++i;
-            while (i != last && n != 1 && *i==value)
-            {
-                ++i;
-                --n;
-            }
-            if (n == 1)
-                return first;
-            if (i == last)
-                return last;
-            first = std::find(++i, last, value);
-        }
-        return last;
-    }
-
-    // search_n random-access iterator version
-    template<typename RandomAccessIterator, typename Integer, typename Value>
-    inline RandomAccessIterator
-    search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
-                  Integer count, const Value& value,
-                  std::random_access_iterator_tag)
-    {
-        typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
-
-        difference_t tail_size = last - first;
-        const difference_t pattern_size = count;
-
-        if (tail_size < pattern_size)
-            return last;
-
-        const difference_t skip_offset = pattern_size - 1;
-        RandomAccessIterator look_ahead = first + skip_offset;
-        tail_size -= pattern_size;
-
-        while (1)
-        {
-            // look_ahead here is pointing to the last element of the
-            // next possible match
-            while (!(*look_ahead == value)) // skip loop...
-            {
-                if (tail_size < pattern_size)
-                    return last; // no match
-                look_ahead += pattern_size;
-                tail_size -= pattern_size;
-            }
-            difference_t remainder = skip_offset;
-            for (RandomAccessIterator back_track = look_ahead - 1;
-                    *back_track == value; --back_track)
-            {
-                if (--remainder == 0)
-                {
-                    return look_ahead - skip_offset; // matched
-                }
-            }
-            if (remainder > tail_size)
-                return last; // no match
-            look_ahead += remainder;
-            tail_size -= remainder;
-        }
-
-        return last;
-    }
-
-    // search_n for forward iterators using a binary predicate
-    // to determine a match
-    template<typename ForwardIterator, typename Integer, typename Value,
-             typename BinaryPredicate>
-    inline ForwardIterator
-    search_n_pred_impl(ForwardIterator first, ForwardIterator last,
-                       Integer count, const Value& value,
-                       BinaryPredicate pred, std::forward_iterator_tag)
-    {
-        typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
-
-        while (first != last && !static_cast<bool>(pred(*first, value)))
-            ++first;
-
-        while (first != last)
-        {
-            difference_t n = count;
-            ForwardIterator i = first;
-            ++i;
-            while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
-            {
-                ++i;
-                --n;
-            }
-            if (n == 1)
-                return first;
-            if (i == last)
-                return last;
-            first = ++i;
-            while (first != last && !static_cast<bool>(pred(*first, value)))
-                ++first;
-        }
-        return last;
-    }
-
-    // search_n for random-access iterators using a binary predicate
-    // to determine a match
-    template<typename RandomAccessIterator, typename Integer,
-             typename Value, typename BinaryPredicate>
-    inline RandomAccessIterator
-    search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
-                       Integer count, const Value& value,
-                       BinaryPredicate pred, std::random_access_iterator_tag)
-    {
-        typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
-
-        difference_t tail_size = last - first;
-        const difference_t pattern_size = count;
-
-        if (tail_size < pattern_size)
-            return last;
-
-        const difference_t skip_offset = pattern_size - 1;
-        RandomAccessIterator look_ahead = first + skip_offset;
-        tail_size -= pattern_size;
-
-        while (1)
-        {
-            // look_ahead points to the last element of the next
-            // possible match
-            while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
-            {
-                if (tail_size < pattern_size)
-                    return last; // no match
-                look_ahead += pattern_size;
-                tail_size -= pattern_size;
-            }
-            difference_t remainder = skip_offset;
-            for (RandomAccessIterator back_track = look_ahead - 1;
-                    pred(*back_track, value); --back_track)
-            {
-                if (--remainder == 0)
-                    return look_ahead -= skip_offset; // success
-            }
-            if (remainder > tail_size)
-            {
-                return last; // no match
-            }
-            look_ahead += remainder;
-            tail_size -= remainder;
-        }
-    }
-
-    template<typename ForwardIterator, typename Integer, typename Value>
-    inline ForwardIterator
-    search_n_impl(ForwardIterator first, ForwardIterator last,
-                  Integer count, const Value& value)
-    {
-        BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
-        BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
-        BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
-        //BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
-
-        typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
-
-        if (count <= 0)
-            return first;
-        if (count == 1)
-            return std::find(first, last, value);
-        return range_detail::search_n_impl(first, last, count, value, cat_t());
-    }
-
-    template<typename ForwardIterator, typename Integer, typename Value,
-             typename BinaryPredicate>
-    inline ForwardIterator
-    search_n_pred_impl(ForwardIterator first, ForwardIterator last,
-                       Integer count, const Value& value,
-                       BinaryPredicate pred)
-    {
-        BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
-        BOOST_RANGE_CONCEPT_ASSERT((
-            BinaryPredicateConcept<
-                BinaryPredicate,
-                typename std::iterator_traits<ForwardIterator>::value_type,
-                Value>
-            ));
-
-        typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
-
-        if (count <= 0)
-            return first;
-        if (count == 1)
-        {
-            while (first != last && !static_cast<bool>(pred(*first, value)))
-                ++first;
-            return first;
-        }
-        return range_detail::search_n_pred_impl(first, last, count,
-                                                value, pred, cat_t());
-    }
-} // namespace range_detail
-
-/// \brief template function search
-///
-/// range-based version of the search std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-/// \pre Integer is an integral type
-/// \pre Value is a model of the EqualityComparableConcept
-/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
-/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
-template< class ForwardRange, class Integer, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-search_n(ForwardRange& rng, Integer count, const Value& value)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
-}
-
-/// \overload
-template< class ForwardRange, class Integer, class Value >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-search_n(const ForwardRange& rng, Integer count, const Value& value)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
-    return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
-}
-
-/// \overload
-template< class ForwardRange, class Integer, class Value,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
-search_n(ForwardRange& rng, Integer count, const Value& value,
-         BinaryPredicate binary_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
-    return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
-        count, value, binary_pred);
-}
-
-/// \overload
-template< class ForwardRange, class Integer, class Value,
-          class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-search_n(const ForwardRange& rng, Integer count, const Value& value,
-         BinaryPredicate binary_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
-    return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
-        count, value, binary_pred);
-}
-
-// range_return overloads
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Integer,
-          class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-search_n(ForwardRange& rng, Integer count, const Value& value)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    return range_return<ForwardRange,re>::
-        pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
-                           count, value),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Integer,
-          class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-search_n(const ForwardRange& rng, Integer count, const Value& value)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
-    return range_return<const ForwardRange,re>::
-        pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
-                           count, value),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Integer,
-          class Value, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-search_n(ForwardRange& rng, Integer count, const Value& value,
-         BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
-        const Value&>));
-    return range_return<ForwardRange,re>::
-        pack(range_detail::search_n_pred_impl(boost::begin(rng),
-                                              boost::end(rng),
-                           count, value, pred),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Integer,
-          class Value, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-search_n(const ForwardRange& rng, Integer count, const Value& value,
-         BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-        BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
-        const Value&>));
-    return range_return<const ForwardRange,re>::
-        pack(range_detail::search_n_pred_impl(boost::begin(rng),
-                                              boost::end(rng),
-                           count, value, pred),
-             rng);
-}
-
-    } // namespace range
-    using range::search_n;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/set_algorithm.hpp b/src/boost/range/algorithm/set_algorithm.hpp
deleted file mode 100644
index 82ef8ec..0000000
--- a/src/boost/range/algorithm/set_algorithm.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function includes
-///
-/// range-based version of the includes std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange1, class SinglePassRange2>
-inline bool includes(const SinglePassRange1& rng1,
-                     const SinglePassRange2& rng2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::includes(boost::begin(rng1),boost::end(rng1),
-                         boost::begin(rng2),boost::end(rng2));
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class BinaryPredicate>
-inline bool includes(const SinglePassRange1& rng1,
-                     const SinglePassRange2& rng2,
-                     BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::includes(boost::begin(rng1), boost::end(rng1),
-                         boost::begin(rng2), boost::end(rng2), pred);
-}
-
-/// \brief template function set_union
-///
-/// range-based version of the set_union std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator>
-inline OutputIterator set_union(const SinglePassRange1& rng1,
-                                const SinglePassRange2& rng2,
-                                OutputIterator          out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_union(boost::begin(rng1), boost::end(rng1),
-                          boost::begin(rng2), boost::end(rng2), out);
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator, class BinaryPredicate>
-inline OutputIterator set_union(const SinglePassRange1& rng1,
-                                const SinglePassRange2& rng2,
-                                OutputIterator          out,
-                                BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_union(boost::begin(rng1), boost::end(rng1),
-                          boost::begin(rng2), boost::end(rng2), out, pred);
-}
-
-/// \brief template function set_intersection
-///
-/// range-based version of the set_intersection std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator>
-inline OutputIterator set_intersection(const SinglePassRange1& rng1,
-                                       const SinglePassRange2& rng2,
-                                       OutputIterator          out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_intersection(boost::begin(rng1), boost::end(rng1),
-                                 boost::begin(rng2), boost::end(rng2), out);
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator, class BinaryPredicate>
-inline OutputIterator set_intersection(const SinglePassRange1& rng1,
-                                       const SinglePassRange2& rng2,
-                                       OutputIterator          out,
-                                       BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_intersection(boost::begin(rng1), boost::end(rng1),
-                                 boost::begin(rng2), boost::end(rng2),
-                                 out, pred);
-}
-
-/// \brief template function set_difference
-///
-/// range-based version of the set_difference std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator>
-inline OutputIterator set_difference(const SinglePassRange1& rng1,
-                                     const SinglePassRange2& rng2,
-                                     OutputIterator out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_difference(boost::begin(rng1), boost::end(rng1),
-                               boost::begin(rng2), boost::end(rng2), out);
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator, class BinaryPredicate>
-inline OutputIterator set_difference(const SinglePassRange1& rng1,
-                                     const SinglePassRange2& rng2,
-                                     OutputIterator          out,
-                                     BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_difference(
-        boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2), out, pred);
-}
-
-/// \brief template function set_symmetric_difference
-///
-/// range-based version of the set_symmetric_difference std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator>
-inline OutputIterator
-set_symmetric_difference(const SinglePassRange1& rng1,
-                         const SinglePassRange2& rng2,
-                         OutputIterator          out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
-                                         boost::begin(rng2), boost::end(rng2), out);
-}
-
-/// \overload
-template<class SinglePassRange1, class SinglePassRange2,
-         class OutputIterator, class BinaryPredicate>
-inline OutputIterator
-set_symmetric_difference(const SinglePassRange1& rng1,
-                         const SinglePassRange2& rng2,
-                         OutputIterator          out,
-                         BinaryPredicate         pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-    return std::set_symmetric_difference(
-        boost::begin(rng1), boost::end(rng1),
-        boost::begin(rng2), boost::end(rng2), out, pred);
-}
-
-    } // namespace range
-    using range::includes;
-    using range::set_union;
-    using range::set_intersection;
-    using range::set_difference;
-    using range::set_symmetric_difference;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/sort.hpp b/src/boost/range/algorithm/sort.hpp
deleted file mode 100644
index 45eecde..0000000
--- a/src/boost/range/algorithm/sort.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function sort
-///
-/// range-based version of the sort std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& sort(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::sort(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& sort(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::sort(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::sort(boost::begin(rng), boost::end(rng), pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::sort(boost::begin(rng), boost::end(rng), pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::sort;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/stable_partition.hpp b/src/boost/range/algorithm/stable_partition.hpp
deleted file mode 100644
index 24febfc..0000000
--- a/src/boost/range/algorithm/stable_partition.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function stable_partition
-///
-/// range-based version of the stable_partition std algorithm
-///
-/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
-/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
-template<class BidirectionalRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type
-stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return std::stable_partition(boost::begin(rng), boost::end(rng), pred);
-}
-
-/// \overload
-template<class BidirectionalRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_iterator<const BidirectionalRange>::type
-stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return std::stable_partition(boost::begin(rng),boost::end(rng),pred);
-}
-
-// range_return overloads
-template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<BidirectionalRange,re>::type
-stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
-    return range_return<BidirectionalRange,re>::pack(
-        std::stable_partition(boost::begin(rng), boost::end(rng), pred),
-        rng);
-}
-
-/// \overload
-template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
-inline BOOST_DEDUCED_TYPENAME range_return<const BidirectionalRange,re>::type
-stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
-    return range_return<const BidirectionalRange,re>::pack(
-        std::stable_partition(boost::begin(rng),boost::end(rng),pred),
-        rng);
-}
-
-    } // namespace range
-    using range::stable_partition;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/stable_sort.hpp b/src/boost/range/algorithm/stable_sort.hpp
deleted file mode 100644
index d18da4d..0000000
--- a/src/boost/range/algorithm/stable_sort.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function stable_sort
-///
-/// range-based version of the stable_sort std algorithm
-///
-/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template<class RandomAccessRange>
-inline RandomAccessRange& stable_sort(RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::stable_sort(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange>
-inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::stable_sort(boost::begin(rng), boost::end(rng));
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
-    std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
-    return rng;
-}
-
-/// \overload
-template<class RandomAccessRange, class BinaryPredicate>
-inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
-    std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
-    return rng;
-}
-
-    } // namespace range
-    using range::stable_sort;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/swap_ranges.hpp b/src/boost/range/algorithm/swap_ranges.hpp
deleted file mode 100644
index 52b0162..0000000
--- a/src/boost/range/algorithm/swap_ranges.hpp
+++ /dev/null
@@ -1,132 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
-
-#include <boost/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <boost/iterator/iterator_categories.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<class Iterator1, class Iterator2>
-        void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
-                              Iterator2 it2, Iterator2 last2,
-                              single_pass_traversal_tag,
-                              single_pass_traversal_tag)
-        {
-            ignore_unused_variable_warning(last2);
-            for (; it1 != last1; ++it1, ++it2)
-            {
-                BOOST_ASSERT( it2 != last2 );
-                std::iter_swap(it1, it2);
-            }
-        }
-
-        template<class Iterator1, class Iterator2>
-        void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
-                              Iterator2 it2, Iterator2 last2,
-                              random_access_traversal_tag,
-                              random_access_traversal_tag)
-        {
-            ignore_unused_variable_warning(last2);
-            BOOST_ASSERT( last2 - it2 >= last1 - it1 );
-            std::swap_ranges(it1, last1, it2);
-        }
-
-        template<class Iterator1, class Iterator2>
-        void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
-                              Iterator2 first2, Iterator2 last2)
-        {
-            swap_ranges_impl(first1, last1, first2, last2,
-                BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
-                BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
-        }
-    } // namespace range_detail
-
-    namespace range
-    {
-
-/// \brief template function swap_ranges
-///
-/// range-based version of the swap_ranges std algorithm
-///
-/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-template< class SinglePassRange1, class SinglePassRange2 >
-inline SinglePassRange2&
-swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
-
-    boost::range_detail::swap_ranges_impl(
-        boost::begin(range1), boost::end(range1),
-        boost::begin(range2), boost::end(range2));
-
-    return range2;
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline SinglePassRange2&
-swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
-
-    boost::range_detail::swap_ranges_impl(
-        boost::begin(range1), boost::end(range1),
-        boost::begin(range2), boost::end(range2));
-
-    return range2;
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline const SinglePassRange2&
-swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
-
-    boost::range_detail::swap_ranges_impl(
-        boost::begin(range1), boost::end(range1),
-        boost::begin(range2), boost::end(range2));
-
-    return range2;
-}
-
-/// \overload
-template< class SinglePassRange1, class SinglePassRange2 >
-inline const SinglePassRange2&
-swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
-
-    boost::range_detail::swap_ranges_impl(
-        boost::begin(range1), boost::end(range1),
-        boost::begin(range2), boost::end(range2));
-
-    return range2;
-}
-
-    } // namespace range
-    using range::swap_ranges;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/transform.hpp b/src/boost/range/algorithm/transform.hpp
deleted file mode 100644
index fb03441..0000000
--- a/src/boost/range/algorithm/transform.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
-
-#include <boost/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-        /// \brief template function transform
-        ///
-        /// range-based version of the transform std algorithm
-        ///
-        /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
-        /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
-        /// \pre OutputIterator is a model of the OutputIteratorConcept
-        /// \pre UnaryOperation is a model of the UnaryFunctionConcept
-        /// \pre BinaryOperation is a model of the BinaryFunctionConcept
-        template< class SinglePassRange1,
-                  class OutputIterator,
-                  class UnaryOperation >
-        inline OutputIterator
-        transform(const SinglePassRange1& rng,
-                  OutputIterator          out,
-                  UnaryOperation          fun)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            return std::transform(boost::begin(rng),boost::end(rng),out,fun);
-        }
-
-    } // namespace range
-
-    namespace range_detail
-    {
-        template< class SinglePassTraversalReadableIterator1,
-                  class SinglePassTraversalReadableIterator2,
-                  class OutputIterator,
-                  class BinaryFunction >
-        inline OutputIterator
-        transform_impl(SinglePassTraversalReadableIterator1 first1,
-                       SinglePassTraversalReadableIterator1 last1,
-                       SinglePassTraversalReadableIterator2 first2,
-                       SinglePassTraversalReadableIterator2 last2,
-                       OutputIterator                       out,
-                       BinaryFunction                       fn)
-        {
-            for (; first1 != last1; ++first1, ++first2)
-            {
-                BOOST_ASSERT( first2 != last2 );
-                *out = fn(*first1, *first2);
-                ++out;
-            }
-            return out;
-        }
-    }
-
-    namespace range
-    {
-
-        /// \overload
-        template< class SinglePassRange1,
-                  class SinglePassRange2,
-                  class OutputIterator,
-                  class BinaryOperation >
-        inline OutputIterator
-        transform(const SinglePassRange1& rng1,
-                  const SinglePassRange2& rng2,
-                  OutputIterator          out,
-                  BinaryOperation         fun)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-            return boost::range_detail::transform_impl(
-                        boost::begin(rng1), boost::end(rng1),
-                        boost::begin(rng2), boost::end(rng2),
-                        out, fun);
-        }
-
-    } // namespace range
-    using range::transform;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/unique.hpp b/src/boost/range/algorithm/unique.hpp
deleted file mode 100644
index be6eaf9..0000000
--- a/src/boost/range/algorithm/unique.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function unique
-///
-/// range-based version of the unique std algorithm
-///
-/// \pre Rng meets the requirements for a Forward range
-template< range_return_value re, class ForwardRange >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-unique( ForwardRange& rng )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack( std::unique( boost::begin(rng),
-                           boost::end(rng)), rng );
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-unique( const ForwardRange& rng )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack( std::unique( boost::begin(rng),
-                           boost::end(rng)), rng );
-}
-/// \overload
-template< range_return_value re, class ForwardRange, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
-unique( ForwardRange& rng, BinaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack(std::unique(boost::begin(rng), boost::end(rng), pred),
-             rng);
-}
-/// \overload
-template< range_return_value re, class ForwardRange, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-unique( const ForwardRange& rng, BinaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack(std::unique(boost::begin(rng), boost::end(rng), pred),
-             rng);
-}
-
-/// \overload
-template< class ForwardRange >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
-unique( ForwardRange& rng )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return ::boost::range::unique<return_begin_found>(rng);
-}
-/// \overload
-template< class ForwardRange >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
-unique( const ForwardRange& rng )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return ::boost::range::unique<return_begin_found>(rng);
-}
-/// \overload
-template< class ForwardRange, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
-unique( ForwardRange& rng, BinaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return ::boost::range::unique<return_begin_found>(rng);
-}
-/// \overload
-template< class ForwardRange, class BinaryPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-unique( const ForwardRange& rng, BinaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return ::boost::range::unique<return_begin_found>(rng, pred);
-}
-
-    } // namespace range
-    using range::unique;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/unique_copy.hpp b/src/boost/range/algorithm/unique_copy.hpp
deleted file mode 100644
index 0682d74..0000000
--- a/src/boost/range/algorithm/unique_copy.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function unique_copy
-///
-/// range-based version of the unique_copy std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre OutputIterator is a model of the OutputIteratorConcept
-/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
-template< class SinglePassRange, class OutputIterator >
-inline OutputIterator
-unique_copy( const SinglePassRange& rng, OutputIterator out_it )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::unique_copy(boost::begin(rng), boost::end(rng), out_it);
-}
-/// \overload
-template< class SinglePassRange, class OutputIterator, class BinaryPredicate >
-inline OutputIterator
-unique_copy( const SinglePassRange& rng, OutputIterator out_it,
-             BinaryPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    return std::unique_copy(boost::begin(rng), boost::end(rng), out_it, pred);
-}
-
-    } // namespace range
-    using range::unique_copy;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm/upper_bound.hpp b/src/boost/range/algorithm/upper_bound.hpp
deleted file mode 100644
index c8acbc6..0000000
--- a/src/boost/range/algorithm/upper_bound.hpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/detail/range_return.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function upper_bound
-///
-/// range-based version of the upper_bound std algorithm
-///
-/// \pre ForwardRange is a model of the ForwardRangeConcept
-template< class ForwardRange, class Value >
-inline
-BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
->::type
-upper_bound( ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::upper_bound(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class ForwardRange, class Value >
-BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-upper_bound( const ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::upper_bound(boost::begin(rng), boost::end(rng), val);
-}
-
-/// \overload
-template< class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
->::type
-upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-/// \overload
-template< class ForwardRange, class Value, class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
-upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
->::type
-upper_bound( ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-upper_bound( const ForwardRange& rng, Value val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value,
-          class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME disable_if<
-    is_const<ForwardRange>,
-    BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
->::type
-upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    return range_return<ForwardRange,re>::
-        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
-             rng);
-}
-
-/// \overload
-template< range_return_value re, class ForwardRange, class Value,
-          class SortPredicate >
-inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
-upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    return range_return<const ForwardRange,re>::
-        pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
-             rng);
-}
-
-    } // namespace range
-    using range::upper_bound;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext.hpp b/src/boost/range/algorithm_ext.hpp
deleted file mode 100644
index 783d38a..0000000
--- a/src/boost/range/algorithm_ext.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2007. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//  Copyright Thorsten Ottosen 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_HPP
-#define BOOST_RANGE_ALGORITHM_EXT_HPP
-
-#include <boost/range/algorithm_ext/copy_n.hpp>
-#include <boost/range/algorithm_ext/for_each.hpp>
-#include <boost/range/algorithm_ext/is_sorted.hpp>
-#include <boost/range/algorithm_ext/iota.hpp>
-#include <boost/range/algorithm_ext/overwrite.hpp>
-#include <boost/range/algorithm_ext/push_back.hpp>
-#include <boost/range/algorithm_ext/push_front.hpp>
-#include <boost/range/algorithm_ext/insert.hpp>
-#include <boost/range/algorithm_ext/erase.hpp>
-
-#endif
diff --git a/src/boost/range/algorithm_ext/copy_n.hpp b/src/boost/range/algorithm_ext/copy_n.hpp
deleted file mode 100644
index f855441..0000000
--- a/src/boost/range/algorithm_ext/copy_n.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
-
-#include <boost/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/distance.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function copy
-///
-/// range-based version of the copy std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-/// \pre OutputIterator is a model of the OutputIteratorConcept
-/// \pre 0 <= n <= distance(rng)
-template< class SinglePassRange, class Size, class OutputIterator >
-inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-    BOOST_ASSERT( n <= static_cast<Size>(::boost::distance(rng)) );
-    BOOST_ASSERT( n >= static_cast<Size>(0) );
-
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = ::boost::begin(rng);
-
-    for (Size i = 0; i < n; ++i, ++out, ++source)
-        *out = *source;
-
-    return out;
-}
-
-    } // namespace range
-    using ::boost::range::copy_n;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/erase.hpp b/src/boost/range/algorithm_ext/erase.hpp
deleted file mode 100644
index 107d32b..0000000
--- a/src/boost/range/algorithm_ext/erase.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/iterator_range_core.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class Container >
-inline Container& erase( Container& on,
-      iterator_range<BOOST_DEDUCED_TYPENAME Container::iterator> to_erase )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
-    on.erase( boost::begin(to_erase), boost::end(to_erase) );
-    return on;
-}
-
-template< class Container, class T >
-inline Container& remove_erase( Container& on, const T& val )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
-    on.erase(
-        std::remove(boost::begin(on), boost::end(on), val),
-        boost::end(on));
-    return on;
-}
-
-template< class Container, class Pred >
-inline Container& remove_erase_if( Container& on, Pred pred )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
-    on.erase(
-        std::remove_if(boost::begin(on), boost::end(on), pred),
-        boost::end(on));
-    return on;
-}
-
-    } // namespace range
-    using range::erase;
-    using range::remove_erase;
-    using range::remove_erase_if;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/for_each.hpp b/src/boost/range/algorithm_ext/for_each.hpp
deleted file mode 100644
index a470e2b..0000000
--- a/src/boost/range/algorithm_ext/for_each.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<class InputIterator1, class InputIterator2, class Fn2>
-        inline Fn2 for_each_impl(InputIterator1 first1, InputIterator1 last1,
-                                 InputIterator2 first2, InputIterator2 last2,
-                                 Fn2 fn)
-        {
-            for (; first1 != last1 && first2 != last2; ++first1, ++first2)
-            {
-                fn(*first1, *first2);
-            }
-            return fn;
-        }
-    }
-
-    namespace range
-    {
-        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
-        inline Fn2 for_each(const SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-            return ::boost::range_detail::for_each_impl(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2), fn);
-        }
-
-        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
-        inline Fn2 for_each(const SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-            return ::boost::range_detail::for_each_impl(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2), fn);
-        }
-
-        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
-        inline Fn2 for_each(SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-            return ::boost::range_detail::for_each_impl(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2), fn);
-        }
-
-        template<class SinglePassRange1, class SinglePassRange2, class Fn2>
-        inline Fn2 for_each(SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-            return ::boost::range_detail::for_each_impl(
-                ::boost::begin(rng1), ::boost::end(rng1),
-                ::boost::begin(rng2), ::boost::end(rng2), fn);
-        }
-    } // namespace range
-    using range::for_each;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/insert.hpp b/src/boost/range/algorithm_ext/insert.hpp
deleted file mode 100644
index b9adfdd..0000000
--- a/src/boost/range/algorithm_ext/insert.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class Container, class Range >
-inline Container& insert( Container& on,
-                          BOOST_DEDUCED_TYPENAME Container::iterator before,
-                          const Range& from )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
-    BOOST_ASSERT( (void*)&on != (void*)&from &&
-                  "cannot copy from a container to itself" );
-    on.insert( before, boost::begin(from), boost::end(from) );
-    return on;
-}
-
-    } // namespace range
-    using range::insert;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/iota.hpp b/src/boost/range/algorithm_ext/iota.hpp
deleted file mode 100644
index f7af446..0000000
--- a/src/boost/range/algorithm_ext/iota.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class ForwardRange, class Value >
-inline ForwardRange& iota( ForwardRange& rng, Value x )
-{
-    BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
-    typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
-
-    iterator_t last_target = ::boost::end(rng);
-    for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
-        *target = x;
-
-    return rng;
-}
-
-template< class ForwardRange, class Value >
-inline const ForwardRange& iota( const ForwardRange& rng, Value x )
-{
-    BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
-    typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type iterator_t;
-    
-    iterator_t last_target = ::boost::end(rng);
-    for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
-        *target = x;
-    
-    return rng;
-}
-
-    } // namespace range
-    using range::iota;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/is_sorted.hpp b/src/boost/range/algorithm_ext/is_sorted.hpp
deleted file mode 100644
index 3d00729..0000000
--- a/src/boost/range/algorithm_ext/is_sorted.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//  Copyright Bryce Lelbach 2010
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/detail/is_sorted.hpp>
-#include <algorithm>
-
-namespace boost
-{
-    namespace range
-    {
-
-/// \brief template function is_sorted
-///
-/// range-based version of the is_sorted std algorithm
-///
-/// \pre SinglePassRange is a model of the SinglePassRangeConcept
-template<class SinglePassRange>
-inline bool is_sorted(const SinglePassRange& rng)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME
-      range_value<const SinglePassRange>::type>));
-    return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng));
-}
-
-/// \overload
-template<class SinglePassRange, class BinaryPredicate>
-inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred)
-{
-    BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
-    BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
-      BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type,
-      BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>));
-    return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred);
-}
-
-    } // namespace range
-
-using range::is_sorted;
-
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/overwrite.hpp b/src/boost/range/algorithm_ext/overwrite.hpp
deleted file mode 100644
index f84f6ea..0000000
--- a/src/boost/range/algorithm_ext/overwrite.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class SinglePassRange1, class SinglePassRange2 >
-inline void overwrite( const SinglePassRange1& from, SinglePassRange2& to )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
-        i = boost::begin(from), e = boost::end(from);
-
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
-        out = boost::begin(to);
-
-#ifndef NDEBUG
-    BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
-        last_out = boost::end(to);
-#endif
-
-    for( ; i != e; ++out, ++i )
-    {
-#ifndef NDEBUG
-        BOOST_ASSERT( out != last_out
-            && "out of bounds in boost::overwrite()" );
-#endif
-        *out = *i;
-    }
-}
-
-template< class SinglePassRange1, class SinglePassRange2 >
-inline void overwrite( const SinglePassRange1& from, const SinglePassRange2& to )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
-        i = boost::begin(from), e = boost::end(from);
-
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
-        out = boost::begin(to);
-
-#ifndef NDEBUG
-    BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
-        last_out = boost::end(to);
-#endif
-
-    for( ; i != e; ++out, ++i )
-    {
-#ifndef NDEBUG
-        BOOST_ASSERT( out != last_out
-            && "out of bounds in boost::overwrite()" );
-#endif
-        *out = *i;
-    }
-}
-
-    } // namespace range
-    using range::overwrite;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/push_back.hpp b/src/boost/range/algorithm_ext/push_back.hpp
deleted file mode 100644
index 51a7a7b..0000000
--- a/src/boost/range/algorithm_ext/push_back.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class Container, class Range >
-inline Container& push_back( Container& on, const Range& from )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
-    BOOST_ASSERT( (void*)&on != (void*)&from &&
-                  "cannot copy from a container to itself" );
-    on.insert( on.end(), boost::begin(from), boost::end(from) );
-    return on;
-}
-
-    } // namespace range
-    using range::push_back;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/algorithm_ext/push_front.hpp b/src/boost/range/algorithm_ext/push_front.hpp
deleted file mode 100644
index 470d793..0000000
--- a/src/boost/range/algorithm_ext/push_front.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
-#define BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-
-template< class Container, class Range >
-inline Container& push_front( Container& on, const Range& from )
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
-    BOOST_ASSERT( (void*)&on != (void*)&from &&
-                  "cannot copy from a container to itself" );
-    on.insert( on.begin(), boost::begin(from), boost::end(from) );
-    return on;
-}
-
-    } // namespace range
-    using range::push_front;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/any_range.hpp b/src/boost/range/any_range.hpp
deleted file mode 100644
index ba4c224..0000000
--- a/src/boost/range/any_range.hpp
+++ /dev/null
@@ -1,205 +0,0 @@
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
-#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/iterator/iterator_categories.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/range/detail/any_iterator.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/reference.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/iterator_range_core.hpp>
-#include <boost/cast.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        // If T is use_default, return the result of Default, otherwise
-        // return T.
-        //
-        // This is an implementation artifact used to pick intelligent default
-        // values when the user specified boost::use_default as a template
-        // parameter.
-        template<
-            class T,
-            class Default
-        >
-        struct any_range_default_help
-            : mpl::eval_if<
-                is_same<T, use_default>
-              , Default
-              , mpl::identity<T>
-            >
-        {
-        };
-
-        template<
-            class WrappedRange
-          , class Value
-          , class Reference
-        >
-        struct any_range_value_type
-        {
-# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
-            typedef typename any_range_default_help<
-                    Value
-                  , mpl::eval_if<
-                        is_same<Reference, use_default>
-                      , range_value<
-                            typename remove_const<WrappedRange>
-                        ::type>
-                      , remove_reference<Reference>
-                    >
-                >::type type;
-# else
-            typedef typename any_range_default_help<
-                Value
-              , range_value<
-                    typename remove_const<WrappedRange>
-                ::type>
-            >::type type;
-# endif
-        };
-
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer = use_default
-        >
-        class any_range
-            : public iterator_range<
-                        any_iterator<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , typename any_range_default_help<
-                                Buffer
-                              , mpl::identity<any_iterator_default_buffer>
-                            >::type
-                        >
-                    >
-        {
-            typedef iterator_range<
-                        any_iterator<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , typename any_range_default_help<
-                                Buffer
-                              , mpl::identity<any_iterator_default_buffer>
-                            >::type
-                        >
-                    > base_type;
-
-            struct enabler {};
-            struct disabler {};
-        public:
-            any_range()
-            {
-            }
-
-            any_range(const any_range& other)
-                : base_type(other)
-            {
-            }
-
-            template<class WrappedRange>
-            any_range(WrappedRange& wrapped_range)
-            : base_type(boost::begin(wrapped_range),
-                        boost::end(wrapped_range))
-            {
-            }
-
-            template<class WrappedRange>
-            any_range(const WrappedRange& wrapped_range)
-            : base_type(boost::begin(wrapped_range),
-                        boost::end(wrapped_range))
-            {
-            }
-
-            template<
-                class OtherValue
-              , class OtherTraversal
-              , class OtherReference
-              , class OtherDifference
-            >
-            any_range(const any_range<
-                                OtherValue
-                              , OtherTraversal
-                              , OtherReference
-                              , OtherDifference
-                              , Buffer
-                            >& other)
-            : base_type(boost::begin(other), boost::end(other))
-            {
-            }
-
-            template<class Iterator>
-            any_range(Iterator first, Iterator last)
-                : base_type(first, last)
-            {
-            }
-        };
-
-        template<
-            class WrappedRange
-          , class Value = use_default
-          , class Traversal = use_default
-          , class Reference = use_default
-          , class Difference = use_default
-          , class Buffer = use_default
-        >
-        struct any_range_type_generator
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> ));
-            typedef any_range<
-                typename any_range_value_type<
-                    WrappedRange
-                  , Value
-                  , typename any_range_default_help<
-                        Reference
-                      , range_reference<WrappedRange>
-                    >::type
-                >::type
-              , typename any_range_default_help<
-                            Traversal
-                          , iterator_traversal<
-                                typename range_iterator<WrappedRange>::type
-                            >
-                        >::type
-              , typename any_range_default_help<
-                    Reference
-                  , range_reference<WrappedRange>
-                >::type
-              , typename any_range_default_help<
-                    Difference
-                  , range_difference<WrappedRange>
-                >::type
-              , typename any_range_default_help<
-                    Buffer
-                  , mpl::identity<any_iterator_default_buffer>
-                >::type
-            > type;
-        };
-    } // namespace range_detail
-
-    using range_detail::any_range;
-    using range_detail::any_range_type_generator;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/as_array.hpp b/src/boost/range/as_array.hpp
deleted file mode 100644
index 0723e60..0000000
--- a/src/boost/range/as_array.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_AS_ARRAY_HPP
-#define BOOST_RANGE_AS_ARRAY_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/detail/str_types.hpp>
-
-namespace boost
-{
-
-    template< class R >
-    inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type > 
-    as_array( R& r )
-    {
-        return boost::make_iterator_range( r );
-    }
-
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-    template< class Range >
-    inline boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type > 
-    as_array( const Range& r )
-    {
-        return boost::make_iterator_range( r );
-    }
-    
-#endif
-    
-}
-
-#endif
-
diff --git a/src/boost/range/as_literal.hpp b/src/boost/range/as_literal.hpp
deleted file mode 100644
index 9ea144d..0000000
--- a/src/boost/range/as_literal.hpp
+++ /dev/null
@@ -1,127 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_AS_LITERAL_HPP
-#define BOOST_RANGE_AS_LITERAL_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-#include <boost/range/detail/as_literal.hpp>
-#else
-
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/detail/str_types.hpp>
-
-#include <boost/detail/workaround.hpp>
-
-#include <cstring>
-#ifndef BOOST_NO_CWCHAR
-#include <cwchar>
-#endif
-
-namespace boost
-{
-    namespace range_detail
-    {
-        inline std::size_t length( const char* s )
-        {
-            return strlen( s );
-        }
-
-#ifndef BOOST_NO_CWCHAR
-        inline std::size_t length( const wchar_t* s )
-        {
-            return wcslen( s );
-        }
-#endif
-
-        //
-        // Remark: the compiler cannot choose between T* and T[sz]
-        // overloads, so we must put the T* internal to the
-        // unconstrained version.
-        //
-
-        inline bool is_char_ptr( char* )
-        {
-            return true;
-        }
-
-        inline bool is_char_ptr( const char* )
-        {
-            return true;
-        }
-
-#ifndef BOOST_NO_CWCHAR
-        inline bool is_char_ptr( wchar_t* )
-        {
-            return true;
-        }
-
-        inline bool is_char_ptr( const wchar_t* )
-        {
-            return true;
-        }
-#endif
-
-        template< class T >
-        inline long is_char_ptr( const T& /* r */ )
-        {
-            return 0L;
-        }
-
-        template< class T >
-        inline iterator_range<T*>
-        make_range( T* const r, bool )
-        {
-            return iterator_range<T*>( r, r + length(r) );
-        }
-
-        template< class T >
-        inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type>
-        make_range( T& r, long )
-        {
-            return boost::make_iterator_range( r );
-        }
-
-    }
-
-    template< class Range >
-    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
-    as_literal( Range& r )
-    {
-        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
-    }
-
-    template< class Range >
-    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type>
-    as_literal( const Range& r )
-    {
-        return range_detail::make_range( r, range_detail::is_char_ptr(r) );
-    }
-
-    template< class Char, std::size_t sz >
-    inline iterator_range<Char*> as_literal( Char (&arr)[sz] )
-    {
-        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
-    }
-
-    template< class Char, std::size_t sz >
-    inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] )
-    {
-        return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
-    }
-}
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-#endif
diff --git a/src/boost/range/atl.hpp b/src/boost/range/atl.hpp
deleted file mode 100644
index ab492d9..0000000
--- a/src/boost/range/atl.hpp
+++ /dev/null
@@ -1,733 +0,0 @@
-#ifndef BOOST_RANGE_ATL_HPP
-#define BOOST_RANGE_ATL_HPP
-
-
-
-
-// Boost.Range ATL Extension
-//
-// Copyright Shunsuke Sogame 2005-2006.
-// Distributed under the Boost Software License, Version 1.0. 
-// (See accompanying file LICENSE_1_0.txt or copy at 
-// http://www.boost.org/LICENSE_1_0.txt)
-
-
-
-
-// config
-//
-
-
-#include <atldef.h> // _ATL_VER
-
-
-#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-    #if (_ATL_VER < 0x0700)
-        #define BOOST_RANGE_ATL_NO_COLLECTIONS
-    #endif
-#endif
-
-
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-    #if (_ATL_VER < 0x0700) // dubious
-        #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX
-    #endif
-#endif
-
-
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
-    #if (_MSC_VER < 1310)   // from <boost/regex/mfc.hpp>, but dubious
-        #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING
-    #endif
-#endif
-
-
-
-
-// forward declarations
-//
-
-
-#include <basetyps.h> // IID
-
-
-namespace ATL {
-
-
-#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-    // arrays
-    //
-    template< class E, class ETraits >
-    class CAtlArray;
-
-    template< class E >
-    class CAutoPtrArray;
-
-    template< class I, const IID *piid >
-    class CInterfaceArray;
-
-
-    // lists
-    //
-    template< class E, class ETraits >
-    class CAtlList;
-
-    template< class E >
-    class CAutoPtrList;
-
-    template< class E, class Allocator >
-    class CHeapPtrList;
-
-    template< class I, const IID *piid >
-    class CInterfaceList;
-
-
-    // maps
-    //
-    template< class K, class V, class KTraits, class VTraits >
-    class CAtlMap;
-
-    template< class K, class V, class KTraits, class VTraits >
-    class CRBTree;
-
-    template< class K, class V, class KTraits, class VTraits >
-    class CRBMap;
-
-    template< class K, class V, class KTraits, class VTraits >
-    class CRBMultiMap;
-
-
-    // strings
-    //
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
-    template< class BaseType, bool t_bMFCDLL >
-    class CSimpleStringT;
-#else
-    template< class BaseType >
-    class CSimpleStringT;
-#endif
-
-    template< class BaseType, class StringTraits >
-    class CStringT;
-
-    template< class StringType, int t_nChars >
-    class CFixedStringT;
-
-    template< class BaseType, const int t_nSize >
-    class CStaticString;
-
-
-#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-    // simples
-    //
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-    template< class T, class TEqual >
-    class CSimpleArray;
-
-    template< class TKey, class TVal, class TEqual >
-    class CSimpleMap;
-
-#else
-
-    template< class T >
-    class CSimpleArray;
-
-    template< class T >
-    class CSimpleValArray;
-
-    template< class TKey, class TVal >
-    class CSimpleMap;
-
-#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-
-    // pointers
-    //
-    template< class E >
-    class CAutoPtr;
-
-    template< class T >
-    class CComPtr;
-
-    template< class T, const IID *piid >
-    class CComQIPtr;
-
-    template< class E, class Allocator >
-    class CHeapPtr;
-
-    template< class T >
-    class CAdapt;
-
-
-} // namespace ATL
-
-
-
-
-// indirect_iterator customizations
-//
-
-
-#include <boost/mpl/identity.hpp>
-#include <boost/pointee.hpp>
-
-
-namespace boost {
-
-
-    template< class E >
-    struct pointee< ATL::CAutoPtr<E> > :
-        mpl::identity<E>
-    { };
-
-    template< class T >
-    struct pointee< ATL::CComPtr<T> > :
-        mpl::identity<T>
-    { };
-
-    template< class T, const IID *piid >
-    struct pointee< ATL::CComQIPtr<T, piid> > :
-        mpl::identity<T>
-    { };
-
-    template< class E, class Allocator >
-    struct pointee< ATL::CHeapPtr<E, Allocator> > :
-        mpl::identity<E>
-    { };
-
-    template< class T >
-    struct pointee< ATL::CAdapt<T> > :
-        pointee<T>
-    { };
-
-
-} // namespace boost
-
-
-
-
-// extended customizations
-//
-
-
-#include <boost/iterator/indirect_iterator.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/range/detail/microsoft.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <atlbase.h> // CComBSTR
-
-
-namespace boost { namespace range_detail_microsoft {
-
-
-#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-    // arrays
-    //
-
-    struct atl_array_functions :
-        array_functions
-    {
-        template< class Iterator, class X >
-        Iterator end(X& x) // redefine
-        {
-            return x.GetData() + x.GetCount(); // no 'GetSize()'
-        }
-    };
-
-
-    template< class E, class ETraits >
-    struct customization< ATL::CAtlArray<E, ETraits> > :
-        atl_array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef E val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< class E >
-    struct customization< ATL::CAutoPtrArray<E> > :
-        atl_array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            // ATL::CAutoPtr/CHeapPtr is no assignable.
-            typedef ATL::CAutoPtr<E> val_t;
-            typedef val_t *miter_t;
-            typedef val_t const *citer_t;
-
-            typedef indirect_iterator<miter_t> mutable_iterator;
-            typedef indirect_iterator<citer_t> const_iterator;
-        };
-    };
-
-
-    template< class I, const IID *piid >
-    struct customization< ATL::CInterfaceArray<I, piid> > :
-        atl_array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ATL::CComQIPtr<I, piid> val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< class E, class ETraits >
-    struct customization< ATL::CAtlList<E, ETraits> > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef E val_t;
-
-            typedef list_iterator<X, val_t> mutable_iterator;
-            typedef list_iterator<X const, val_t const> const_iterator;
-        };
-    };
-
-
-    struct indirected_list_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            typedef typename Iterator::base_type base_t; // == list_iterator
-            return Iterator(base_t(x, x.GetHeadPosition()));
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            typedef typename Iterator::base_type base_t;
-            return Iterator(base_t(x, POSITION(0)));
-        }
-    };
-
-
-    template< class E >
-    struct customization< ATL::CAutoPtrList<E> > :
-        indirected_list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ATL::CAutoPtr<E> val_t;
-            typedef list_iterator<X, val_t> miter_t;
-            typedef list_iterator<X const, val_t const> citer_t;
-
-            typedef indirect_iterator<miter_t> mutable_iterator;
-            typedef indirect_iterator<citer_t> const_iterator;
-        };
-    };
-
-
-    template< class E, class Allocator >
-    struct customization< ATL::CHeapPtrList<E, Allocator> > :
-        indirected_list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ATL::CHeapPtr<E, Allocator> val_t;
-            typedef list_iterator<X, val_t> miter_t;
-            typedef list_iterator<X const, val_t const> citer_t;
-
-            typedef indirect_iterator<miter_t> mutable_iterator;
-            typedef indirect_iterator<citer_t> const_iterator;
-        };
-    };
-
-
-    template< class I, const IID *piid >
-    struct customization< ATL::CInterfaceList<I, piid> > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ATL::CComQIPtr<I, piid> val_t;
-
-            typedef list_iterator<X, val_t> mutable_iterator;
-            typedef list_iterator<X const, val_t const> const_iterator;
-        };
-    };
-
-
-    // maps
-    //
-
-    struct atl_rb_tree_tag
-    { };
-
-    template< >
-    struct customization< atl_rb_tree_tag > :
-        indirected_list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef typename X::CPair val_t;
-
-            typedef list_iterator<X, val_t *, val_t *> miter_t;
-            typedef list_iterator<X const, val_t const *, val_t const *> citer_t;
-            
-            typedef indirect_iterator<miter_t> mutable_iterator;
-            typedef indirect_iterator<citer_t> const_iterator;
-        };
-    };
-
-
-    template< class K, class V, class KTraits, class VTraits >
-    struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > :
-        customization< atl_rb_tree_tag >
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x) // redefine
-        {
-            typedef typename Iterator::base_type base_t; // == list_iterator
-            return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition'
-        }
-    };
-
-
-    // strings
-    //
-
-    struct atl_string_tag
-    { };
-
-    template< >
-    struct customization< atl_string_tag >
-    {
-        template< class X >
-        struct meta
-        {
-            typedef typename X::PXSTR mutable_iterator;
-            typedef typename X::PCXSTR const_iterator;
-        };
-
-        template< class Iterator, class X >
-        typename mutable_<Iterator, X>::type begin(X& x)
-        {
-            return x.GetBuffer(0);
-        }
-
-        template< class Iterator, class X >
-        Iterator begin(X const& x)
-        {
-            return x.GetString();
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return begin<Iterator>(x) + x.GetLength();
-        }
-    };
-
-
-    template< class BaseType, const int t_nSize >
-    struct customization< ATL::CStaticString<BaseType, t_nSize> >
-    {
-        template< class X >
-        struct meta
-        {
-            typedef BaseType const *mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-
-        template< class Iterator, class X >
-        Iterator begin(X const& x)
-        {
-            return x;
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X const& x)
-        {
-            return begin<Iterator>(x) + X::GetLength();
-        }
-    };
-
-
-#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-    template< >
-    struct customization< ATL::CComBSTR >
-    {
-        template< class X >
-        struct meta
-        {
-            typedef OLECHAR *mutable_iterator;
-            typedef OLECHAR const *const_iterator;
-        };
-
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return x.operator BSTR();
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return begin<Iterator>(x) + x.Length();
-        }
-    };
-
-
-    // simples
-    //
-
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-    template< class T, class TEqual >
-    struct customization< ATL::CSimpleArray<T, TEqual> > :
-#else
-    template< class T >
-    struct customization< ATL::CSimpleArray<T> > :
-#endif
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef T val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-    template< class T >
-    struct customization< ATL::CSimpleValArray<T> > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef T val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-    template< class TKey, class TVal, class TEqual >
-    struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> >
-#else
-    template< class TKey, class TVal >
-    struct customization< ATL::CSimpleMap<TKey, TVal> >
-#endif
-    {
-        template< class X >
-        struct meta
-        {
-            typedef TKey k_val_t;
-            typedef k_val_t *k_miter_t;
-            typedef k_val_t const *k_citer_t;
-
-            typedef TVal v_val_t;
-            typedef v_val_t *v_miter_t;
-            typedef v_val_t const *v_citer_t;
-
-            // Topic:
-            // 'std::pair' can't contain references
-            // because of reference to reference problem.
-
-            typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator;
-            typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator;
-        };
-
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal));
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize()));
-        }
-    };
-
-
-} } // namespace boost::range_detail_microsoft
-
-
-
-
-// range customizations
-//
-
-
-#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-    // arrays
-    //
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CAtlArray, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CAutoPtrArray, 1
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *)
-    )
-
-
-    // lists
-    //
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CAtlList, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CAutoPtrList, 1
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CHeapPtrList, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *)
-    )
-
-
-    //maps
-    //
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CAtlMap, 4
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::atl_rb_tree_tag,
-        (ATL, BOOST_PP_NIL), CRBTree, 4
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::atl_rb_tree_tag,
-        (ATL, BOOST_PP_NIL), CRBMap, 4
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::atl_rb_tree_tag,
-        (ATL, BOOST_PP_NIL), CRBMultiMap, 4
-    )
-
-
-    // strings
-    //
-    #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-            boost::range_detail_microsoft::atl_string_tag,
-            (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool)
-        )
-    #else
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-            boost::range_detail_microsoft::atl_string_tag,
-            (ATL, BOOST_PP_NIL), CSimpleStringT, 1
-        )
-    #endif
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::atl_string_tag,
-        (ATL, BOOST_PP_NIL), CStringT, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::atl_string_tag,
-        (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int)
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CStaticString, (class)(const int)
-    )
-
-
-#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
-
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    (ATL, BOOST_PP_NIL), CComBSTR
-)
-
-
-// simples
-//
-#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CSimpleArray, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CSimpleMap, 3
-    )
-
-#else
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CSimpleArray, 1
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CSimpleMap, 2
-    )
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        (ATL, BOOST_PP_NIL), CSimpleValArray, 1
-    )
-
-#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
-
-
-
-
-#endif
diff --git a/src/boost/range/begin.hpp b/src/boost/range/begin.hpp
deleted file mode 100644
index c668488..0000000
--- a/src/boost/range/begin.hpp
+++ /dev/null
@@ -1,143 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_BEGIN_HPP
-#define BOOST_RANGE_BEGIN_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-#include <boost/range/detail/begin.hpp>
-#else
-
-#include <boost/range/iterator.hpp>
-
-namespace boost
-{
-
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-namespace range_detail
-{
-#endif
-
-    //////////////////////////////////////////////////////////////////////
-    // primary template
-    //////////////////////////////////////////////////////////////////////
-
-    template< typename C >
-    inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
-    range_begin( C& c )
-    {
-        //
-        // If you get a compile-error here, it is most likely because
-        // you have not implemented range_begin() properly in
-        // the namespace of C
-        //
-        return c.begin();
-    }
-
-    //////////////////////////////////////////////////////////////////////
-    // pair
-    //////////////////////////////////////////////////////////////////////
-
-    template< typename Iterator >
-    inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
-    {
-        return p.first;
-    }
-
-    template< typename Iterator >
-    inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
-    {
-        return p.first;
-    }
-
-    //////////////////////////////////////////////////////////////////////
-    // array
-    //////////////////////////////////////////////////////////////////////
-
-    //
-    // May this be discarded? Or is it needed for bad compilers?
-    //
-    template< typename T, std::size_t sz >
-    inline const T* range_begin( const T (&a)[sz] )
-    {
-        return a;
-    }
-
-    template< typename T, std::size_t sz >
-    inline T* range_begin( T (&a)[sz] )
-    {
-        return a;
-    }
-
-
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-} // namespace 'range_detail'
-#endif
-
-// Use a ADL namespace barrier to avoid ambiguity with other unqualified
-// calls. This is particularly important with C++0x encouraging
-// unqualified calls to begin/end.
-namespace range_adl_barrier
-{
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
-{
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-    using namespace range_detail;
-#endif
-    return range_begin( r );
-}
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
-{
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-    using namespace range_detail;
-#endif
-    return range_begin( r );
-}
-
-    } // namespace range_adl_barrier
-} // namespace boost
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-namespace boost
-{
-    namespace range_adl_barrier
-    {
-        template< class T >
-        inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
-        const_begin( const T& r )
-        {
-            return boost::range_adl_barrier::begin( r );
-        }
-    } // namespace range_adl_barrier
-
-    using namespace range_adl_barrier;
-} // namespace boost
-
-#endif
-
diff --git a/src/boost/range/category.hpp b/src/boost/range/category.hpp
deleted file mode 100644
index 1574605..0000000
--- a/src/boost/range/category.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_CATEGORY_HPP
-#define BOOST_RANGE_CATEGORY_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_category : iterator_category< typename range_iterator<T>::type >
-    { };
-}
-
-#endif
diff --git a/src/boost/range/combine.hpp b/src/boost/range/combine.hpp
deleted file mode 100644
index 999bbc3..0000000
--- a/src/boost/range/combine.hpp
+++ /dev/null
@@ -1,304 +0,0 @@
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_COMBINE_HPP
-#define BOOST_RANGE_COMBINE_HPP
-
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/type_traits/is_void.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/plus.hpp>
-#include <boost/mpl/arithmetic.hpp>
-#include <boost/config.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        struct void_ { typedef void_ type; };
-    }
-
-    template<> struct range_iterator< ::boost::range_detail::void_ >
-    {
-       typedef ::boost::tuples::null_type type;
-    };
-
-    namespace range_detail
-    {
-        inline ::boost::tuples::null_type range_begin( ::boost::range_detail::void_& )
-        { return ::boost::tuples::null_type(); }
-
-        inline ::boost::tuples::null_type range_begin( const ::boost::range_detail::void_& )
-        { return ::boost::tuples::null_type(); }
-
-        inline ::boost::tuples::null_type range_end( ::boost::range_detail::void_& )
-        { return ::boost::tuples::null_type(); }
-
-        inline ::boost::tuples::null_type range_end( const ::boost::range_detail::void_& )
-        { return ::boost::tuples::null_type(); }
-
-        template< class T >
-        struct tuple_iter
-        {
-            typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
-                ::boost::is_same<T, ::boost::range_detail::void_ >::value,
-                ::boost::mpl::identity< ::boost::tuples::null_type >,
-                ::boost::range_iterator<T>
-            >::type type;
-        };
-
-        template< class Rng1, class Rng2 >
-        struct tuple_range
-        {
-            typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
-                ::boost::is_same<Rng1, ::boost::range_detail::void_ >::value,
-                ::boost::range_detail::void_,
-                ::boost::mpl::identity<Rng1>
-            >::type type;
-        };
-
-        template
-        <
-            class R1,
-            class R2,
-            class R3,
-            class R4,
-            class R5,
-            class R6
-        >
-        struct generate_tuple
-        {
-            typedef ::boost::tuples::tuple<
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R1>::type,
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R2>::type,
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R3>::type,
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R4>::type,
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R5>::type,
-                        BOOST_DEDUCED_TYPENAME tuple_iter<R6>::type
-                    > type;
-
-            static type begin( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
-            {
-                return ::boost::tuples::make_tuple( ::boost::begin(r1),
-                                                    ::boost::begin(r2),
-                                                    ::boost::begin(r3),
-                                                    ::boost::begin(r4),
-                                                    ::boost::begin(r5),
-                                                    ::boost::begin(r6) );
-            }
-
-            static type end( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
-            {
-                return ::boost::tuples::make_tuple( ::boost::end(r1),
-                                                    ::boost::end(r2),
-                                                    ::boost::end(r3),
-                                                    ::boost::end(r4),
-                                                    ::boost::end(r5),
-                                                    ::boost::end(r6) );
-            }
-        };
-
-        template
-        <
-            class R1,
-            class R2 = void_,
-            class R3 = void_,
-            class R4 = void_,
-            class R5 = void_,
-            class R6 = void_
-        >
-        struct zip_rng
-            : iterator_range<
-                zip_iterator<
-                    BOOST_DEDUCED_TYPENAME generate_tuple<R1,R2,R3,R4,R5,R6>::type
-                >
-            >
-        {
-        private:
-            typedef generate_tuple<R1,R2,R3,R4,R5,R6>        generator_t;
-            typedef BOOST_DEDUCED_TYPENAME generator_t::type tuple_t;
-            typedef zip_iterator<tuple_t>                    zip_iter_t;
-            typedef iterator_range<zip_iter_t>               base_t;
-
-        public:
-            zip_rng( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
-            : base_t( zip_iter_t( generator_t::begin(r1,r2,r3,r4,r5,r6) ),
-                      zip_iter_t( generator_t::end(r1,r2,r3,r4,r5,r6) ) )
-            {
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r4));
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r5));
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r6));
-            }
-
-            template< class Zip, class Rng >
-            zip_rng( Zip& z, Rng& r )
-            : base_t( zip_iter_t( generator_t::begin( z, r ) ),
-                      zip_iter_t( generator_t::end( z, r ) ) )
-            {
-
-                // @todo: tuple::begin( should be overloaded for this situation
-            }
-
-            struct tuple_length : ::boost::tuples::length<tuple_t>
-            { };
-
-            template< unsigned N >
-            struct get
-            {
-                template< class Z, class R >
-                static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type begin( Z& z, R& )
-                {
-                    return get<N>( z.begin().get_iterator_tuple() );
-                }
-
-                template< class Z, class R >
-                static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type end( Z& z, R& r )
-                {
-                    return get<N>( z.end().get_iterator_tuple() );
-                }
-            };
-
-        };
-
-        template< class Rng1, class Rng2 >
-        struct zip_range
-            : iterator_range<
-                zip_iterator<
-                    ::boost::tuples::tuple<
-                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
-                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
-                    >
-                >
-            >
-        {
-        private:
-            typedef zip_iterator<
-                        ::boost::tuples::tuple<
-                            BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
-                            BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
-                        >
-                    > zip_iter_t;
-            typedef iterator_range<zip_iter_t> base_t;
-
-        public:
-            zip_range( Rng1& r1, Rng2& r2 )
-            : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
-                                                              ::boost::begin(r2)) ),
-                      zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
-                                                              ::boost::end(r2)) ) )
-            {
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
-            }
-        };
-
-        template< class Rng1, class Rng2, class Rng3 >
-        struct zip_range3
-            : iterator_range<
-                zip_iterator<
-                    ::boost::tuples::tuple<
-                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
-                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
-                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
-                    >
-                >
-            >
-        {
-        private:
-            typedef zip_iterator<
-                ::boost::tuples::tuple<
-                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
-                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
-                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
-                >
-            > zip_iter_t;
-            typedef iterator_range<zip_iter_t> base_t;
-
-        public:
-            zip_range3( Rng1& r1, Rng2& r2, Rng3& r3 )
-            : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
-                                                              ::boost::begin(r2),
-                                                              ::boost::begin(r3)) ),
-                      zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
-                                                              ::boost::end(r2),
-                                                              ::boost::end(r3)) )
-                    )
-            {
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
-                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
-            }
-        };
-
-
-        struct combine_tag {};
-
-        template< class Rng >
-        inline zip_rng<Rng>
-        operator&( combine_tag, Rng& r )
-        {
-            return zip_rng<Rng>(r);
-        }
-
-        template< class Rng >
-        inline iterator_range<const Rng>
-        operator&( combine_tag, const Rng& r )
-        {
-            return iterator_range<const Rng>(r);
-        }
-
-        template
-        <
-            class R1,
-            class R2,
-            class R3,
-            class R4,
-            class R5,
-            class Rng
-        >
-        inline BOOST_DEDUCED_TYPENAME zip_rng<R1,R2,R3,R4,R5>::next
-        operator&( const zip_rng<R1,R2,R3,R4,R5>& zip,
-                   Rng& r )
-        {
-            return zip_rng<R1,R2,R3,R4,R5>::next( zip, r );
-        }
-
-    } // namespace range_detail
-
-    template< class Rng1, class Rng2 >
-    inline ::boost::range_detail::zip_range<Rng1, Rng2> combine( Rng1& r1, Rng2& r2 )
-    {
-        return ::boost::range_detail::zip_range<Rng1, Rng2>(r1, r2);
-    }
-
-    template< class Rng1, class Rng2 >
-    inline ::boost::range_detail::zip_range<const Rng1, Rng2> combine( const Rng1& r1, Rng2& r2 )
-    {
-        return ::boost::range_detail::zip_range<const Rng1, Rng2>(r1, r2);
-    }
-
-    template< class Rng1, class Rng2 >
-    inline ::boost::range_detail::zip_range<Rng1, const Rng2> combine( Rng1& r1, const Rng2& r2 )
-    {
-        return ::boost::range_detail::zip_range<Rng1, const Rng2>(r1, r2);
-    }
-
-    template< class Rng1, class Rng2 >
-    inline ::boost::range_detail::zip_range<const Rng1, const Rng2> combine( const Rng1& r1, const Rng2& r2 )
-    {
-        return ::boost::range_detail::zip_range<const Rng1, const Rng2>(r1, r2);
-    }
-
-} // namespace boost
-
-#endif
diff --git a/src/boost/range/concepts.hpp b/src/boost/range/concepts.hpp
deleted file mode 100644
index 5965293..0000000
--- a/src/boost/range/concepts.hpp
+++ /dev/null
@@ -1,366 +0,0 @@
-// Boost.Range library concept checks
-//
-//  Copyright Neil Groves 2009. Use, modification and distribution
-//  are subject to the Boost Software License, Version 1.0. (See
-//  accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//  Copyright Daniel Walker 2006. Use, modification and distribution
-//  are subject to the Boost Software License, Version 1.0. (See
-//  accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_CONCEPTS_HPP
-#define BOOST_RANGE_CONCEPTS_HPP
-
-#include <boost/concept_check.hpp>
-#include <boost/iterator/iterator_concepts.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/detail/misc_concept.hpp>
-
-/*!
- * \file
- * \brief Concept checks for the Boost Range library.
- *
- * The structures in this file may be used in conjunction with the
- * Boost Concept Check library to insure that the type of a function
- * parameter is compatible with a range concept. If not, a meaningful
- * compile time error is generated. Checks are provided for the range
- * concepts related to iterator traversal categories. For example, the
- * following line checks that the type T models the ForwardRange
- * concept.
- *
- * \code
- * BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
- * \endcode
- *
- * A different concept check is required to ensure writeable value
- * access. For example to check for a ForwardRange that can be written
- * to, the following code is required.
- *
- * \code
- * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
- * \endcode
- *
- * \see http://www.boost.org/libs/range/doc/range.html for details
- * about range concepts.
- * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
- * for details about iterator concepts.
- * \see http://www.boost.org/libs/concept_check/concept_check.htm for
- * details about concept checks.
- */
-
-namespace boost {
-
-    namespace range_detail {
-
-#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-
-// List broken compiler versions here:
-    #ifdef __GNUC__
-        // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
-        // hence the least disruptive approach is to turn-off the concept checking for
-        // this version of the compiler.
-        #if __GNUC__ == 4 && __GNUC_MINOR__ == 2
-            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
-        #endif
-    #endif
-
-    #ifdef __BORLANDC__
-        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
-    #endif
-
-    #ifdef __PATHCC__
-        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
-    #endif
-
-// Default to using the concept asserts unless we have defined it off
-// during the search for black listed compilers.
-    #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
-    #endif
-
-#endif
-
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-    #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
-#else
-    #define BOOST_RANGE_CONCEPT_ASSERT( x )
-#endif
-
-        // Rationale for the inclusion of redefined iterator concept
-        // classes:
-        //
-        // The Range algorithms often do not require that the iterators are
-        // Assignable or default constructable, but the correct standard
-        // conformant iterators do require the iterators to be a model of the
-        // Assignable concept.
-        // Iterators that contains a functor that is not assignable therefore
-        // are not correct models of the standard iterator concepts,
-        // despite being adequate for most algorithms. An example of this
-        // use case is the combination of the boost::adaptors::filtered
-        // class with a boost::lambda::bind generated functor.
-        // Ultimately modeling the range concepts using composition
-        // with the Boost.Iterator concepts would render the library
-        // incompatible with many common Boost.Lambda expressions.
-        template<class Iterator>
-        struct IncrementableIteratorConcept : CopyConstructible<Iterator>
-        {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-            typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
-
-            BOOST_RANGE_CONCEPT_ASSERT((
-                Convertible<
-                    traversal_category,
-                    incrementable_traversal_tag
-                >));
-
-            BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
-            {
-                ++i;
-                (void)i++;
-            }
-        private:
-            Iterator i;
-#endif
-        };
-
-        template<class Iterator>
-        struct SinglePassIteratorConcept
-            : IncrementableIteratorConcept<Iterator>
-            , EqualityComparable<Iterator>
-        {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-            BOOST_RANGE_CONCEPT_ASSERT((
-                Convertible<
-                    BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
-                    single_pass_traversal_tag
-                >));
-
-            BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
-            {
-                Iterator i2(++i);
-                boost::ignore_unused_variable_warning(i2);
-
-                // deliberately we are loose with the postfix version for the single pass
-                // iterator due to the commonly poor adherence to the specification means that
-                // many algorithms would be unusable, whereas actually without the check they
-                // work
-                (void)(i++);
-
-                BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i);
-                boost::ignore_unused_variable_warning(r1);
-
-                BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r2(*(++i));
-                boost::ignore_unused_variable_warning(r2);
-            }
-        private:
-            Iterator i;
-#endif
-        };
-
-        template<class Iterator>
-        struct ForwardIteratorConcept
-            : SinglePassIteratorConcept<Iterator>
-            , DefaultConstructible<Iterator>
-        {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-            typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::difference_type difference_type;
-
-            BOOST_MPL_ASSERT((is_integral<difference_type>));
-            BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
-
-            BOOST_RANGE_CONCEPT_ASSERT((
-                Convertible<
-                    BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
-                    forward_traversal_tag
-                >));
-
-            BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
-            {
-                // See the above note in the SinglePassIteratorConcept about the handling of the
-                // postfix increment. Since with forward and better iterators there is no need
-                // for a proxy, we can sensibly require that the dereference result
-                // is convertible to reference.
-                Iterator i2(i++);
-                boost::ignore_unused_variable_warning(i2);
-                BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r(*(i++));
-                boost::ignore_unused_variable_warning(r);
-            }
-        private:
-            Iterator i;
-#endif
-         };
-
-         template<class Iterator>
-         struct BidirectionalIteratorConcept
-             : ForwardIteratorConcept<Iterator>
-         {
- #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-             BOOST_RANGE_CONCEPT_ASSERT((
-                 Convertible<
-                     BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
-                     bidirectional_traversal_tag
-                 >));
-
-             BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
-             {
-                 --i;
-                 (void)i--;
-             }
-         private:
-             Iterator i;
- #endif
-         };
-
-         template<class Iterator>
-         struct RandomAccessIteratorConcept
-             : BidirectionalIteratorConcept<Iterator>
-         {
- #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-             BOOST_RANGE_CONCEPT_ASSERT((
-                 Convertible<
-                     BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
-                     random_access_traversal_tag
-                 >));
-
-             BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
-             {
-                 i += n;
-                 i = i + n;
-                 i = n + i;
-                 i -= n;
-                 i = i - n;
-                 n = i - j;
-             }
-         private:
-             BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n;
-             Iterator i;
-             Iterator j;
- #endif
-         };
-
-    } // namespace range_detail
-
-    //! Check if a type T models the SinglePassRange range concept.
-    template<class T>
-    struct SinglePassRangeConcept
-    {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-         typedef BOOST_DEDUCED_TYPENAME range_iterator<T const>::type  const_iterator;
-         typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type        iterator;
-
-         BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<iterator>));
-         BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<const_iterator>));
-
-         BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
-         {
-            // This has been modified from assigning to this->i
-            // (where i was a member variable) to improve
-            // compatibility with Boost.Lambda
-            iterator i1 = boost::begin(*m_range);
-            iterator i2 = boost::end(*m_range);
-
-            ignore_unused_variable_warning(i1);
-            ignore_unused_variable_warning(i2);
-
-            const_constraints(*m_range);
-        }
-
-    private:
-        void const_constraints(const T& const_range)
-        {
-            const_iterator ci1 = boost::begin(const_range);
-            const_iterator ci2 = boost::end(const_range);
-
-            ignore_unused_variable_warning(ci1);
-            ignore_unused_variable_warning(ci2);
-        }
-
-       // Rationale:
-       // The type of m_range is T* rather than T because it allows
-       // T to be an abstract class. The other obvious alternative of
-       // T& produces a warning on some compilers.
-       T* m_range;
-#endif
-    };
-
-    //! Check if a type T models the ForwardRange range concept.
-    template<class T>
-    struct ForwardRangeConcept : SinglePassRangeConcept<T>
-    {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
-        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
-#endif
-    };
-
-    template<class Range>
-    struct WriteableRangeConcept
-    {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<Range>::type iterator;
-
-        BOOST_CONCEPT_USAGE(WriteableRangeConcept)
-        {
-            *i = v;
-        }
-    private:
-        iterator i;
-        BOOST_DEDUCED_TYPENAME range_value<Range>::type v;
-#endif
-    };
-
-    //! Check if a type T models the WriteableForwardRange range concept.
-    template<class T>
-    struct WriteableForwardRangeConcept
-        : ForwardRangeConcept<T>
-        , WriteableRangeConcept<T>
-    {
-    };
-
-    //! Check if a type T models the BidirectionalRange range concept.
-    template<class T>
-    struct BidirectionalRangeConcept : ForwardRangeConcept<T>
-    {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-        BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
-        BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
-#endif
-    };
-
-    //! Check if a type T models the WriteableBidirectionalRange range concept.
-    template<class T>
-    struct WriteableBidirectionalRangeConcept
-        : BidirectionalRangeConcept<T>
-        , WriteableRangeConcept<T>
-    {
-    };
-
-    //! Check if a type T models the RandomAccessRange range concept.
-    template<class T>
-    struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
-    {
-#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
-        BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
-        BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
-#endif
-    };
-
-    //! Check if a type T models the WriteableRandomAccessRange range concept.
-    template<class T>
-    struct WriteableRandomAccessRangeConcept
-        : RandomAccessRangeConcept<T>
-        , WriteableRangeConcept<T>
-    {
-    };
-
-} // namespace boost
-
-#endif // BOOST_RANGE_CONCEPTS_HPP
diff --git a/src/boost/range/config.hpp b/src/boost/range/config.hpp
deleted file mode 100644
index 4e7fb24..0000000
--- a/src/boost/range/config.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_CONFIG_HPP
-#define BOOST_RANGE_CONFIG_HPP
-
-#include <boost/detail/workaround.hpp>
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/config.hpp>
-
-#ifdef BOOST_RANGE_DEDUCED_TYPENAME
-#error "macro already defined!"
-#endif
-
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-# define BOOST_RANGE_DEDUCED_TYPENAME typename
-#else
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) && !defined(_MSC_EXTENSIONS)
-#  define BOOST_RANGE_DEDUCED_TYPENAME typename
-# else
-#  define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
-# endif
-#endif
-
-#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
-#error "macro already defined!"
-#endif
-
-#if BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) || BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
-#define BOOST_RANGE_NO_ARRAY_SUPPORT 1
-#endif
-
-#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
-#define BOOST_RANGE_ARRAY_REF() (boost_range_array)
-#define BOOST_RANGE_NO_STATIC_ASSERT
-#else
-#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
-#endif
-
-
-
-#endif
-
diff --git a/src/boost/range/const_iterator.hpp b/src/boost/range/const_iterator.hpp
deleted file mode 100644
index 875320f..0000000
--- a/src/boost/range/const_iterator.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_CONST_ITERATOR_HPP
-#define BOOST_RANGE_CONST_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-#include <boost/range/detail/const_iterator.hpp>
-#else
-
-#include <boost/range/detail/extract_optional_type.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <cstddef>
-#include <utility>
-
-namespace boost
-{
-    //////////////////////////////////////////////////////////////////////////
-    // default
-    //////////////////////////////////////////////////////////////////////////
-    
-    namespace range_detail {
-        BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator )
-    }
-
-    template< typename C >
-    struct range_const_iterator : range_detail::extract_const_iterator<C>
-    {};
-    
-    //////////////////////////////////////////////////////////////////////////
-    // pair
-    //////////////////////////////////////////////////////////////////////////
-
-    template< typename Iterator >
-    struct range_const_iterator< std::pair<Iterator,Iterator> >
-    {
-        typedef Iterator type;
-    };
-    
-    //////////////////////////////////////////////////////////////////////////
-    // array
-    //////////////////////////////////////////////////////////////////////////
-
-    template< typename T, std::size_t sz >
-    struct range_const_iterator< T[sz] >
-    {
-        typedef const T* type;
-    };
-
-} // namespace boost
-
-#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-#endif
diff --git a/src/boost/range/const_reverse_iterator.hpp b/src/boost/range/const_reverse_iterator.hpp
deleted file mode 100644
index 215bcc7..0000000
--- a/src/boost/range/const_reverse_iterator.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
-#define BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/reverse_iterator.hpp>
-
-namespace boost
-{
-    //
-    // This interface is deprecated, use range_reverse_iterator<const T>
-    //
-    
-    template< typename C >
-    struct range_const_reverse_iterator : range_reverse_iterator<const C>
-    { };
-    
-} // namespace boost
-
-#endif
diff --git a/src/boost/range/counting_range.hpp b/src/boost/range/counting_range.hpp
deleted file mode 100644
index b8e4e3a..0000000
--- a/src/boost/range/counting_range.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
-#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#if BOOST_MSVC >= 1400
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-
-#include <boost/range/iterator_range_core.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-
-namespace boost
-{
-
-    template<class Value>
-    inline iterator_range<counting_iterator<Value> >
-    counting_range(Value first, Value last)
-    {
-        typedef counting_iterator<Value> counting_iterator_t;
-        typedef iterator_range<counting_iterator_t> result_t;
-        return result_t(counting_iterator_t(first),
-                        counting_iterator_t(last));
-    }
-
-    template<class Range>
-    inline iterator_range<counting_iterator<BOOST_DEDUCED_TYPENAME range_value<const Range>::type> >
-    counting_range(const Range& rng)
-    {
-        typedef counting_iterator<BOOST_DEDUCED_TYPENAME range_value<const Range>::type> counting_iterator_t;
-        typedef iterator_range<counting_iterator_t> result_t;
-        return boost::empty(rng)
-            ? result_t()
-            : result_t(
-                counting_iterator_t(*boost::begin(rng)),
-                counting_iterator_t(*boost::prior(boost::end(rng))));
-    }
-
-    template<class Range>
-    inline iterator_range<counting_iterator<BOOST_DEDUCED_TYPENAME range_value<Range>::type> >
-    counting_range(Range& rng)
-    {
-        typedef counting_iterator<BOOST_DEDUCED_TYPENAME range_value<Range>::type> counting_iterator_t;
-        typedef iterator_range<counting_iterator_t> result_t;
-        return boost::empty(rng)
-            ? result_t()
-            : result_t(
-                counting_iterator_t(*boost::begin(rng)),
-                counting_iterator_t(*boost::prior(boost::end(rng))));
-    }
-} // namespace boost
-
-#if BOOST_MSVC >= 1400
-#pragma warning(pop)
-#endif
-
-#endif // include guard
diff --git a/src/boost/range/detail/any_iterator.hpp b/src/boost/range/detail/any_iterator.hpp
deleted file mode 100644
index 5705ff0..0000000
--- a/src/boost/range/detail/any_iterator.hpp
+++ /dev/null
@@ -1,586 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
-
-#include <boost/cast.hpp>
-#include <boost/mpl/and.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/mpl/not.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/is_reference.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/range/detail/any_iterator_buffer.hpp>
-#include <boost/range/detail/any_iterator_interface.hpp>
-#include <boost/range/detail/any_iterator_wrapper.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        // metafunction to determine if T is a const reference
-        template<class T>
-        struct is_const_reference
-        {
-            typedef typename mpl::and_<
-                typename is_reference<T>::type,
-                typename is_const<
-                    typename remove_reference<T>::type
-                >::type
-            >::type type;
-        };
-
-        // metafunction to determine if T is a mutable reference
-        template<class T>
-        struct is_mutable_reference
-        {
-            typedef typename mpl::and_<
-                typename is_reference<T>::type,
-                typename mpl::not_<
-                    typename is_const<
-                        typename remove_reference<T>::type
-                    >::type
-                >::type
-            >::type type;
-        };
-
-        // metafunction to evaluate if a source 'reference' can be
-        // converted to a target 'reference' as a value.
-        //
-        // This is true, when the target reference type is actually
-        // not a reference, and the source reference is convertible
-        // to the target type.
-        template<class SourceReference, class TargetReference>
-        struct is_convertible_to_value_as_reference
-        {
-            typedef typename mpl::and_<
-                typename mpl::not_<
-                    typename is_reference<TargetReference>::type
-                >::type
-              , typename is_convertible<
-                    SourceReference
-                  , TargetReference
-                >::type
-            >::type type;
-        };
-
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer = any_iterator_default_buffer
-        >
-        class any_iterator;
-
-        // metafunction to determine if SomeIterator is an
-        // any_iterator.
-        //
-        // This is the general implementation which evaluates to false.
-        template<class SomeIterator>
-        struct is_any_iterator
-            : mpl::bool_<false>
-        {
-        };
-
-        // specialization of is_any_iterator to return true for
-        // any_iterator classes regardless of template parameters.
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct is_any_iterator<
-            any_iterator<
-                Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >
-        >
-            : mpl::bool_<true>
-        {
-        };
-    } // namespace range_detail
-
-    namespace detail
-    {
-        // Rationale:
-        // These are specialized since the iterator_facade versions lack
-        // the requisite typedefs to allow wrapping to determine the types
-        // if a user copy constructs from a postfix increment.
-
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        class postfix_increment_proxy<
-                    range_detail::any_iterator<
-                        Value
-                      , Traversal
-                      , Reference
-                      , Difference
-                      , Buffer
-                    >
-                >
-        {
-            typedef range_detail::any_iterator<
-                Value
-              , Traversal
-              , Reference
-              , Difference
-              , Buffer
-            > any_iterator_type;
-
-        public:
-            typedef Value value_type;
-            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
-            typedef Difference difference_type;
-            typedef typename iterator_pointer<any_iterator_type>::type pointer;
-            typedef Reference reference;
-
-            explicit postfix_increment_proxy(any_iterator_type const& x)
-                : stored_value(*x)
-            {}
-
-            value_type&
-            operator*() const
-            {
-                return this->stored_value;
-            }
-        private:
-            mutable value_type stored_value;
-        };
-
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        class writable_postfix_increment_proxy<
-                    range_detail::any_iterator<
-                        Value
-                      , Traversal
-                      , Reference
-                      , Difference
-                      , Buffer
-                    >
-                >
-        {
-            typedef range_detail::any_iterator<
-                        Value
-                      , Traversal
-                      , Reference
-                      , Difference
-                      , Buffer
-                    > any_iterator_type;
-         public:
-            typedef Value value_type;
-            typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
-            typedef Difference difference_type;
-            typedef typename iterator_pointer<any_iterator_type>::type pointer;
-            typedef Reference reference;
-
-            explicit writable_postfix_increment_proxy(any_iterator_type const& x)
-              : stored_value(*x)
-              , stored_iterator(x)
-            {}
-
-            // Dereferencing must return a proxy so that both *r++ = o and
-            // value_type(*r++) can work.  In this case, *r is the same as
-            // *r++, and the conversion operator below is used to ensure
-            // readability.
-            writable_postfix_increment_proxy const&
-            operator*() const
-            {
-                return *this;
-            }
-
-            // Provides readability of *r++
-            operator value_type&() const
-            {
-                return stored_value;
-            }
-
-            // Provides writability of *r++
-            template <class T>
-            T const& operator=(T const& x) const
-            {
-                *this->stored_iterator = x;
-                return x;
-            }
-
-            // This overload just in case only non-const objects are writable
-            template <class T>
-            T& operator=(T& x) const
-            {
-                *this->stored_iterator = x;
-                return x;
-            }
-
-            // Provides X(r++)
-            operator any_iterator_type const&() const
-            {
-                return stored_iterator;
-            }
-
-         private:
-            mutable value_type stored_value;
-            any_iterator_type stored_iterator;
-        };
-
-
-    }
-
-    namespace range_detail
-    {
-        template<
-            class Value
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        class any_iterator
-            : public iterator_facade<
-                        any_iterator<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                        >
-                    , Value
-                    , Traversal
-                    , Reference
-                    , Difference
-                >
-        {
-            template<
-                class OtherValue
-              , class OtherTraversal
-              , class OtherReference
-              , class OtherDifference
-              , class OtherBuffer
-            >
-            friend class any_iterator;
-
-            struct enabler {};
-            struct disabler {};
-
-            typedef typename any_iterator_interface_type_generator<
-                Traversal
-              , Reference
-              , Difference
-              , Buffer
-            >::type abstract_base_type;
-
-            typedef iterator_facade<
-                        any_iterator<
-                            Value
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                        >
-                      , Value
-                      , Traversal
-                      , Reference
-                      , Difference
-                  > base_type;
-
-            typedef Buffer buffer_type;
-
-        public:
-            typedef typename base_type::value_type value_type;
-            typedef typename base_type::reference reference;
-            typedef typename base_type::difference_type difference_type;
-
-            // Default constructor
-            any_iterator()
-                : m_impl(0) {}
-
-            // Simple copy construction without conversion
-            any_iterator(const any_iterator& other)
-                : base_type(other)
-                , m_impl(other.m_impl
-                            ? other.m_impl->clone(m_buffer)
-                            : 0)
-            {
-            }
-
-            // Simple assignment operator without conversion
-            any_iterator& operator=(const any_iterator& other)
-            {
-                if (this != &other)
-                {
-                    if (m_impl)
-                        m_impl->~abstract_base_type();
-                    m_buffer.deallocate();
-                    m_impl = 0;
-                    if (other.m_impl)
-                        m_impl = other.m_impl->clone(m_buffer);
-                }
-                return *this;
-            }
-
-            // Implicit conversion from another any_iterator where the
-            // conversion is from a non-const reference to a const reference
-            template<
-                class OtherValue
-              , class OtherTraversal
-              , class OtherReference
-              , class OtherDifference
-            >
-            any_iterator(const any_iterator<
-                                OtherValue,
-                                OtherTraversal,
-                                OtherReference,
-                                OtherDifference,
-                                Buffer
-                            >& other,
-                         typename enable_if<
-                            typename mpl::and_<
-                                typename is_mutable_reference<OtherReference>::type,
-                                typename is_const_reference<Reference>::type
-                            >::type,
-                            enabler
-                        >::type* = 0
-                    )
-                : m_impl(other.m_impl
-                            ? other.m_impl->clone_const_ref(m_buffer)
-                         : 0
-                        )
-            {
-            }
-
-            // Implicit conversion from another any_iterator where the
-            // reference types of the source and the target are references
-            // that are either both const, or both non-const.
-            template<
-                class OtherValue
-              , class OtherTraversal
-              , class OtherReference
-              , class OtherDifference
-            >
-            any_iterator(const any_iterator<
-                                OtherValue
-                              , OtherTraversal
-                              , OtherReference
-                              , OtherDifference
-                              , Buffer
-                            >& other,
-                         typename enable_if<
-                            typename mpl::or_<
-                                typename mpl::and_<
-                                    typename is_mutable_reference<OtherReference>::type,
-                                    typename is_mutable_reference<Reference>::type
-                                >::type,
-                                typename mpl::and_<
-                                    typename is_const_reference<OtherReference>::type,
-                                    typename is_const_reference<Reference>::type
-                                >::type
-                            >::type,
-                            enabler
-                        >::type* = 0
-                        )
-                : m_impl(other.m_impl
-                            ? other.m_impl->clone(m_buffer)
-                         : 0
-                        )
-            {
-            }
-
-            // Implicit conversion to an any_iterator that uses a value for
-            // the reference type.
-            template<
-                class OtherValue
-              , class OtherTraversal
-              , class OtherReference
-              , class OtherDifference
-            >
-            any_iterator(const any_iterator<
-                                OtherValue
-                              , OtherTraversal
-                              , OtherReference
-                              , OtherDifference
-                              , Buffer
-                            >& other,
-                        typename enable_if<
-                            typename is_convertible_to_value_as_reference<
-                                        OtherReference
-                                      , Reference
-                                    >::type,
-                            enabler
-                        >::type* = 0
-                        )
-                : m_impl(other.m_impl
-                            ? other.m_impl->clone_reference_as_value(m_buffer)
-                            : 0
-                            )
-            {
-            }
-
-            any_iterator clone() const
-            {
-                any_iterator result;
-                if (m_impl)
-                    result.m_impl = m_impl->clone(result.m_buffer);
-                return result;
-            }
-
-            any_iterator<
-                Value
-              , Traversal
-              , typename abstract_base_type::const_reference
-              , Difference
-              , Buffer
-            >
-            clone_const_ref() const
-            {
-                typedef any_iterator<
-                    Value
-                  , Traversal
-                  , typename abstract_base_type::const_reference
-                  , Difference
-                  , Buffer
-                > result_type;
-
-                result_type result;
-
-                if (m_impl)
-                    result.m_impl = m_impl->clone_const_ref(result.m_buffer);
-
-                return result;
-            }
-
-            // implicit conversion and construction from type-erasure-compatible
-            // iterators
-            template<class WrappedIterator>
-            explicit any_iterator(
-                const WrappedIterator& wrapped_iterator,
-                typename disable_if<
-                    typename is_any_iterator<WrappedIterator>::type
-                  , disabler
-                >::type* = 0
-                )
-            {
-                typedef typename any_iterator_wrapper_type_generator<
-                            WrappedIterator
-                          , Traversal
-                          , Reference
-                          , Difference
-                          , Buffer
-                        >::type wrapper_type;
-
-                void* ptr = m_buffer.allocate(sizeof(wrapper_type));
-                m_impl = new(ptr) wrapper_type(wrapped_iterator);
-            }
-
-            ~any_iterator()
-            {
-                // manually run the destructor, the deallocation is automatically
-                // handled by the any_iterator_small_buffer base class.
-                if (m_impl)
-                    m_impl->~abstract_base_type();
-            }
-
-        private:
-            friend class ::boost::iterator_core_access;
-
-            Reference dereference() const
-            {
-                BOOST_ASSERT( m_impl );
-                return m_impl->dereference();
-            }
-
-            bool equal(const any_iterator& other) const
-            {
-                return (m_impl == other.m_impl)
-                    || (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
-            }
-
-            void increment()
-            {
-                BOOST_ASSERT( m_impl );
-                m_impl->increment();
-            }
-
-            void decrement()
-            {
-                BOOST_ASSERT( m_impl );
-                m_impl->decrement();
-            }
-
-            Difference distance_to(const any_iterator& other) const
-            {
-                return m_impl && other.m_impl
-                    ? m_impl->distance_to(*other.m_impl)
-                    : 0;
-            }
-
-            void advance(Difference offset)
-            {
-                BOOST_ASSERT( m_impl );
-                m_impl->advance(offset);
-            }
-
-            any_iterator& swap(any_iterator& other)
-            {
-                BOOST_ASSERT( this != &other );
-                // grab a temporary copy of the other iterator
-                any_iterator tmp(other);
-
-                // deallocate the other iterator, taking care to obey the
-                // class-invariants in-case of exceptions later
-                if (other.m_impl)
-                {
-                    other.m_impl->~abstract_base_type();
-                    other.m_buffer.deallocate();
-                    other.m_impl = 0;
-                }
-
-                // If this is a non-null iterator then we need to put
-                // a clone of this iterators impementation into the other
-                // iterator.
-                // We can't just swap because of the small buffer optimization.
-                if (m_impl)
-                {
-                    other.m_impl = m_impl->clone(other.m_buffer);
-                    m_impl->~abstract_base_type();
-                    m_buffer.deallocate();
-                    m_impl = 0;
-                }
-
-                // assign to this instance a clone of the temporarily held
-                // tmp which represents the input other parameter at the
-                // start of execution of this function.
-                if (tmp.m_impl)
-                    m_impl = tmp.m_impl->clone(m_buffer);
-
-                return *this;
-            }
-
-            buffer_type m_buffer;
-            abstract_base_type* m_impl;
-        };
-
-    } // namespace range_detail
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_buffer.hpp b/src/boost/range/detail/any_iterator_buffer.hpp
deleted file mode 100644
index 2bb5d53..0000000
--- a/src/boost/range/detail/any_iterator_buffer.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
-
-#include <boost/array.hpp>
-#include <boost/assert.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/noncopyable.hpp>
-
-namespace boost
-{
-    template<std::size_t StackBufferSize>
-    class any_iterator_buffer
-        : noncopyable
-    {
-        BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
-    public:
-        any_iterator_buffer()
-            : m_ptr()
-        {
-        }
-
-        ~any_iterator_buffer()
-        {
-            delete [] m_ptr;
-        }
-
-        void* allocate(std::size_t bytes)
-        {
-            BOOST_ASSERT( !m_ptr );
-            if (bytes <= StackBufferSize)
-                return m_buffer.data();
-
-            m_ptr = new char[bytes];
-            return m_ptr;
-        }
-
-        void deallocate()
-        {
-            delete [] m_ptr;
-            m_ptr = 0;
-        }
-
-    private:
-        // Rationale:
-        // Do not use inheritance from noncopyable because this causes
-        // the concepts to erroneous detect the derived any_iterator
-        // as noncopyable.
-        any_iterator_buffer(const any_iterator_buffer&);
-        void operator=(const any_iterator_buffer&);
-
-        char* m_ptr;
-        boost::array<char, StackBufferSize> m_buffer;
-    };
-
-    class any_iterator_heap_only_buffer
-        : noncopyable
-    {
-    public:
-        any_iterator_heap_only_buffer()
-            : m_ptr()
-        {
-        }
-
-        ~any_iterator_heap_only_buffer()
-        {
-            delete [] m_ptr;
-        }
-
-        void* allocate(std::size_t bytes)
-        {
-            BOOST_ASSERT( !m_ptr );
-            m_ptr = new char[bytes];
-            return m_ptr;
-        }
-
-        void deallocate()
-        {
-            delete [] m_ptr;
-            m_ptr = 0;
-        }
-
-    private:
-        char* m_ptr;
-    };
-
-    template<std::size_t StackBufferSize>
-    class any_iterator_stack_only_buffer
-    {
-        BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
-    public:
-        void* allocate(std::size_t bytes)
-        {
-            BOOST_ASSERT( bytes <= m_buffer.size() );
-            return m_buffer.data();
-        }
-
-        void deallocate()
-        {
-        }
-
-    private:
-        boost::array<char, StackBufferSize> m_buffer;
-    };
-
-    typedef any_iterator_buffer<64> any_iterator_default_buffer;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_interface.hpp b/src/boost/range/detail/any_iterator_interface.hpp
deleted file mode 100644
index d8f4de7..0000000
--- a/src/boost/range/detail/any_iterator_interface.hpp
+++ /dev/null
@@ -1,258 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
-
-#include <boost/range/detail/any_iterator_buffer.hpp>
-#include <boost/type_traits/add_reference.hpp>
-#include <boost/type_traits/add_const.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<class T>
-        struct const_reference_type_generator
-        {
-            typedef typename mpl::if_<
-                typename is_reference<T>::type,
-                typename add_reference<
-                    typename add_const<
-                        typename remove_reference<T>::type
-                    >::type
-                >::type,
-                T
-            >::type type;
-        };
-
-        template<
-            class Reference
-          , class Buffer
-        >
-        struct any_incrementable_iterator_interface
-        {
-            typedef Reference reference;
-            typedef typename const_reference_type_generator<
-                Reference
-            >::type const_reference;
-            typedef typename remove_const<
-                typename remove_reference<Reference>::type
-            >::type reference_as_value_type;
-
-            typedef Buffer buffer_type;
-
-            virtual ~any_incrementable_iterator_interface() {}
-
-            virtual any_incrementable_iterator_interface*
-                        clone(buffer_type& buffer) const = 0;
-
-            virtual any_incrementable_iterator_interface<const_reference, Buffer>*
-                        clone_const_ref(buffer_type& buffer) const = 0;
-
-            virtual any_incrementable_iterator_interface<reference_as_value_type, Buffer>*
-                        clone_reference_as_value(buffer_type& buffer) const = 0;
-
-            virtual void increment() = 0;
-        };
-
-        template<
-            class Reference
-          , class Buffer
-        >
-        struct any_single_pass_iterator_interface
-            : any_incrementable_iterator_interface<Reference, Buffer>
-        {
-            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference reference;
-            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::const_reference const_reference;
-            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
-            typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
-
-            virtual any_single_pass_iterator_interface*
-                        clone(buffer_type& buffer) const = 0;
-
-            virtual any_single_pass_iterator_interface<const_reference, Buffer>*
-                        clone_const_ref(buffer_type& buffer) const = 0;
-
-            virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
-                        clone_reference_as_value(buffer_type& buffer) const = 0;
-
-            virtual Reference dereference() const = 0;
-
-            virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
-        };
-
-        template<
-            class Reference
-          , class Buffer
-        >
-        struct any_forward_iterator_interface
-            : any_single_pass_iterator_interface<Reference, Buffer>
-        {
-            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference reference;
-            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::const_reference const_reference;
-            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
-            typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
-
-            virtual any_forward_iterator_interface*
-                        clone(buffer_type& buffer) const = 0;
-
-            virtual any_forward_iterator_interface<const_reference, Buffer>*
-                        clone_const_ref(buffer_type& buffer) const = 0;
-
-            virtual any_forward_iterator_interface<reference_as_value_type, Buffer>*
-                        clone_reference_as_value(buffer_type& buffer) const = 0;
-        };
-
-        template<
-            class Reference
-          , class Buffer
-        >
-        struct any_bidirectional_iterator_interface
-            : any_forward_iterator_interface<Reference, Buffer>
-        {
-            typedef typename any_forward_iterator_interface<Reference, Buffer>::reference reference;
-            typedef typename any_forward_iterator_interface<Reference, Buffer>::const_reference const_reference;
-            typedef typename any_forward_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
-            typedef typename any_forward_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
-
-            virtual any_bidirectional_iterator_interface*
-                        clone(buffer_type& buffer) const = 0;
-
-            virtual any_bidirectional_iterator_interface<const_reference, Buffer>*
-                        clone_const_ref(buffer_type& buffer) const = 0;
-
-            virtual any_bidirectional_iterator_interface<reference_as_value_type, Buffer>*
-                        clone_reference_as_value(buffer_type& buffer) const = 0;
-
-            virtual void decrement() = 0;
-        };
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_random_access_iterator_interface
-            : any_bidirectional_iterator_interface<
-                    Reference
-                  , Buffer
-                >
-        {
-            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference reference;
-            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::const_reference const_reference;
-            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
-            typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
-            typedef Difference difference_type;
-
-            virtual any_random_access_iterator_interface*
-                        clone(buffer_type& buffer) const = 0;
-
-            virtual any_random_access_iterator_interface<const_reference, Difference, Buffer>*
-                        clone_const_ref(buffer_type& buffer) const = 0;
-
-            virtual any_random_access_iterator_interface<reference_as_value_type, Difference, Buffer>*
-                        clone_reference_as_value(buffer_type& buffer) const = 0;
-
-            virtual void advance(Difference offset) = 0;
-
-            virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0;
-        };
-
-        template<
-            class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator;
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator<
-                    incrementable_traversal_tag
-                  , Reference
-                  , Difference
-                  , Buffer
-                >
-        {
-            typedef any_incrementable_iterator_interface<Reference, Buffer> type;
-        };
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator<
-                    single_pass_traversal_tag
-                  , Reference
-                  , Difference
-                  , Buffer
-                >
-        {
-            typedef any_single_pass_iterator_interface<Reference, Buffer> type;
-        };
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator<
-                    forward_traversal_tag
-                  , Reference
-                  , Difference
-                  , Buffer
-                >
-        {
-            typedef any_forward_iterator_interface<Reference, Buffer> type;
-        };
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator<
-                    bidirectional_traversal_tag
-                  , Reference
-                  , Difference
-                  , Buffer
-                >
-        {
-            typedef any_bidirectional_iterator_interface<Reference, Buffer> type;
-        };
-
-        template<
-            class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_interface_type_generator<
-                    random_access_traversal_tag
-                  , Reference
-                  , Difference
-                  , Buffer
-                >
-        {
-            typedef any_random_access_iterator_interface<
-                        Reference
-                      , Difference
-                      , Buffer
-                    > type;
-        };
-
-    } // namespace range_detail
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_wrapper.hpp b/src/boost/range/detail/any_iterator_wrapper.hpp
deleted file mode 100644
index b5313a7..0000000
--- a/src/boost/range/detail/any_iterator_wrapper.hpp
+++ /dev/null
@@ -1,590 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
-
-#include <boost/range/config.hpp>
-#include <boost/range/detail/any_iterator_interface.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Buffer
-        >
-        class any_incrementable_iterator_wrapper
-            : public any_incrementable_iterator_interface<
-                        Reference
-                      , Buffer
-                    >
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> ));
-        public:
-            typedef WrappedIterator wrapped_type;
-
-            BOOST_STATIC_ASSERT(( is_convertible<
-                                    typename iterator_reference<WrappedIterator>::type
-                                  , Reference
-                                  >::value ));
-
-            any_incrementable_iterator_wrapper()
-                : m_it()
-            {}
-
-            explicit any_incrementable_iterator_wrapper(wrapped_type it)
-                : m_it(it)
-            {}
-
-        // any_incrementable_iterator implementation
-            virtual any_incrementable_iterator_wrapper* clone(
-                typename any_incrementable_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                return new (buffer.allocate(sizeof(*this)))
-                                any_incrementable_iterator_wrapper(m_it);
-            }
-
-            virtual any_incrementable_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_incrementable_iterator_wrapper::const_reference
-                      , Buffer
-                    >* clone_const_ref(
-                        typename any_incrementable_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                typedef any_incrementable_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_incrementable_iterator_wrapper::const_reference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual any_incrementable_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_incrementable_iterator_wrapper::reference_as_value_type
-                      , Buffer
-                    >* clone_reference_as_value(
-                        typename any_incrementable_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                typedef any_incrementable_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_incrementable_iterator_wrapper::reference_as_value_type
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual void increment()
-            {
-                ++m_it;
-            }
-
-         private:
-            wrapped_type m_it;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Buffer
-        >
-        class any_single_pass_iterator_wrapper
-            : public any_single_pass_iterator_interface<
-                        Reference
-                      , Buffer
-                    >
-        {
-            struct disabler {};
-            BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
-        public:
-
-            any_single_pass_iterator_wrapper()
-                : m_it()
-            {}
-
-            explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
-                : m_it(it)
-            {}
-        // any_single_pass_iterator_interface<Reference> implementation
-            virtual any_single_pass_iterator_wrapper* clone(
-                typename any_single_pass_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                return new (buffer.allocate(sizeof(*this)))
-                            any_single_pass_iterator_wrapper(m_it);
-            }
-
-            virtual any_single_pass_iterator_wrapper<
-                WrappedIterator
-              , typename any_single_pass_iterator_wrapper::const_reference
-              , Buffer
-            >* clone_const_ref(
-                   typename any_single_pass_iterator_wrapper::buffer_type& buffer
-                   ) const
-            {
-                typedef any_single_pass_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_single_pass_iterator_wrapper::const_reference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual any_single_pass_iterator_wrapper<
-                WrappedIterator
-              , typename any_single_pass_iterator_wrapper::reference_as_value_type
-              , Buffer
-            >* clone_reference_as_value(
-                typename any_single_pass_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                typedef any_single_pass_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_single_pass_iterator_wrapper::reference_as_value_type
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual void increment()
-            {
-                ++m_it;
-            }
-
-            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
-            {
-                return m_it == boost::polymorphic_downcast<const any_single_pass_iterator_wrapper*>(&other)->m_it;
-            }
-
-            virtual Reference dereference() const
-            {
-                return *m_it;
-            }
-
-        private:
-            WrappedIterator m_it;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Buffer
-        >
-        class any_forward_iterator_wrapper
-            : public any_forward_iterator_interface<
-                        Reference
-                      , Buffer
-                    >
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
-        public:
-            any_forward_iterator_wrapper()
-                : m_it()
-            {}
-
-            explicit any_forward_iterator_wrapper(const WrappedIterator& it)
-                : m_it(it)
-            {}
-
-            // any_forward_iterator_interface<Reference> implementation
-            virtual any_forward_iterator_wrapper* clone(
-                typename any_forward_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                return new (buffer.allocate(sizeof(*this)))
-                                any_forward_iterator_wrapper(m_it);
-            }
-
-            virtual any_forward_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_forward_iterator_wrapper::const_reference
-                      , Buffer
-                    >* clone_const_ref(
-                            typename any_forward_iterator_wrapper::buffer_type& buffer
-                        ) const
-            {
-                typedef any_forward_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_forward_iterator_wrapper::const_reference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual any_forward_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_forward_iterator_wrapper::reference_as_value_type
-                      , Buffer
-                    >* clone_reference_as_value(
-                            typename any_forward_iterator_wrapper::buffer_type& buffer
-                    ) const
-            {
-                typedef any_forward_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_forward_iterator_wrapper::reference_as_value_type
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual void increment()
-            {
-                ++m_it;
-            }
-
-            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
-            {
-                return m_it == boost::polymorphic_downcast<const any_forward_iterator_wrapper*>(&other)->m_it;
-            }
-
-            virtual Reference dereference() const
-            {
-                return *m_it;
-            }
-        private:
-            WrappedIterator m_it;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Buffer
-        >
-        class any_bidirectional_iterator_wrapper
-            : public any_bidirectional_iterator_interface<
-                        Reference
-                      , Buffer
-                    >
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
-        public:
-            any_bidirectional_iterator_wrapper()
-                : m_it()
-            {
-            }
-
-            explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
-                : m_it(it)
-            {
-            }
-
-            virtual any_bidirectional_iterator_wrapper* clone(
-                typename any_bidirectional_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                return new (buffer.allocate(sizeof(*this)))
-                            any_bidirectional_iterator_wrapper(*this);
-            }
-
-            virtual any_bidirectional_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_bidirectional_iterator_wrapper::const_reference
-                      , Buffer
-                    >* clone_const_ref(
-                           typename any_bidirectional_iterator_wrapper::buffer_type& buffer
-                       ) const
-            {
-                typedef any_bidirectional_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_bidirectional_iterator_wrapper::const_reference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual any_bidirectional_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_bidirectional_iterator_wrapper::reference_as_value_type
-                      , Buffer
-                    >* clone_reference_as_value(
-                           typename any_bidirectional_iterator_wrapper::buffer_type& buffer
-                       ) const
-            {
-                typedef any_bidirectional_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_bidirectional_iterator_wrapper::reference_as_value_type
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual void increment()
-            {
-                ++m_it;
-            }
-
-            virtual void decrement()
-            {
-                --m_it;
-            }
-
-            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
-            {
-                return m_it == boost::polymorphic_downcast<const any_bidirectional_iterator_wrapper*>(&other)->m_it;
-            }
-
-            virtual Reference dereference() const
-            {
-                return *m_it;
-            }
-
-        private:
-            WrappedIterator m_it;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        class any_random_access_iterator_wrapper
-            : public any_random_access_iterator_interface<
-                            Reference
-                          , Difference
-                          , Buffer
-                        >
-        {
-            BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
-        public:
-            typedef Difference difference_type;
-
-            any_random_access_iterator_wrapper()
-                : m_it()
-            {
-            }
-
-            explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
-                : m_it(other)
-            {
-            }
-
-            virtual any_random_access_iterator_wrapper* clone(
-                    typename any_random_access_iterator_wrapper::buffer_type& buffer
-                ) const
-            {
-                return new (buffer.allocate(sizeof(*this)))
-                                any_random_access_iterator_wrapper(*this);
-            }
-
-            virtual any_random_access_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_random_access_iterator_wrapper::const_reference
-                      , Difference
-                      , Buffer
-                    >* clone_const_ref(
-                           typename any_random_access_iterator_wrapper::buffer_type& buffer
-                           ) const
-            {
-                typedef any_random_access_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_random_access_iterator_wrapper::const_reference
-                          , Difference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual any_random_access_iterator_wrapper<
-                        WrappedIterator
-                      , typename any_random_access_iterator_wrapper::reference_as_value_type
-                      , Difference
-                      , Buffer
-                    >* clone_reference_as_value(
-                           typename any_random_access_iterator_wrapper::buffer_type& buffer
-                           ) const
-            {
-                typedef any_random_access_iterator_wrapper<
-                            WrappedIterator
-                          , typename any_random_access_iterator_wrapper::reference_as_value_type
-                          , Difference
-                          , Buffer
-                        > result_type;
-
-                return new (buffer.allocate(sizeof(result_type)))
-                            result_type(m_it);
-            }
-
-            virtual void increment()
-            {
-                ++m_it;
-            }
-
-            virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
-            {
-                return m_it == boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it;
-            }
-
-            virtual void decrement()
-            {
-                --m_it;
-            }
-
-            virtual void advance(Difference offset)
-            {
-                m_it += offset;
-            }
-
-            virtual Reference dereference() const
-            {
-                return *m_it;
-            }
-
-            virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
-            {
-                return boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it - m_it;
-            }
-
-        private:
-            WrappedIterator m_it;
-        };
-
-        template<
-            class WrappedIterator
-          , class Traversal
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator;
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator<
-            WrappedIterator
-          , incrementable_traversal_tag
-          , Reference
-          , Difference
-          , Buffer
-        >
-        {
-            typedef any_incrementable_iterator_wrapper<
-                        WrappedIterator
-                      , Reference
-                      , Buffer
-                    > type;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator<
-            WrappedIterator
-          , single_pass_traversal_tag
-          , Reference
-          , Difference
-          , Buffer
-        >
-        {
-            typedef any_single_pass_iterator_wrapper<
-                        WrappedIterator
-                      , Reference
-                      , Buffer
-                > type;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator<
-            WrappedIterator
-          , forward_traversal_tag
-          , Reference
-          , Difference
-          , Buffer
-        >
-        {
-            typedef any_forward_iterator_wrapper<
-                WrappedIterator
-              , Reference
-              , Buffer
-            > type;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator<
-            WrappedIterator
-          , bidirectional_traversal_tag
-          , Reference
-          , Difference
-          , Buffer
-        >
-        {
-            typedef any_bidirectional_iterator_wrapper<
-                WrappedIterator
-              , Reference
-              , Buffer
-            > type;
-        };
-
-        template<
-            class WrappedIterator
-          , class Reference
-          , class Difference
-          , class Buffer
-        >
-        struct any_iterator_wrapper_type_generator<
-            WrappedIterator
-          , random_access_traversal_tag
-          , Reference
-          , Difference
-          , Buffer
-        >
-        {
-            typedef any_random_access_iterator_wrapper<
-                WrappedIterator
-              , Reference
-              , Difference
-              , Buffer
-            > type;
-        };
-
-    } // namespace range_detail
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/as_literal.hpp b/src/boost/range/detail/as_literal.hpp
deleted file mode 100644
index 0bd9a15..0000000
--- a/src/boost/range/detail/as_literal.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_AS_LITERAL_HPP
-#define BOOST_RANGE_DETAIL_AS_LITERAL_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/detail/detail_str.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    template< class Range >
-    inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type> 
-    as_literal( Range& r )
-    {
-        return ::boost::make_iterator_range( ::boost::range_detail::str_begin(r),
-                                             ::boost::range_detail::str_end(r) );
-    }
-
-}
-
-#endif
diff --git a/src/boost/range/detail/begin.hpp b/src/boost/range/detail/begin.hpp
deleted file mode 100644
index f3da732..0000000
--- a/src/boost/range/detail/begin.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_BEGIN_HPP
-#define BOOST_RANGE_DETAIL_BEGIN_HPP
-
-#include <boost/config.hpp> // BOOST_MSVC
-#include <boost/detail/workaround.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/detail/common.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1310)
-# include <boost/range/value_type.hpp>
-#endif
-
-namespace boost
-{
-
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_begin;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_begin<std_container_>
-        {
-            template< typename C >
-            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type fun( C& c )
-            {
-                return c.begin();
-            };
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_begin<std_pair_>
-        {
-            template< typename P >
-            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type fun( const P& p )
-            {
-                return p.first;
-            }
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_begin<array_>
-        {
-        #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
-            template< typename T, std::size_t sz >
-            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost_range_array;
-            }
-        #else
-            template<typename T>
-            static BOOST_RANGE_DEDUCED_TYPENAME range_value<T>::type* fun(T& t)
-            {
-                return t;
-            }
-        #endif
-        };
-
-    } // namespace 'range_detail'
-
-    namespace range_adl_barrier
-    {
-        template< typename C >
-        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
-        begin( C& c )
-        {
-            return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
-        }
-    }
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/collection_traits.hpp b/src/boost/range/detail/collection_traits.hpp
deleted file mode 100644
index c50ca3e..0000000
--- a/src/boost/range/detail/collection_traits.hpp
+++ /dev/null
@@ -1,266 +0,0 @@
-//  Boost string_algo library collection_traits.hpp header file  -------------//
-
-//  Copyright Pavol Droba 2002-2003. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-
-// (C) Copyright Thorsten Ottosen 2002-2003. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-
-// (C) Copyright Jeremy Siek 2001. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-
-//  Original idea of container traits was proposed by Jeremy Siek and
-//  Thorsten Ottosen. This implementation is lightweighted version
-//  of container_traits adapter for usage with string_algo library
-
-#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
-#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
-
-#include <boost/algorithm/string/config.hpp>
-#include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/mpl/eval_if.hpp>
-
-// Implementation
-#include <boost/range/detail/collection_traits_detail.hpp>
-
-/*! \file
-    Defines collection_traits class and related free-standing functions.
-    This facility is used to unify the access to different types of collections.
-    It allows the algorithms in the library to work with STL collections, c-style
-    array, null-terminated c-strings (and more) using the same interface.
-*/
-
-namespace boost {
-    namespace algorithm {
-
-//  collection_traits template class -----------------------------------------//
-        
-        //! collection_traits class
-        /*!
-            Collection traits provide uniform access to different types of 
-            collections. This functionality allows to write generic algorithms
-            which work with several different kinds of collections.
-
-            Currently following collection types are supported:
-                - containers with STL compatible container interface ( see ContainerConcept )
-                    ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... )
-                - c-style array 
-                   ( \c char[10], \c int[15] ... )
-                - null-terminated c-strings
-                    ( \c char*, \c wchar_T* )
-                - std::pair of iterators 
-                    ( i.e \c std::pair<vector<int>::iterator,vector<int>::iterator> )
-
-            Collection traits provide an external collection interface operations.
-            All are accessible using free-standing functions.
-
-            The following operations are supported:
-                - \c size()
-                - \c empty()
-                - \c begin()
-                - \c end()
-
-            Container traits have somewhat limited functionality on compilers not
-            supporting partial template specialization and partial template ordering.
-        */
-        template< typename T >
-        struct collection_traits
-        {
-        private:
-            typedef BOOST_STRING_TYPENAME ::boost::mpl::eval_if< 
-                    ::boost::algorithm::detail::is_pair<T>, 
-                        detail::pair_container_traits_selector<T>,
-                        BOOST_STRING_TYPENAME ::boost::mpl::eval_if< 
-                        ::boost::is_array<T>, 
-                            detail::array_container_traits_selector<T>,
-                            BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
-                            ::boost::is_pointer<T>,
-                                detail::pointer_container_traits_selector<T>,
-                                detail::default_container_traits_selector<T>
-                            >
-                        > 
-                >::type container_helper_type;
-        public:
-            //! Function type       
-            typedef container_helper_type function_type;        
-            //! Value type
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::value_type value_type;
-            //! Size type
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::size_type size_type;
-            //! Iterator type
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::iterator iterator;
-            //! Const iterator type
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::const_iterator const_iterator;
-            //! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::result_iterator result_iterator;
-            //! Difference type
-            typedef BOOST_STRING_TYPENAME 
-                container_helper_type::difference_type difference_type;
-
-        }; // 'collection_traits'
-
-//  collection_traits metafunctions -----------------------------------------//
-
-        //! Container value_type trait
-        /*!
-            Extract the type of elements contained in a container
-        */
-        template< typename C >
-        struct value_type_of
-        {
-            typedef BOOST_STRING_TYPENAME collection_traits<C>::value_type type;
-        };
-        
-        //! Container difference trait
-        /*!
-            Extract the container's difference type
-        */
-        template< typename C >
-        struct difference_type_of
-        {
-            typedef BOOST_STRING_TYPENAME collection_traits<C>::difference_type type;
-        };
-
-        //! Container iterator trait
-        /*!
-            Extract the container's iterator type
-        */
-        template< typename C >
-        struct iterator_of
-        {
-            typedef BOOST_STRING_TYPENAME collection_traits<C>::iterator type;
-        };
-
-        //! Container const_iterator trait
-        /*!
-            Extract the container's const_iterator type
-        */
-        template< typename C >
-        struct const_iterator_of
-        {
-            typedef BOOST_STRING_TYPENAME collection_traits<C>::const_iterator type;
-        };
-
-
-        //! Container result_iterator
-        /*!
-            Extract the container's result_iterator type. This type maps to \c C::iterator
-            for mutable container and \c C::const_iterator for const containers.
-        */
-        template< typename C >
-        struct result_iterator_of
-        {
-            typedef BOOST_STRING_TYPENAME collection_traits<C>::result_iterator type;
-        };
-
-//  collection_traits related functions -----------------------------------------//
-
-        //! Free-standing size() function
-        /*!
-            Get the size of the container. Uses collection_traits.
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::size_type
-        size( const C& c )
-        {
-            return collection_traits<C>::function_type::size( c ); 
-        }
-
-        //! Free-standing empty() function
-        /*!
-            Check whether the container is empty. Uses container traits.
-        */
-        template< typename C >
-        inline bool empty( const C& c )
-        {
-            return collection_traits<C>::function_type::empty( c );
-        }
-
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        //! Free-standing begin() function
-        /*!
-            Get the begin iterator of the container. Uses collection_traits.
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
-        begin( C& c )
-        {
-            return collection_traits<C>::function_type::begin( c ); 
-        }
-
-        //! Free-standing begin() function
-        /*!
-            \overload
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
-        begin( const C& c )
-        {
-            return collection_traits<C>::function_type::begin( c ); 
-        }
-
-        //! Free-standing end() function
-        /*!
-            Get the begin iterator of the container. Uses collection_traits.
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
-        end( C& c )
-        {
-            return collection_traits<C>::function_type::end( c );
-        }
-
-        //! Free-standing end() function
-        /*!
-            \overload           
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
-        end( const C& c )
-        {
-            return collection_traits<C>::function_type::end( c );
-        }
-
-#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        //! Free-standing begin() function
-        /*!
-            \overload
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
-        begin( C& c )
-        {
-            return collection_traits<C>::function_type::begin( c );
-        }
-
-        //! Free-standing end() function
-        /*!
-            \overload
-        */
-        template< typename C >
-        inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
-        end( C& c )
-        {
-            return collection_traits<C>::function_type::end( c );
-        }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-    } // namespace algorithm
-} // namespace boost
-
-#endif // BOOST_STRING_COLLECTION_TRAITS_HPP
diff --git a/src/boost/range/detail/collection_traits_detail.hpp b/src/boost/range/detail/collection_traits_detail.hpp
deleted file mode 100644
index 44fbde0..0000000
--- a/src/boost/range/detail/collection_traits_detail.hpp
+++ /dev/null
@@ -1,621 +0,0 @@
-//  Boost string_algo library collection_traits.hpp header file  -----------------------//
-
-//  Copyright Pavol Droba 2002-2003. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-
-//  See http://www.boost.org for updates, documentation, and revision history.
-
-#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
-#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
-
-#include <boost/algorithm/string/config.hpp>
-#include <cstddef>
-#include <string>
-#include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/type_traits/remove_pointer.hpp>
-#include <boost/type_traits/remove_cv.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/mpl/vector.hpp>
-#include <boost/mpl/fold.hpp>
-#include <boost/detail/iterator.hpp>
-#include <boost/algorithm/string/yes_no_type.hpp>
-
-// Container traits implementation ---------------------------------------------------------
-
-namespace boost {
-    namespace algorithm {
-        namespace detail {
-
-// Default collection traits -----------------------------------------------------------------
-
-            // Default collection helper 
-            /*
-                Wraps std::container compliant containers
-            */
-            template< typename ContainerT >     
-            struct default_container_traits
-            {
-                typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type;
-                typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator;
-                typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator;
-                typedef BOOST_STRING_TYPENAME 
-                    ::boost::mpl::if_< ::boost::is_const<ContainerT>,
-                        const_iterator,
-                        iterator 
-                    >::type result_iterator;
-                typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type;
-                typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type;
-                
-                // static operations
-                template< typename C >
-                static size_type size( const C& c )
-                {
-                    return c.size();
-                }
-
-                template< typename C >
-                static bool empty( const C& c )
-                {
-                    return c.empty();
-                }
-
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename C >
-                static iterator begin( C& c )
-                {
-                    return c.begin();
-                }
-
-                template< typename C >
-                static const_iterator begin( const C& c )
-                {
-                    return c.begin();
-                }
-
-                template< typename C >
-                static iterator end( C& c )
-                {
-                    return c.end();
-                }
-
-                template< typename C >
-                static const_iterator end( const C& c )
-                {
-                    return c.end();
-                }
-
-#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename C >
-                static result_iterator begin( C& c )
-                {
-                    return c.begin();
-                }
-
-                template< typename C >
-                static result_iterator end( C& c )
-                {
-                    return c.end();
-                }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
-
-            }; 
-
-            template<typename T>
-            struct default_container_traits_selector
-            {
-                typedef default_container_traits<T> type;
-            };
-
-// Pair container traits ---------------------------------------------------------------------
-                    
-            // pair selector
-            template< typename T, typename U >
-            yes_type is_pair_impl( const std::pair<T,U>* );
-            no_type is_pair_impl( ... );
-
-            template<typename T> struct is_pair
-            {
-            private:
-                static T* t;
-            public:
-                BOOST_STATIC_CONSTANT( bool, value=
-                    sizeof(is_pair_impl(t))==sizeof(yes_type) );
-            };
-
-            // pair helper
-            template< typename PairT >
-            struct pair_container_traits
-            {
-                typedef BOOST_STRING_TYPENAME PairT::first_type element_type;
-
-                typedef BOOST_STRING_TYPENAME ::boost::detail::
-                    iterator_traits<element_type>::value_type value_type;
-                typedef std::size_t size_type;
-                typedef BOOST_STRING_TYPENAME ::boost::detail::
-                    iterator_traits<element_type>::difference_type difference_type;
-
-                typedef element_type iterator;
-                typedef element_type const_iterator;
-                typedef element_type result_iterator;
-
-                // static operations
-                template< typename P >
-                static size_type size( const P& p )
-                {
-                    difference_type diff = std::distance( p.first, p.second );
-                    if ( diff < 0 ) 
-                        return 0;
-                    else
-                        return diff;
-                }
-
-                template< typename P >
-                static bool empty( const P& p )
-                {
-                    return p.first==p.second;
-                }
-
-                template< typename P > 
-                static const_iterator begin( const P& p )
-                {
-                    return p.first;
-                }
-
-                template< typename P >
-                static const_iterator end( const P& p )
-                {
-                    return p.second;
-                }
-            }; // 'pair_container_helper'
-
-            template<typename T>
-            struct pair_container_traits_selector
-            {
-                typedef pair_container_traits<T> type;
-            };
-
-// Array container traits ---------------------------------------------------------------
-
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-            // array traits ( partial specialization )
-            template< typename T >
-            struct array_traits;
-
-            template< typename T, std::size_t sz >
-            struct array_traits<T[sz]>
-            {
-                // typedef
-                typedef T* iterator;
-                typedef const T* const_iterator;
-                typedef T value_type;
-                typedef std::size_t size_type;
-                typedef std::ptrdiff_t difference_type;
-
-                // size of the array ( static );
-                BOOST_STATIC_CONSTANT( size_type, array_size = sz );
-            };
-
-#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-            // array traits ( no partial specialization )
-            /*
-                without parial specialization we are able to
-                provide support only for a limited number of
-                types. Currently the primitive numeric types 
-                are supported
-            */
-            template< typename T, typename BaseT >
-            struct array_traits_impl
-            {
-                typedef BaseT value_type;
-                typedef BaseT* iterator;
-                typedef const BaseT* const_iterator;
-                typedef std::size_t size_type;
-                typedef std::ptrdiff_t difference_type;
-
-                // size of the array
-                BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) );
-            };
-            
-            template< typename T, typename BaseT >
-            struct array_traits_impl_selector
-            {
-                typedef array_traits_impl<T,BaseT> type;
-            };
-
-            struct array_traits_void
-            {
-                typedef void type;
-            };
-
-            template< typename T, typename BaseT >
-            struct array_traits_cv_selector
-            {
-                typedef BOOST_STRING_TYPENAME 
-                    ::boost::mpl::eval_if< 
-                        ::boost::is_convertible<T,BaseT*>,
-                        array_traits_impl_selector<T,BaseT>,
-                        ::boost::mpl::eval_if< 
-                            ::boost::is_convertible<T,const BaseT*>,
-                                array_traits_impl_selector<T, const BaseT>,
-                                ::boost::mpl::eval_if< 
-                                    ::boost::is_convertible<T, volatile BaseT*>,
-                                    array_traits_impl_selector<T, volatile BaseT>,
-                                    array_traits_impl_selector<T, const volatile BaseT>
-                                >
-                            >
-                    >::type type;
-            };
-
-            template< typename T >
-            struct array_traits_select
-            {
-                template< typename T1, typename T2 >
-                struct apply
-                {
-                    typedef BOOST_STRING_TYPENAME
-                        ::boost::mpl::eval_if< 
-                            ::boost::is_convertible<T,const volatile T2*>,
-                            array_traits_cv_selector<T,T2>,
-                            ::boost::mpl::identity<T1> >::type type;
-                };
-            };
-
-            template< typename T >
-            struct array_traits_selector 
-            {
-            private:
-                // supported array base types
-#ifndef BOOST_NO_INTRINSIC_WCHAR_T
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::mpl::vector10<
-                        wchar_t,
-#else // BOOST_NO_INTRINSIC_WCHAR_T
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::mpl::vector9<
-#endif // BOOST_NO_INTRINSIC_WCHAR_T
-                        char,
-                        signed char,
-                        unsigned char,
-                        signed short,
-                        unsigned short,
-                        signed int,
-                        unsigned int,
-                        signed long,
-                        unsigned long
-                >::type array_base_types;
-
-            public:
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::mpl::fold<
-                        array_base_types,
-                        ::boost::algorithm::detail::array_traits_void,
-                        ::boost::algorithm::detail::array_traits_select<T> >::type type;
-            };
-
-            template< typename T >
-            struct array_traits
-            {
-                typedef BOOST_STRING_TYPENAME
-                    array_traits_selector<T>::type traits_type;
-
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::value_type value_type;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::iterator iterator;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::const_iterator const_iterator;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::size_type size_type;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::difference_type difference_type;
-
-                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
-            };
-
-#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-            
-            // array lenght resolving
-            /*
-                Lenght of string contained in a static array could
-                be different from the size of the array.
-                For string processing we need the lenght without
-                terminating 0.
-
-                Therefore, the lenght is calulated for char and wchar_t
-                using char_traits, rather then simply returning
-                the array size.
-            */
-            template< typename T >
-            struct array_length_selector
-            {
-                template< typename TraitsT >
-                struct array_length
-                {
-                    typedef BOOST_STRING_TYPENAME 
-                        TraitsT::size_type size_type;
-
-                    BOOST_STATIC_CONSTANT(
-                        size_type,
-                        array_size=TraitsT::array_size );
-
-                    template< typename A >
-                    static size_type length( const A& )
-                    {
-                        return array_size;
-                    }
-
-                    template< typename A >
-                    static bool empty( const A& )
-                    {
-                        return array_size==0;
-                    }
-                };
-            };
-
-            // specialization for char
-            template<>
-            struct array_length_selector<char>
-            {
-                template< typename TraitsT >
-                struct array_length
-                {
-                    typedef BOOST_STRING_TYPENAME 
-                        TraitsT::size_type size_type;
-
-                    template< typename A >
-                    static size_type length( const A& a )
-                    {
-                        if ( a==0 ) 
-                            return 0;
-                        else
-                            return std::char_traits<char>::length(a);
-                    }
-                    
-                    template< typename A >
-                    static bool empty( const A& a )
-                    {
-                        return a==0 || a[0]==0;
-                    }
-                };
-            };
-
-            // specialization for wchar_t
-            template<>
-            struct array_length_selector<wchar_t>
-            {
-                template< typename TraitsT >
-                struct array_length
-                {
-                    typedef BOOST_STRING_TYPENAME 
-                        TraitsT::size_type size_type;
-
-                    template< typename A >
-                    static size_type length( const A& a )
-                    {
-                        if ( a==0 ) 
-                            return 0;
-                        else
-                            return std::char_traits<wchar_t>::length(a);
-                    }
-
-                    template< typename A >
-                    static bool empty( const A& a )
-                    {
-                        return a==0 || a[0]==0;
-                    }
-                };
-            };
-
-            template< typename T >
-            struct array_container_traits
-            {
-            private:
-                // resolve array traits
-                typedef array_traits<T> traits_type;
-
-            public:
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::value_type value_type;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::iterator iterator;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::const_iterator const_iterator;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::size_type size_type;
-                typedef BOOST_STRING_TYPENAME
-                    traits_type::difference_type difference_type;
-
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::mpl::if_< ::boost::is_const<T>,
-                        const_iterator,
-                        iterator 
-                    >::type result_iterator;
-                
-            private:
-                // resolve array size
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::remove_cv<value_type>::type char_type;
-                typedef BOOST_STRING_TYPENAME
-                    array_length_selector<char_type>::
-                        BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
-
-            public:
-                BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
-
-                // static operations
-                template< typename A >
-                static size_type size( const A& a )
-                {
-                    return array_length_type::length(a);
-                }
-
-                template< typename A >
-                static bool empty( const A& a )
-                {
-                    return array_length_type::empty(a);
-                }
-                
-
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename A >
-                static iterator begin( A& a )
-                {
-                    return a;
-                }
-
-                template< typename A >
-                static const_iterator begin( const A& a )
-                {
-                    return a;
-                }
-
-                template< typename A >
-                static iterator end( A& a )
-                {
-                    return a+array_length_type::length(a);
-                }
-
-                template< typename A >
-                static const_iterator end( const A& a )
-                {
-                    return a+array_length_type::length(a);
-                }
-
-#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename A >
-                static result_iterator begin( A& a )
-                {
-                    return a;
-                }
-
-                template< typename A >
-                static result_iterator end( A& a )
-                {
-                    return a+array_length_type::length(a);
-                }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
-
-            }; 
-
-            template<typename T>
-            struct array_container_traits_selector
-            {
-                typedef array_container_traits<T> type;
-            };
-
-// Pointer container traits ---------------------------------------------------------------
-
-            template<typename T>
-            struct pointer_container_traits
-            {
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::remove_pointer<T>::type value_type;
-
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::remove_cv<value_type>::type char_type;
-                typedef ::std::char_traits<char_type> char_traits;
-
-                typedef value_type* iterator;
-                typedef const value_type* const_iterator;
-                typedef std::ptrdiff_t difference_type;
-                typedef std::size_t size_type;
-
-                typedef BOOST_STRING_TYPENAME
-                    ::boost::mpl::if_< ::boost::is_const<T>,
-                        const_iterator,
-                        iterator 
-                    >::type result_iterator;
-
-                // static operations
-                template< typename P >
-                static size_type size( const P& p )
-                {
-                    if ( p==0 ) 
-                        return 0;
-                    else
-                        return char_traits::length(p);
-                }
-
-                template< typename P >
-                static bool empty( const P& p )
-                {
-                    return p==0 || p[0]==0;
-                }
-
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename P >
-                static iterator begin( P& p )
-                {
-                    return p;
-                }
-
-                template< typename P >
-                static const_iterator begin( const P& p )
-                {
-                    return p;
-                }
-
-                template< typename P >
-                static iterator end( P& p )
-                {
-                    if ( p==0 )
-                        return p;
-                    else
-                        return p+char_traits::length(p);
-                }
-
-                template< typename P >
-                static const_iterator end( const P& p )
-                {
-                    if ( p==0 )
-                        return p;
-                    else
-                        return p+char_traits::length(p);
-                }
-
-#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-                template< typename P >
-                static result_iterator begin( P& p )
-                {
-                    return p;
-                }
-
-                template< typename P >
-                static result_iterator end( P& p )
-                {
-                    if ( p==0 )
-                        return p;
-                    else
-                        return p+char_traits::length(p);
-                }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING    
-            }; 
-
-            template<typename T>
-            struct pointer_container_traits_selector
-            {
-                typedef pointer_container_traits<T> type;
-            };
-
-        } // namespace detail
-    } // namespace algorithm
-} // namespace boost
-
-
-#endif  // BOOST_STRING_DETAIL_COLLECTION_HPP
diff --git a/src/boost/range/detail/common.hpp b/src/boost/range/detail/common.hpp
deleted file mode 100644
index f7539f5..0000000
--- a/src/boost/range/detail/common.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_COMMON_HPP
-#define BOOST_RANGE_DETAIL_COMMON_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/detail/sfinae.hpp>
-#include <boost/type_traits/is_void.hpp>
-#include <boost/type_traits/detail/ice_or.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/int.hpp>
-#include <cstddef>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost 
-{
-    namespace range_detail 
-    {        
-        // 1 = std containers
-        // 2 = std::pair
-        // 3 = const std::pair
-        // 4 = array
-        // 5 = const array
-        // 6 = char array
-        // 7 = wchar_t array
-        // 8 = char*
-        // 9 = const char*
-        // 10 = whar_t*
-        // 11 = const wchar_t*
-        // 12 = string
-        
-        typedef mpl::int_<1>::type    std_container_;
-        typedef mpl::int_<2>::type    std_pair_;
-        typedef mpl::int_<3>::type    const_std_pair_;
-        typedef mpl::int_<4>::type    array_;
-        typedef mpl::int_<5>::type    const_array_;
-        typedef mpl::int_<6>::type    char_array_;
-        typedef mpl::int_<7>::type    wchar_t_array_;
-        typedef mpl::int_<8>::type    char_ptr_;
-        typedef mpl::int_<9>::type    const_char_ptr_;
-        typedef mpl::int_<10>::type   wchar_t_ptr_;
-        typedef mpl::int_<11>::type   const_wchar_t_ptr_;
-        typedef mpl::int_<12>::type   string_;
-        
-        template< typename C >
-        struct range_helper
-        {
-            static C* c;
-            static C  ptr;
-
-            BOOST_STATIC_CONSTANT( bool, is_pair_                = sizeof( boost::range_detail::is_pair_impl( c ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_char_ptr_            = sizeof( boost::range_detail::is_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_const_char_ptr_      = sizeof( boost::range_detail::is_const_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_wchar_t_ptr_         = sizeof( boost::range_detail::is_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_   = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_char_array_          = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_       = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
-            BOOST_STATIC_CONSTANT( bool, is_string_              = (boost::type_traits::ice_or<is_const_char_ptr_, is_const_wchar_t_ptr_>::value ));
-            BOOST_STATIC_CONSTANT( bool, is_array_               = boost::is_array<C>::value );
-            
-        };
-        
-        template< typename C >
-        class range
-        {
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_pair_,
-                                                                  boost::range_detail::std_pair_,
-                                                                  void >::type pair_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_array_,
-                                                                    boost::range_detail::array_,
-                                                                    pair_t >::type array_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_string_,
-                                                                    boost::range_detail::string_,
-                                                                    array_t >::type string_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_char_ptr_,
-                                                                    boost::range_detail::const_char_ptr_,
-                                                                    string_t >::type const_char_ptr_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_ptr_,
-                                                                    boost::range_detail::char_ptr_,
-                                                                    const_char_ptr_t >::type char_ptr_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_wchar_t_ptr_,
-                                                                    boost::range_detail::const_wchar_t_ptr_,
-                                                                    char_ptr_t >::type const_wchar_ptr_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_ptr_,
-                                                                    boost::range_detail::wchar_t_ptr_,
-                                                                    const_wchar_ptr_t >::type wchar_ptr_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_array_,
-                                                                    boost::range_detail::wchar_t_array_,
-                                                                    wchar_ptr_t >::type wchar_array_t;
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_array_,
-                                                                    boost::range_detail::char_array_,
-                                                                    wchar_array_t >::type char_array_t;
-        public:
-            typedef BOOST_RANGE_DEDUCED_TYPENAME   boost::mpl::if_c< ::boost::is_void<char_array_t>::value,
-                                                                    boost::range_detail::std_container_,
-                                                                    char_array_t >::type type;  
-        }; // class 'range' 
-    }
-}
-        
-#endif
-
diff --git a/src/boost/range/detail/const_iterator.hpp b/src/boost/range/detail/const_iterator.hpp
deleted file mode 100644
index e5cb34a..0000000
--- a/src/boost/range/detail/const_iterator.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_CONST_ITERATOR_HPP
-#define BOOST_RANGE_DETAIL_CONST_ITERATOR_HPP
-
-#include <boost/range/detail/common.hpp>
-#include <boost/range/detail/remove_extent.hpp>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost 
-{
-    namespace range_detail 
-    {      
-        template< typename T >
-        struct range_const_iterator_;
-
-        template<>
-        struct range_const_iterator_<std_container_>
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME C::const_iterator type;
-            };
-        };
-
-        template<>
-        struct range_const_iterator_<std_pair_>
-        {
-            template< typename P >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME P::first_type type;
-            };
-        };
-
-
-        template<>
-        struct range_const_iterator_<array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                typedef const BOOST_RANGE_DEDUCED_TYPENAME 
-                    remove_extent<T>::type* type;
-            };
-        };
-    } 
-    
-    template< typename C >
-    class range_const_iterator
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
-    public:
-        typedef BOOST_DEDUCED_TYPENAME range_detail::range_const_iterator_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
-    };
-
-}
-
-#endif
diff --git a/src/boost/range/detail/demote_iterator_traversal_tag.hpp b/src/boost/range/detail/demote_iterator_traversal_tag.hpp
deleted file mode 100644
index 2127de9..0000000
--- a/src/boost/range/detail/demote_iterator_traversal_tag.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// Acknowledgements:
-// aschoedl supplied a fix to supply the level of interoperability I had
-// originally intended, but failed to implement.
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
-
-#include <boost/iterator/iterator_categories.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-template<class IteratorTraversalTag1, class IteratorTraversalTag2>
-struct inner_demote_iterator_traversal_tag
-{
-};
-
-#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \
-template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \
-{ \
-    typedef ResultTag type; \
-};
-
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, no_traversal_tag,            no_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, incrementable_traversal_tag, no_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, single_pass_traversal_tag,   no_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, forward_traversal_tag,       no_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, bidirectional_traversal_tag, no_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, random_access_traversal_tag, no_traversal_tag )
-
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, no_traversal_tag,            no_traversal_tag            )
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, single_pass_traversal_tag,   incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, forward_traversal_tag,       incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, bidirectional_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, random_access_traversal_tag, incrementable_traversal_tag )
-
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, no_traversal_tag,            no_traversal_tag            )
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, forward_traversal_tag,       single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, bidirectional_traversal_tag, single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, random_access_traversal_tag, single_pass_traversal_tag   )
-
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, no_traversal_tag,            no_traversal_tag            )
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, bidirectional_traversal_tag, forward_traversal_tag       )
-BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, random_access_traversal_tag, forward_traversal_tag       )
-
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, no_traversal_tag,            no_traversal_tag            )
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, random_access_traversal_tag, bidirectional_traversal_tag )
-
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, no_traversal_tag,            no_traversal_tag            )
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, single_pass_traversal_tag,   single_pass_traversal_tag   )
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, forward_traversal_tag,       forward_traversal_tag       )
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
-BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal_tag, random_access_traversal_tag )
-
-#undef BOOST_DEMOTE_TRAVERSAL_TAG
-
-template<class IteratorTraversalTag1, class IteratorTraversalTag2>
-struct demote_iterator_traversal_tag
-    : inner_demote_iterator_traversal_tag<
-        typename boost::detail::pure_traversal_tag< IteratorTraversalTag1 >::type,
-        typename boost::detail::pure_traversal_tag< IteratorTraversalTag2 >::type
-      >
-{
-};
-
-    } // namespace range_detail
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/detail_str.hpp b/src/boost/range/detail/detail_str.hpp
deleted file mode 100644
index 5ef7a34..0000000
--- a/src/boost/range/detail/detail_str.hpp
+++ /dev/null
@@ -1,376 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_DETAIL_STR_HPP
-#define BOOST_RANGE_DETAIL_DETAIL_STR_HPP
-
-#include <boost/config.hpp> // BOOST_MSVC
-#include <boost/range/iterator.hpp>
-
-namespace boost 
-{
-    
-    namespace range_detail
-    {
-        //
-        // iterator
-        //
-        
-        template<>
-        struct range_iterator_<char_array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                 typedef BOOST_RANGE_DEDUCED_TYPENAME 
-                    remove_extent<T>::type* type;
-            };
-        };
-
-        template<>
-        struct range_iterator_<char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef char* type; 
-            };         
-        };
-
-        template<>
-        struct range_iterator_<const_char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef const char* type;
-            };         
-        };
-
-        template<>
-        struct range_iterator_<wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef wchar_t* type; 
-            };         
-        };
-
-        template<>
-        struct range_iterator_<const_wchar_t_ptr_>
-        {
-             template< typename S >
-             struct pts
-             {
-                 typedef const wchar_t* type; 
-             };         
-        };
-
-
-        //
-        // const iterator
-        //
-
-        template<>
-        struct range_const_iterator_<char_array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                typedef const BOOST_RANGE_DEDUCED_TYPENAME 
-                    remove_extent<T>::type* type;
-            };
-        };
-
-        template<>
-        struct range_const_iterator_<char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef const char* type; 
-            };         
-        };
-
-        template<>
-        struct range_const_iterator_<const_char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef const char* type; 
-            };         
-        };
-
-        template<>
-        struct range_const_iterator_<wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef const wchar_t* type; 
-            };         
-        };
-
-        template<>
-        struct range_const_iterator_<const_wchar_t_ptr_>
-        {
-             template< typename S >
-             struct pts
-             {
-                 typedef const wchar_t* type; 
-             };         
-        };
-    }
-}
-
-#include <boost/range/detail/begin.hpp>
-#include <boost/range/detail/end.hpp>
-#include <boost/range/detail/size_type.hpp>
-#include <boost/range/detail/value_type.hpp>
-#include <boost/range/detail/common.hpp>
-
-namespace boost 
-{
-    
-    namespace range_detail
-    {
-        //
-        // str_begin()
-        //
-        template<>
-        struct range_begin<char_ptr_>
-        {
-            static char* fun( char* s )
-            {
-                return s;
-            }
-        };
-
-        template<>
-        struct range_begin<const_char_ptr_>
-        {
-            static const char* fun( const char* s )
-            {
-                return s;
-            }
-        };
-        
-        template<>
-        struct range_begin<wchar_t_ptr_>
-        {
-            
-            static wchar_t* fun( wchar_t* s )
-            {
-                return s;
-            }
-        };
-
-        template<>
-        struct range_begin<const_wchar_t_ptr_>
-        {
-            static const wchar_t* fun( const wchar_t* s )
-            {
-                return s;
-            }
-        };
-        
-        template< typename C >
-        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type 
-        str_begin( C& c )
-        {
-            return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME 
-                range_detail::range<C>::type >::fun( c );
-        }
-
-        //
-        // str_end()
-        //
-
-        template<>
-        struct range_end<char_array_>
-        {
-            template< typename T, std::size_t sz >
-            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost::range_detail::array_end( boost_range_array );
-            }
-        };
-        
-        template<>
-        struct range_end<wchar_t_array_>
-        {
-            template< typename T, std::size_t sz >
-            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost::range_detail::array_end( boost_range_array );
-            }
-        };
-        
-        template<>
-        struct range_end<char_ptr_>
-        {
-            static char* fun( char* s )
-            {
-                return boost::range_detail::str_end( s );
-            }
-        };
-
-        template<>
-        struct range_end<const_char_ptr_>
-        {
-            static const char* fun( const char* s )
-            {
-                return boost::range_detail::str_end( s );
-            }
-        };
-
-        template<>
-        struct range_end<wchar_t_ptr_>
-        {
-            static wchar_t* fun( wchar_t* s )
-            {
-                return boost::range_detail::str_end( s );
-            }
-        };
-
-
-        template<>
-        struct range_end<const_wchar_t_ptr_>
-        {
-            static const wchar_t* fun( const wchar_t* s )
-            {
-                return boost::range_detail::str_end( s );
-            }
-        };
-
-        template< typename C >
-        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type 
-        str_end( C& c )
-        {
-            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME 
-                range_detail::range<C>::type >::fun( c );
-        }
-
-        //
-        // size_type
-        //
-
-        template<>
-        struct range_size_type_<char_array_>
-        { 
-            template< typename A >
-            struct pts
-            {
-                typedef std::size_t type;
-            };
-        };
-
-        template<>
-        struct range_size_type_<char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::size_t type;
-            };         
-        };
-        
-        template<>
-        struct range_size_type_<const_char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::size_t type;
-            };         
-        };
-        
-        template<>
-        struct range_size_type_<wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::size_t type;
-            };         
-        };
-        
-        template<>
-        struct range_size_type_<const_wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::size_t type;
-            };         
-        };  
-
-        //
-        // value_type
-        //
-        
-        template<>
-        struct range_value_type_<char_array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                typedef char type;
-            };
-        };
-
-        template<>
-        struct range_value_type_<char_ptr_>
-        {
-             template< typename S >
-             struct pts
-             {
-                 typedef char type; 
-             };         
-        };
-        
-        template<>
-        struct range_value_type_<const_char_ptr_>
-        {
-             template< typename S >
-             struct pts
-             {
-                 typedef const char type;
-             };         
-        };
-        
-        template<>
-        struct range_value_type_<wchar_t_ptr_>
-        {
-             template< typename S >
-             struct pts
-             {
-                 typedef wchar_t type;
-             };         
-        };
-        
-        template<>
-        struct range_value_type_<const_wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef const wchar_t type;
-            };         
-        };
-
-    } // namespace 'range_detail'
-
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/difference_type.hpp b/src/boost/range/detail/difference_type.hpp
deleted file mode 100644
index c641516..0000000
--- a/src/boost/range/detail/difference_type.hpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
-#define BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
-
-#include <boost/range/detail/common.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost 
-{
-    namespace range_detail 
-    {        
-        template< typename T >
-        struct range_difference_type_;
-
-        template<>
-        struct range_difference_type_<std_container_>
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
-            };
-        };
-
-        template<>
-        struct range_difference_type_<std_pair_>
-        {
-            template< typename P >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;                
-            };
-        };
-
-        template<>
-        struct range_difference_type_<array_>
-        {
-            template< typename A >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };
-        };
-
-        template<>
-        struct range_difference_type_<char_array_>
-        { 
-            template< typename A >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };
-        };
-
-        template<>
-        struct range_difference_type_<char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };         
-        };
-        
-        template<>
-        struct range_difference_type_<const_char_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };         
-        };
-        
-        template<>
-        struct range_difference_type_<wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };         
-        };
-        
-        template<>
-        struct range_difference_type_<const_wchar_t_ptr_>
-        {
-            template< typename S >
-            struct pts
-            {
-                typedef std::ptrdiff_t type;
-            };         
-        };
-        
-    } 
-    
-    template< typename C >
-    class range_difference
-    {
-        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
-    public:
-        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
-    };
-
-}
-
-#endif
-
diff --git a/src/boost/range/detail/empty.hpp b/src/boost/range/detail/empty.hpp
deleted file mode 100644
index b098705..0000000
--- a/src/boost/range/detail/empty.hpp
+++ /dev/null
@@ -1,120 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_EMPTY_HPP
-#define BOOST_RANGE_DETAIL_EMPTY_HPP
-
-#include <boost/range/detail/common.hpp>
-
-namespace boost 
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_empty;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_empty<std_container_>
-        {
-            template< typename C >
-            static bool fun( C& c )
-            {
-                return c.empty();
-            };
-        };
-                    
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_empty<std_pair_>
-        {
-            template< typename P >
-            static bool fun( const P& p )
-            {
-                return p.first == p.second;
-            }
-        };
- 
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_empty<array_>
-        {
-            template< typename T, std::size_t sz >
-            static bool fun( T BOOST_ARRAY_REF[sz] )
-            {
-                if( boost_range_array == 0 )
-                    return true;
-                return false;
-            }
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // string
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_empty<char_ptr_>
-        {
-            static bool fun( const char* s )
-            {
-                return s == 0 || s[0] == 0;
-            }
-        };
-
-        template<>
-        struct range_empty<const_char_ptr_>
-        {
-            static bool fun( const char* s )
-            {
-                return  s == 0 || s[0] == 0;
-            }
-        };
-
-        template<>
-        struct range_empty<wchar_t_ptr_>
-        {
-            static bool fun( const wchar_t* s )
-            {
-                return  s == 0 || s[0] == 0;
-            }
-        };
-        
-        template<>
-        struct range_empty<const_wchar_t_ptr_>
-        {
-            static bool fun( const wchar_t* s )
-            {
-                return  s == 0 || s[0] == 0;
-            }
-        };
-
-    } // namespace 'range_detail'
-    
-        
-    template< typename C >
-    inline bool 
-    empty( const C& c )
-    {
-        return range_detail::range_empty<  BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
-    }
-
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/end.hpp b/src/boost/range/detail/end.hpp
deleted file mode 100644
index 8b5f35d..0000000
--- a/src/boost/range/detail/end.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_END_HPP
-#define BOOST_RANGE_DETAIL_END_HPP
-
-#include <boost/config.hpp> // BOOST_MSVC
-#include <boost/detail/workaround.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# include <boost/range/detail/vc6/end.hpp>
-#else
-# include <boost/range/detail/implementation_help.hpp>
-# include <boost/range/iterator.hpp>
-# include <boost/range/detail/common.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, < 1310)
-#  include <boost/range/detail/remove_extent.hpp>
-# endif
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_end;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_end<std_container_>
-        {
-            template< typename C >
-            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
-            fun( C& c )
-            {
-                return c.end();
-            };
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_end<std_pair_>
-        {
-            template< typename P >
-            static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
-            fun( const P& p )
-            {
-                return p.second;
-            }
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_end<array_>
-        {
-        #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
-            template< typename T, std::size_t sz >
-            static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost::range_detail::array_end( boost_range_array );
-            }
-        #else
-            template<typename T>
-            static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t)
-            {
-                return t + remove_extent<T>::size;
-            }
-        #endif
-        };
-
-    } // namespace 'range_detail'
-
-    namespace range_adl_barrier
-    {
-        template< typename C >
-        inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
-        end( C& c )
-        {
-            return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
-        }
-    } // namespace range_adl_barrier
-
-} // namespace 'boost'
-
-# endif // VC6
-#endif
diff --git a/src/boost/range/detail/extract_optional_type.hpp b/src/boost/range/detail/extract_optional_type.hpp
deleted file mode 100644
index 8292e34..0000000
--- a/src/boost/range/detail/extract_optional_type.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Arno Schoedl & Neil Groves 2009.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/config.hpp>
-
-#ifdef BOOST_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-
-#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                         \
-    template< typename C >                                                     \
-    struct extract_ ## a_typedef                                               \
-    {                                                                          \
-        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                      \
-    };
-
-#else
-
-namespace boost {
-    namespace range_detail {
-        template< typename T > struct exists { typedef void type; };
-    }
-}
-
-// Defines extract_some_typedef<T> which exposes T::some_typedef as
-// extract_some_typedef<T>::type if T::some_typedef exists. Otherwise
-// extract_some_typedef<T> is empty.
-#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef )                         \
-    template< typename C, typename Enable=void >                               \
-    struct extract_ ## a_typedef                                               \
-    {};                                                                        \
-    template< typename C >                                                     \
-    struct extract_ ## a_typedef< C                                            \
-    , BOOST_DEDUCED_TYPENAME boost::range_detail::exists< BOOST_DEDUCED_TYPENAME C::a_typedef >::type \
-    > {                                                                        \
-        typedef BOOST_DEDUCED_TYPENAME C::a_typedef type;                      \
-    };
-
-#endif
-
-#endif // include guard
diff --git a/src/boost/range/detail/implementation_help.hpp b/src/boost/range/detail/implementation_help.hpp
deleted file mode 100644
index 1f7d163..0000000
--- a/src/boost/range/detail/implementation_help.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
-#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
-
-#include <boost/range/config.hpp>
-#include <boost/range/detail/common.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <cstddef>
-#include <string.h>
-
-#ifndef BOOST_NO_CWCHAR
-#include <wchar.h>
-#endif
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template <typename T>
-        inline void boost_range_silence_warning( const T& ) { }
-
-        /////////////////////////////////////////////////////////////////////
-        // end() help
-        /////////////////////////////////////////////////////////////////////
-
-        inline const char* str_end( const char* s, const char* )
-        {
-            return s + strlen( s );
-        }
-
-#ifndef BOOST_NO_CWCHAR
-        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
-        {
-            return s + wcslen( s );
-        }
-#else
-        inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
-        {
-            if( s == 0 || s[0] == 0 )
-                return s;
-            while( *++s != 0 )
-                ;
-            return s;
-        }
-#endif
-
-        template< class Char >
-        inline Char* str_end( Char* s )
-        {
-            return const_cast<Char*>( str_end( s, s ) );
-        }
-
-        template< class T, std::size_t sz >
-        inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] )
-        {
-            return boost_range_array + sz;
-        }
-
-        template< class T, std::size_t sz >
-        inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] )
-        {
-            return boost_range_array + sz;
-        }
-
-        /////////////////////////////////////////////////////////////////////
-        // size() help
-        /////////////////////////////////////////////////////////////////////
-
-        template< class Char >
-        inline std::size_t str_size( const Char* const& s )
-        {
-            return str_end( s ) - s;
-        }
-
-        template< class T, std::size_t sz >
-        inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
-        {
-            boost_range_silence_warning( boost_range_array );
-            return sz;
-        }
-
-        template< class T, std::size_t sz >
-        inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
-        {
-            boost_range_silence_warning( boost_range_array );
-            return sz;
-        }
-
-    } // namespace 'range_detail'
-
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/iterator.hpp b/src/boost/range/detail/iterator.hpp
deleted file mode 100644
index 58346d4..0000000
--- a/src/boost/range/detail/iterator.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_ITERATOR_HPP
-#define BOOST_RANGE_DETAIL_ITERATOR_HPP
-
-#include <boost/range/detail/common.hpp>
-#include <boost/range/detail/remove_extent.hpp>
-
-#include <boost/static_assert.hpp>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost 
-{
-    namespace range_detail 
-    {        
-        template< typename T >
-        struct range_iterator_ {
-            template< typename C >
-            struct pts
-            {
-                typedef int type;
-            };
-        };
-
-        template<>
-        struct range_iterator_<std_container_>
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME C::iterator type;
-            };
-        };
-
-        template<>
-        struct range_iterator_<std_pair_>
-        {
-            template< typename P >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME P::first_type type;
-            };
-        };
-
-        template<>
-        struct range_iterator_<array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME 
-                    remove_extent<T>::type* type;
-            };
-        };
-        
-    } 
-
-    template< typename C >
-    class range_mutable_iterator
-    {
-        typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
-    public:
-        typedef typename range_detail::range_iterator_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
-    };
-}
-
-#endif
diff --git a/src/boost/range/detail/join_iterator.hpp b/src/boost/range/detail/join_iterator.hpp
deleted file mode 100644
index bbdeec7..0000000
--- a/src/boost/range/detail/join_iterator.hpp
+++ /dev/null
@@ -1,344 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// Acknowledgements:
-// aschoedl contributed an improvement to the determination
-// of the Reference type parameter.
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
-
-#include <iterator>
-#include <boost/assert.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/empty.hpp>
-#include <boost/range/detail/demote_iterator_traversal_tag.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/next_prior.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-template<typename Iterator1, typename Iterator2>
-struct join_iterator_link
-{
-public:
-    join_iterator_link(Iterator1 last1, Iterator2 first2)
-        :    last1(last1)
-        ,    first2(first2)
-    {
-    }
-
-    Iterator1 last1;
-    Iterator2 first2;
-
-private:
-    join_iterator_link() /* = delete */ ;
-};
-
-class join_iterator_begin_tag {};
-class join_iterator_end_tag {};
-
-template<typename Iterator1
-       , typename Iterator2
-       , typename Reference
->
-class join_iterator_union
-{
-public:
-    typedef Iterator1 iterator1_t;
-    typedef Iterator2 iterator2_t;
-
-    join_iterator_union() {}
-    join_iterator_union(unsigned int /*selected*/, const iterator1_t& it1, const iterator2_t& it2) : m_it1(it1), m_it2(it2) {}
-
-    iterator1_t& it1() { return m_it1; }
-    const iterator1_t& it1() const { return m_it1; }
-
-    iterator2_t& it2() { return m_it2; }
-    const iterator2_t& it2() const { return m_it2; }
-
-    Reference dereference(unsigned int selected) const
-    {
-        return selected ? *m_it2 : *m_it1;
-    }
-
-    bool equal(const join_iterator_union& other, unsigned int selected) const
-    {
-        return selected
-            ? m_it2 == other.m_it2
-            : m_it1 == other.m_it1;
-    }
-
-private:
-    iterator1_t m_it1;
-    iterator2_t m_it2;
-};
-
-template<class Iterator, class Reference>
-class join_iterator_union<Iterator, Iterator, Reference>
-{
-public:
-    typedef Iterator iterator1_t;
-    typedef Iterator iterator2_t;
-
-    join_iterator_union() {}
-
-    join_iterator_union(unsigned int selected, const iterator1_t& it1, const iterator2_t& it2)
-        : m_it(selected ? it2 : it1)
-    {
-    }
-
-    iterator1_t& it1() { return m_it; }
-    const iterator1_t& it1() const { return m_it; }
-
-    iterator2_t& it2() { return m_it; }
-    const iterator2_t& it2() const { return m_it; }
-
-    Reference dereference(unsigned int) const
-    {
-        return *m_it;
-    }
-
-    bool equal(const join_iterator_union& other, unsigned int selected) const
-    {
-        return m_it == other.m_it;
-    }
-
-private:
-    iterator1_t m_it;
-};
-
-template<typename Iterator1
-       , typename Iterator2
-       , typename ValueType = typename iterator_value<Iterator1>::type
-       // find least demanding, commonly supported reference type, in the order &, const&, and by-value:
-       , typename Reference = typename mpl::if_c<
-                !is_reference<typename iterator_reference<Iterator1>::type>::value
-             || !is_reference<typename iterator_reference<Iterator2>::type>::value,
-                        typename remove_const<
-                            typename remove_reference<
-                                typename iterator_reference<Iterator1>::type
-                            >::type
-                        >::type,
-                        typename mpl::if_c<
-                            is_const<
-                                typename remove_reference<
-                                    typename iterator_reference<Iterator1>::type
-                                >::type
-                            >::value
-                            || is_const<
-                                typename remove_reference<
-                                    typename iterator_reference<Iterator2>::type
-                                >::type
-                            >::value,
-                            typename add_const<
-                                typename iterator_reference<Iterator2>::type
-                            >::type,
-                            typename iterator_reference<Iterator1>::type
-                        >::type
-                    >::type
-       , typename Traversal = typename demote_iterator_traversal_tag<
-                                  typename iterator_traversal<Iterator1>::type
-                                , typename iterator_traversal<Iterator2>::type>::type
->
-class join_iterator
-    : public iterator_facade<join_iterator<Iterator1,Iterator2,ValueType,Reference,Traversal>, ValueType, Traversal, Reference>
-{
-    typedef join_iterator_link<Iterator1, Iterator2> link_t;
-    typedef join_iterator_union<Iterator1, Iterator2, Reference> iterator_union;
-public:
-    typedef Iterator1 iterator1_t;
-    typedef Iterator2 iterator2_t;
-
-    join_iterator()
-        : m_section(0u)
-        , m_it(0u, iterator1_t(), iterator2_t())
-        , m_link(link_t(iterator1_t(), iterator2_t()))
-    {}
-
-    join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2)
-        : m_section(section)
-        , m_it(section, current1, current2)
-        , m_link(link_t(last1, first2))
-        {
-        }
-
-    template<typename Range1, typename Range2>
-    join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag)
-        : m_section(boost::empty(r1) ? 1u : 0u)
-        , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2))
-        , m_link(link_t(boost::end(r1), boost::begin(r2)))
-    {
-    }
-
-    template<typename Range1, typename Range2>
-    join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag)
-        : m_section(boost::empty(r1) ? 1u : 0u)
-        , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2))
-        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
-    {
-    }
-
-    template<typename Range1, typename Range2>
-    join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag)
-        : m_section(1u)
-        , m_it(1u, boost::end(r1), boost::end(r2))
-        , m_link(link_t(boost::end(r1), boost::begin(r2)))
-    {
-    }
-
-    template<typename Range1, typename Range2>
-    join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag)
-        : m_section(1u)
-        , m_it(1u, boost::const_end(r1), boost::const_end(r2))
-        , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
-    {
-    }
-
-private:
-    void increment()
-    {
-        if (m_section)
-            ++m_it.it2();
-        else
-        {
-            ++m_it.it1();
-            if (m_it.it1() == m_link.last1)
-            {
-                m_it.it2() = m_link.first2;
-                m_section = 1u;
-            }
-        }
-    }
-
-    void decrement()
-    {
-        if (m_section)
-        {
-            if (m_it.it2() == m_link.first2)
-            {
-                m_it.it1() = boost::prior(m_link.last1);
-                m_section = 0u;
-            }
-            else
-                --m_it.it2();
-        }
-        else
-            --m_it.it1();
-    }
-
-    typename join_iterator::reference dereference() const
-    {
-        return m_it.dereference(m_section);
-    }
-
-    bool equal(const join_iterator& other) const
-    {
-        return m_section == other.m_section
-            && m_it.equal(other.m_it, m_section);
-    }
-
-    void advance(typename join_iterator::difference_type offset)
-    {
-        if (m_section)
-            advance_from_range2(offset);
-        else
-            advance_from_range1(offset);
-    }
-
-    typename join_iterator::difference_type distance_to(const join_iterator& other) const
-    {
-        typename join_iterator::difference_type result;
-        if (m_section)
-        {
-            if (other.m_section)
-                result = other.m_it.it2() - m_it.it2();
-            else
-            {
-                result = (m_link.first2 - m_it.it2())
-                       + (other.m_it.it1() - m_link.last1);
-
-                BOOST_ASSERT( result <= 0 );
-            }
-        }
-        else
-        {
-            if (other.m_section)
-            {
-                result = (m_link.last1 - m_it.it1())
-                       + (other.m_it.it2() - m_link.first2);
-            }
-            else
-                result = other.m_it.it1() - m_it.it1();
-        }
-        return result;
-    }
-
-    void advance_from_range2(typename join_iterator::difference_type offset)
-    {
-        typedef typename join_iterator::difference_type difference_t;
-        BOOST_ASSERT( m_section == 1u );
-        if (offset < 0)
-        {
-            difference_t r2_dist = m_link.first2 - m_it.it2();
-            BOOST_ASSERT( r2_dist <= 0 );
-            if (offset >= r2_dist)
-                std::advance(m_it.it2(), offset);
-            else
-            {
-                difference_t r1_dist = offset - r2_dist;
-                BOOST_ASSERT( r1_dist <= 0 );
-                m_it.it1() = m_link.last1 + r1_dist;
-                m_section = 0u;
-            }
-        }
-        else
-            std::advance(m_it.it2(), offset);
-    }
-
-    void advance_from_range1(typename join_iterator::difference_type offset)
-    {
-        typedef typename join_iterator::difference_type difference_t;
-        BOOST_ASSERT( m_section == 0u );
-        if (offset > 0)
-        {
-            difference_t r1_dist = m_link.last1 - m_it.it1();
-            BOOST_ASSERT( r1_dist >= 0 );
-            if (offset < r1_dist)
-                std::advance(m_it.it1(), offset);
-            else
-            {
-                difference_t r2_dist = offset - r1_dist;
-                BOOST_ASSERT( r2_dist >= 0 );
-                m_it.it2() = m_link.first2 + r2_dist;
-                m_section = 1u;
-            }
-        }
-        else
-            std::advance(m_it.it1(), offset);
-    }
-
-    unsigned int m_section;
-    iterator_union m_it;
-    link_t m_link;
-
-    friend class ::boost::iterator_core_access;
-};
-
-    } // namespace range_detail
-
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/microsoft.hpp b/src/boost/range/detail/microsoft.hpp
deleted file mode 100644
index 7b672c9..0000000
--- a/src/boost/range/detail/microsoft.hpp
+++ /dev/null
@@ -1,931 +0,0 @@
-#ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP
-#define BOOST_RANGE_DETAIL_MICROSOFT_HPP
-
-// Boost.Range MFC/ATL Extension
-//
-// Copyright Shunsuke Sogame 2005-2006.
-// Distributed under the Boost Software License, Version 1.0. 
-// (See accompanying file LICENSE_1_0.txt or copy at 
-// http://www.boost.org/LICENSE_1_0.txt)
-
-
-
-
-// config
-//
-
-
-#include <boost/range/iterator.hpp>
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1
-
-
-#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
-#else
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin            range_begin
-    #define BOOST_RANGE_DETAIL_MICROSOFT_range_end              range_end
-#endif
-
-
-
-
-// yet another customization way
-//
-
-
-#include <boost/iterator/iterator_traits.hpp> // iterator_difference
-#include <boost/mpl/identity.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/control/iif.hpp>
-#include <boost/preprocessor/comma_if.hpp>
-#include <boost/preprocessor/detail/is_unary.hpp>
-#include <boost/preprocessor/list/for_each.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/seq/for_each_i.hpp>
-#include <boost/preprocessor/seq/size.hpp>
-#include <boost/preprocessor/tuple/eat.hpp>
-#include <boost/range/const_iterator.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/type_traits/remove_cv.hpp>
-#include <boost/utility/addressof.hpp>
-#include <boost/utility/enable_if.hpp> // disable_if
-
-#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
-    #include <boost/range/mutable_iterator.hpp>
-#else
-    #include <iterator> // distance
-    #include <boost/range/begin.hpp>
-    #include <boost/range/end.hpp>
-    #include <boost/range/iterator.hpp>
-#endif
-
-
-namespace boost { namespace range_detail_microsoft {
-
-
-    // customization point
-    //
-
-    template< class Tag >
-    struct customization;
-
-
-    template< class T >
-    struct customization_tag;
-
-
-    struct using_type_as_tag
-    { };
-
-
-    // Topic:
-    // In fact, it is unnecessary for VC++.
-    // VC++'s behavior seems conforming, while GCC fails without this.
-    template< class Iterator, class T >
-    struct mutable_ :
-        disable_if< is_const<T>, Iterator >
-    { };
-
-
-    // helpers
-    //
-
-    template< class Tag, class T >
-    struct customization_tag_of
-    {
-        typedef typename mpl::if_< is_same<using_type_as_tag, Tag>,
-            T,
-            Tag
-        >::type type;
-    };
-
-
-    template< class T >
-    struct customization_of
-    {
-        typedef typename remove_cv<T>::type bare_t;
-        typedef typename customization_tag<bare_t>::type tag_t;
-        typedef customization<tag_t> type;
-    };
-
-
-    template< class T >
-    struct mutable_iterator_of
-    {
-        typedef typename remove_cv<T>::type bare_t;
-        typedef typename customization_of<bare_t>::type cust_t;
-        typedef typename cust_t::template meta<bare_t>::mutable_iterator type;
-    };
-
-
-    template< class T >
-    struct const_iterator_of
-    {
-        typedef typename remove_cv<T>::type bare_t;
-        typedef typename customization_of<bare_t>::type cust_t;
-        typedef typename cust_t::template meta<bare_t>::const_iterator type;
-    };
-
-
-    template< class T >
-    struct size_type_of
-    {
-        typedef typename range_detail_microsoft::mutable_iterator_of<T>::type miter_t;
-        typedef typename iterator_difference<miter_t>::type type;
-    };
-
-
-    template< class T > inline
-    typename mutable_iterator_of<T>::type
-    begin_of(T& x)
-    {
-        typedef typename customization_of<T>::type cust_t;
-        return cust_t().template begin<typename mutable_iterator_of<T>::type>(x);
-    }
-
-
-    template< class T > inline
-    typename const_iterator_of<T>::type
-    begin_of(T const& x)
-    {
-        typedef typename customization_of<T>::type cust_t;
-        return cust_t().template begin<typename const_iterator_of<T>::type>(x);
-    }
-
-
-    template< class T > inline
-    typename mutable_iterator_of<T>::type
-    end_of(T& x)
-    {
-        typedef typename customization_of<T>::type cust_t;
-        return cust_t().template end<typename mutable_iterator_of<T>::type>(x);
-    }
-
-
-    template< class T > inline
-    typename const_iterator_of<T>::type
-    end_of(T const& x)
-    {
-        typedef typename customization_of<T>::type cust_t;
-        return cust_t().template end<typename const_iterator_of<T>::type>(x);
-    }
-
-
-#if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
-
-    template< class T > inline
-    typename size_type_of<T>::type
-    size_of(T const& x)
-    {
-        return std::distance(boost::begin(x), boost::end(x));
-    }
-
-#endif
-
-
-    template< class Range >
-    struct compatible_mutable_iterator : 
-        BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>
-    { };
-
-
-} } // namespace boost::range_detail_microsoft
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
-    BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \
-/**/
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \
-        namespace elem { \
-    /**/
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
-    BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \
-/**/
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \
-        } \
-    /**/
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \
-    :: elem \
-/**/
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \
-    namespace boost { namespace range_detail_microsoft { \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-    } } \
-    \
-    namespace boost { \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-    } \
-    \
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
-/**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \
-        BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \
-        template< > \
-        struct customization_tag< Fullname > : \
-            customization_tag_of< Tag, Fullname > \
-        { }; \
-    /**/
-
-
-    // metafunctions
-    //
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \
-        template< > \
-        struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
-            range_detail_microsoft::mutable_iterator_of< Fullname > \
-        { }; \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \
-        template< > \
-        struct range_const_iterator< Fullname > : \
-            range_detail_microsoft::const_iterator_of< Fullname > \
-        { }; \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \
-        template< > \
-        struct range_size< Fullname > : \
-            range_detail_microsoft::size_type_of< Fullname > \
-        { }; \
-    /**/
-
-
-    // functions
-    //
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \
-        inline \
-        boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
-        { \
-            return boost::range_detail_microsoft::begin_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \
-        inline \
-        boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
-        { \
-            return boost::range_detail_microsoft::begin_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \
-        inline \
-        boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
-        { \
-            return boost::range_detail_microsoft::end_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \
-        inline \
-        boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
-        { \
-            return boost::range_detail_microsoft::end_of(x); \
-        } \
-    /**/
-
-
-    #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
-        /**/
-
-    #else
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
-            inline \
-            boost::range_detail_microsoft::size_type_of< Fullname >::type \
-            boost_range_size(Fullname const& x) \
-            { \
-                return boost::range_detail_microsoft::size_of(x); \
-            } \
-        /**/
-
-    #endif
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \
-        Tag, NamespaceList, Name, \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
-    ) \
-/**/
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
-        BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \
-            ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \
-            BOOST_PP_REPEAT \
-        )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \
-    /**/
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \
-            (class) \
-        /**/
-
-
-#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \
-    namespace boost { namespace range_detail_microsoft { \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \
-            Tag, \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-    } } \
-    \
-    namespace boost { \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-    } \
-    \
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-        BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
-            BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        ) \
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
-/**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \
-        BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \
-    /**/
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \
-            BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \
-        /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
-        BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \
-        :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \
-        template< Params > \
-        struct customization_tag< Fullname > : \
-            customization_tag_of< Tag, Fullname > \
-        { }; \
-    /**/
-
-
-    // metafunctions
-    //
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \
-        template< Params > \
-        struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
-            range_detail_microsoft::mutable_iterator_of< Fullname > \
-        { }; \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \
-        template< Params > \
-        struct range_const_iterator< Fullname > : \
-            range_detail_microsoft::const_iterator_of< Fullname > \
-        { }; \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \
-        template< Params > \
-        struct range_size< Fullname > : \
-            range_detail_microsoft::size_type_of< Fullname > \
-        { }; \
-    /**/
-
-
-    // functions
-    //
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \
-        template< Params > inline \
-        typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
-        { \
-            return boost::range_detail_microsoft::begin_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \
-        template< Params > inline \
-        typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
-        { \
-            return boost::range_detail_microsoft::begin_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \
-        template< Params > inline \
-        typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
-        { \
-            return boost::range_detail_microsoft::end_of(x); \
-        } \
-    /**/
-
-
-    #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \
-        template< Params > inline \
-        typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
-        BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
-        { \
-            return boost::range_detail_microsoft::end_of(x); \
-        } \
-    /**/
-
-
-    #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
-        /**/
-
-    #else
-
-        #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
-            template< Params > inline \
-            typename boost::range_detail_microsoft::size_type_of< Fullname >::type \
-            boost_range_size(Fullname const& x) \
-            { \
-                return boost::range_detail_microsoft::size_of(x); \
-            } \
-        /**/
-
-    #endif
-
-
-
-
-// list_iterator and helpers
-//
-
-
-#include <boost/assert.hpp>
-#include <boost/iterator/iterator_categories.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-
-// POSITION's header is undocumented, so is NULL.
-//
-struct __POSITION; // incomplete, but used as just a pointer.
-typedef __POSITION *POSITION;
-
-
-namespace boost { namespace range_detail_microsoft {
-
-
-    template<
-        class ListT,
-        class Value,
-        class Reference,
-        class Traversal
-    >
-    struct list_iterator;
-
-
-    template<
-        class ListT,
-        class Value,
-        class Reference,
-        class Traversal
-    >
-    struct list_iterator_super
-    {
-        typedef typename mpl::if_< is_same<use_default, Reference>,
-            Value&,
-            Reference
-        >::type ref_t;
-
-        typedef typename mpl::if_< is_same<use_default, Traversal>,
-            bidirectional_traversal_tag,
-            Traversal
-        >::type trv_t;
-
-        typedef iterator_facade<
-            list_iterator<ListT, Value, Reference, Traversal>,
-            Value,
-            trv_t,
-            ref_t
-        > type;
-    };
-
-
-    template<
-        class ListT,
-        class Value,
-        class Reference = use_default,
-        class Traversal = use_default
-    >
-    struct list_iterator :
-        list_iterator_super<ListT, Value, Reference, Traversal>::type
-    {
-    private:
-        typedef list_iterator self_t;
-        typedef typename list_iterator_super<ListT, Value, Reference, Traversal>::type super_t;
-        typedef typename super_t::reference ref_t;
-
-    public:
-        explicit list_iterator()
-        { }
-
-        explicit list_iterator(ListT& lst, POSITION pos) :
-            m_plst(boost::addressof(lst)), m_pos(pos)
-        { }
-
-    template< class, class, class, class > friend struct list_iterator;
-        template< class ListT_, class Value_, class Reference_, class Traversal_>
-        list_iterator(list_iterator<ListT_, Value_, Reference_, Traversal_> const& other) :
-            m_plst(other.m_plst), m_pos(other.m_pos)
-        { }
-
-    private:
-        ListT *m_plst;
-        POSITION m_pos;
-
-    friend class iterator_core_access;
-        ref_t dereference() const
-        {
-            BOOST_ASSERT(m_pos != 0 && "out of range");
-            return m_plst->GetAt(m_pos);
-        }
-
-        // A    B    C    D    x
-        // Head           Tail NULL(0)
-        //
-        void increment()
-        {
-            BOOST_ASSERT(m_pos != 0 && "out of range");
-            m_plst->GetNext(m_pos);
-        }
-
-        void decrement()
-        {
-            if (m_pos == 0) {
-                m_pos = m_plst->GetTailPosition();
-                return;
-            }
-
-            m_plst->GetPrev(m_pos);
-        }
-
-        bool equal(self_t const& other) const
-        {
-            BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible");
-            return m_pos == other.m_pos;
-        }
-    };
-
-
-    // customization helpers
-    //
-
-    struct array_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return x.GetData();
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return begin<Iterator>(x) + x.GetSize();
-        }
-    };
-
-
-    struct list_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return Iterator(x, x.GetHeadPosition());
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(x, POSITION(0));
-        }
-    };
-
-
-} } // namespace boost::range_detail_microsoft
-
-
-
-
-// test
-//
-
-
-#if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
-
-
-#include <algorithm>
-#include <iterator>
-#include <vector>
-#include <boost/concept_check.hpp>
-#include <boost/next_prior.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/const_iterator.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/distance.hpp>
-#include <boost/range/empty.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/mutable_iterator.hpp>
-#include <boost/range/rbegin.hpp>
-#include <boost/range/rend.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-
-namespace boost { namespace range_detail_microsoft {
-
-
-    template< class Range1, class Range2 >
-    bool test_equals(Range1 const& rng1, Range2 const& rng2)
-    {
-        return
-            boost::distance(rng1) == boost::distance(rng2) &&
-            std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2))
-        ;
-    }
-
-
-    template< class AssocContainer, class PairT >
-    bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa)
-    {
-        typedef typename boost::range_const_iterator<AssocContainer>::type iter_t;
-        for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) {
-            if (it->first == pa.first && it->second == pa.second)
-                return true;
-        }
-
-        return false;
-    }
-
-
-    // test functions
-    //
-
-    template< class Range >
-    bool test_emptiness(Range& )
-    {
-        bool result = true;
-
-        Range emptyRng;
-        result = result && boost::empty(emptyRng);
-
-        return result;
-    }
-
-
-    template< class Range >
-    bool test_trivial(Range& rng)
-    {
-        bool result = true;
-
-        // convertibility check
-        typedef typename range_const_iterator<Range>::type citer_t;
-        citer_t cit = boost::begin(rng);
-        (void)cit; // unused
-
-        // mutability check
-        typedef typename range_value<Range>::type val_t;
-        val_t v = *boost::begin(rng);
-        *boost::begin(rng) = v;
-        result = result && *boost::begin(rng) == v;
-
-        return result;
-    }
-
-
-    template< class Range >
-    bool test_forward(Range& rng)
-    {
-        boost::function_requires< ForwardRangeConcept<Range> >();
-
-        bool result = (test_trivial)(rng);
-
-        typedef typename range_value<Range>::type val_t;
-
-        std::vector<val_t> saved;
-        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
-        std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved));
-
-        std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng));
-
-        return result && (test_equals)(saved, rng);
-    };
-
-
-    template< class Range >
-    bool test_bidirectional(Range& rng)
-    {
-        boost::function_requires< BidirectionalRangeConcept<Range> >();
-
-        bool result = (test_forward)(rng);
-
-        typedef typename range_value<Range>::type val_t;
-
-        std::vector<val_t> saved;
-        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
-
-        result = result && (test_equals)(
-            boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)),
-            boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng))
-        );
-
-        return result;
-    }
-
-
-    template< class Range >
-    bool test_random_access(Range& rng)
-    {
-        boost::function_requires< RandomAccessRangeConcept<Range> >();
-
-        bool result = (test_bidirectional)(rng);
-
-        typedef typename range_value<Range>::type val_t;
-
-        std::vector<val_t> saved;
-        std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
-        std::sort(boost::begin(saved), boost::end(saved));
-
-        std::random_shuffle(boost::begin(rng), boost::end(rng));
-        std::sort(boost::begin(rng), boost::end(rng));
-        result = result && (test_equals)(rng, saved);
-
-        std::random_shuffle(boost::begin(rng), boost::end(rng));
-        std::stable_sort(boost::begin(rng), boost::end(rng));
-        result = result && (test_equals)(rng, saved);
-
-        std::random_shuffle(boost::begin(rng), boost::end(rng));
-        std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng));
-        result = result && (test_equals)(rng, saved);
-
-        return result;
-    }
-
-
-    // initializer
-    //
-
-    template< class ArrayT, class SampleRange >
-    bool test_init_array(ArrayT& arr, SampleRange const& sample)
-    {
-        typedef typename range_const_iterator<SampleRange>::type iter_t;
-        typedef typename range_value<SampleRange>::type val_t;
-
-        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
-            val_t v = *it; // works around ATL3 CSimpleArray
-            arr.Add(v);
-        }
-
-        return (test_equals)(arr, sample);
-    }
-
-
-    template< class ListT, class SampleRange >
-    bool test_init_list(ListT& lst, SampleRange const& sample)
-    {
-        typedef typename range_const_iterator<SampleRange>::type iter_t;
-
-        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
-            lst.AddTail(*it);
-        }
-
-        return (test_equals)(lst, sample);
-    }
-
-
-    template< class StringT, class SampleRange >
-    bool test_init_string(StringT& str, SampleRange const& sample)
-    {
-        typedef typename range_const_iterator<SampleRange>::type iter_t;
-        typedef typename range_value<SampleRange>::type val_t;
-
-        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
-            str += *it;
-        }
-
-        return (test_equals)(str, sample);
-    }
-
-
-    template< class MapT, class SampleMap >
-    bool test_init_map(MapT& map, SampleMap const& sample)
-    {
-        typedef typename range_const_iterator<SampleMap>::type iter_t;
-
-        for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
-            map.SetAt(it->first, it->second);
-        }
-
-        return boost::distance(map) == boost::distance(sample);
-    }
-
-
-    // metafunction test
-    //
-
-    template< class Range, class Iter >
-    struct test_mutable_iter :
-        boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>::type, Iter >
-    { };
-
-
-    template< class Range, class Iter >
-    struct test_const_iter :
-        boost::is_same< typename boost::range_const_iterator<Range>::type, Iter >
-    { };
-
-
-} } // namespace boost::range_detail_microsoft
-
-
-#endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
-
-
-
-#endif
diff --git a/src/boost/range/detail/misc_concept.hpp b/src/boost/range/detail/misc_concept.hpp
deleted file mode 100644
index 74cb919..0000000
--- a/src/boost/range/detail/misc_concept.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Boost.Range library concept checks
-//
-//  Copyright Neil Groves 2009. Use, modification and distribution
-//  are subject to the Boost Software License, Version 1.0. (See
-//  accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-#ifndef BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
-
-#include <boost/concept_check.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<typename T1, typename T2>
-        class SameTypeConcept
-        {
-        public:
-            BOOST_CONCEPT_USAGE(SameTypeConcept)
-            {
-                same_type(a,b);
-            }
-        private:
-            template<typename T> void same_type(T,T) {}
-            T1 a;
-            T2 b;
-        };
-    }
-}
-
-#endif // include guard
diff --git a/src/boost/range/detail/range_return.hpp b/src/boost/range/detail/range_return.hpp
deleted file mode 100644
index 52a6073..0000000
--- a/src/boost/range/detail/range_return.hpp
+++ /dev/null
@@ -1,180 +0,0 @@
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
-#define BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
-
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    enum range_return_value
-    {
-        // (*) indicates the most common values
-        return_found,       // only the found resulting iterator (*)
-        return_next,        // next(found) iterator
-        return_prior,       // prior(found) iterator
-        return_begin_found, // [begin, found) range (*)
-        return_begin_next,  // [begin, next(found)) range
-        return_begin_prior, // [begin, prior(found)) range
-        return_found_end,   // [found, end) range (*)
-        return_next_end,    // [next(found), end) range
-        return_prior_end,   // [prior(found), end) range
-        return_begin_end    // [begin, end) range
-    };
-
-    template< class SinglePassRange, range_return_value >
-    struct range_return
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type(found, boost::end(rng));
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_found >
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
-
-        static type pack(type found, SinglePassRange&)
-        {
-            return found;
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_next >
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
-
-        static type pack(type found, SinglePassRange& rng)
-        {
-            return found == boost::end(rng)
-                ? found
-                : boost::next(found);
-        }
-    };
-
-    template< class BidirectionalRange >
-    struct range_return< BidirectionalRange, return_prior >
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type type;
-
-        static type pack(type found, BidirectionalRange& rng)
-        {
-            return found == boost::begin(rng)
-                ? found
-                : boost::prior(found);
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_begin_found >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type(boost::begin(rng), found);
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_begin_next >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type( boost::begin(rng), 
-                         found == boost::end(rng) ? found : boost::next(found) );
-        }
-    };
-
-    template< class BidirectionalRange >
-    struct range_return< BidirectionalRange, return_begin_prior >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
-                         BidirectionalRange& rng)
-        {
-            return type( boost::begin(rng),
-                         found == boost::begin(rng) ? found : boost::prior(found) );
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_found_end >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type(found, boost::end(rng));
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_next_end >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type( found == boost::end(rng) ? found : boost::next(found),
-                         boost::end(rng) );
-        }
-    };
-
-    template< class BidirectionalRange >
-    struct range_return< BidirectionalRange, return_prior_end >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
-                         BidirectionalRange& rng)
-        {
-            return type( found == boost::begin(rng) ? found : boost::prior(found),
-                         boost::end(rng) );
-        }
-    };
-
-    template< class SinglePassRange >
-    struct range_return< SinglePassRange, return_begin_end >
-    {
-        typedef boost::iterator_range<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
-
-        static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
-                         SinglePassRange& rng)
-        {
-            return type(boost::begin(rng), boost::end(rng));
-        }
-    };
-
-}
-
-#endif // include guard
diff --git a/src/boost/range/detail/remove_extent.hpp b/src/boost/range/detail/remove_extent.hpp
deleted file mode 100644
index 68e4597..0000000
--- a/src/boost/range/detail/remove_extent.hpp
+++ /dev/null
@@ -1,157 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Jonathan Turkanis 2005. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-
-#ifndef BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
-#define BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
-
-#include <boost/config.hpp>  // MSVC, NO_INTRINSIC_WCHAR_T, put size_t in std.
-#include <cstddef>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost 
-{
-    namespace range_detail
-    {
-        
-        template< typename Case1 = mpl::true_,
-                  typename Type1 = mpl::void_,
-                  typename Case2 = mpl::true_,
-                  typename Type2 = mpl::void_,
-                  typename Case3 = mpl::true_,
-                  typename Type3 = mpl::void_,
-                  typename Case4 = mpl::true_,
-                  typename Type4 = mpl::void_,
-                  typename Case5 = mpl::true_,
-                  typename Type5 = mpl::void_,
-                  typename Case6 = mpl::true_,
-                  typename Type6 = mpl::void_,
-                  typename Case7 = mpl::true_,
-                  typename Type7 = mpl::void_,
-                  typename Case8 = mpl::true_,
-                  typename Type8 = mpl::void_,
-                  typename Case9 = mpl::true_,
-                  typename Type9 = mpl::void_,
-                  typename Case10 = mpl::true_,
-                  typename Type10 = mpl::void_,
-                  typename Case11 = mpl::true_,
-                  typename Type11 = mpl::void_,
-                  typename Case12 = mpl::true_,
-                  typename Type12 = mpl::void_,
-                  typename Case13 = mpl::true_,
-                  typename Type13 = mpl::void_,
-                  typename Case14 = mpl::true_,
-                  typename Type14 = mpl::void_,
-                  typename Case15 = mpl::true_,
-                  typename Type15 = mpl::void_,
-                  typename Case16 = mpl::true_,
-                  typename Type16 = mpl::void_,
-                  typename Case17 = mpl::true_,
-                  typename Type17 = mpl::void_,
-                  typename Case18 = mpl::true_,
-                  typename Type18 = mpl::void_,
-                  typename Case19 = mpl::true_,
-                  typename Type19 = mpl::void_,
-                  typename Case20 = mpl::true_,
-                  typename Type20 = mpl::void_>
-        struct select {
-            typedef typename
-                    mpl::eval_if<
-                        Case1, mpl::identity<Type1>, mpl::eval_if<
-                        Case2, mpl::identity<Type2>, mpl::eval_if<
-                        Case3, mpl::identity<Type3>, mpl::eval_if<
-                        Case4, mpl::identity<Type4>, mpl::eval_if<
-                        Case5, mpl::identity<Type5>, mpl::eval_if<
-                        Case6, mpl::identity<Type6>, mpl::eval_if<
-                        Case7, mpl::identity<Type7>, mpl::eval_if<
-                        Case8, mpl::identity<Type8>, mpl::eval_if<
-                        Case9, mpl::identity<Type9>, mpl::if_<
-                        Case10, Type10, mpl::void_ > > > > > > > > >
-                    >::type result1;
-            typedef typename
-                    mpl::eval_if<
-                        Case11, mpl::identity<Type11>, mpl::eval_if<
-                        Case12, mpl::identity<Type12>, mpl::eval_if<
-                        Case13, mpl::identity<Type13>, mpl::eval_if<
-                        Case14, mpl::identity<Type14>, mpl::eval_if<
-                        Case15, mpl::identity<Type15>, mpl::eval_if<
-                        Case16, mpl::identity<Type16>, mpl::eval_if<
-                        Case17, mpl::identity<Type17>, mpl::eval_if<
-                        Case18, mpl::identity<Type18>, mpl::eval_if<
-                        Case19, mpl::identity<Type19>, mpl::if_<
-                        Case20, Type20, mpl::void_ > > > > > > > > >
-                    > result2;
-            typedef typename    
-                    mpl::eval_if<
-                        is_same<result1, mpl::void_>,
-                        result2,
-                        mpl::identity<result1>
-                    >::type type;
-        };
-
-        template<typename T>
-        struct remove_extent {
-            static T* ar;
-            BOOST_STATIC_CONSTANT(std::size_t, size = sizeof(*ar) / sizeof((*ar)[0]));
-
-            typedef typename
-                    select<
-                        is_same<T, bool[size]>,                  bool,
-                        is_same<T, char[size]>,                  char,
-                        is_same<T, signed char[size]>,           signed char,
-                        is_same<T, unsigned char[size]>,         unsigned char,
-                    #ifndef BOOST_NO_INTRINSIC_WCHAR_T
-                        is_same<T, wchar_t[size]>,               wchar_t,
-                    #endif
-                        is_same<T, short[size]>,                 short,
-                        is_same<T, unsigned short[size]>,        unsigned short,
-                        is_same<T, int[size]>,                   int,
-                        is_same<T, unsigned int[size]>,          unsigned int,
-                        is_same<T, long[size]>,                  long,
-                        is_same<T, unsigned long[size]>,         unsigned long,
-                        is_same<T, float[size]>,                 float,
-                        is_same<T, double[size]>,                double,
-                        is_same<T, long double[size]>,           long double
-                    >::type result1;
-            typedef typename
-                    select<
-                        is_same<T, const bool[size]>,            const bool,
-                        is_same<T, const char[size]>,            const char,
-                        is_same<T, const signed char[size]>,     const signed char,
-                        is_same<T, const unsigned char[size]>,   const unsigned char,
-                    #ifndef BOOST_NO_INTRINSIC_WCHAR_T
-                        is_same<T, const wchar_t[size]>,         const wchar_t,
-                    #endif
-                        is_same<T, const short[size]>,           const short,
-                        is_same<T, const unsigned short[size]>,  const unsigned short,
-                        is_same<T, const int[size]>,             const int,
-                        is_same<T, const unsigned int[size]>,    const unsigned int,
-                        is_same<T, const long[size]>,            const long,
-                        is_same<T, const unsigned long[size]>,   const unsigned long,
-                        is_same<T, const float[size]>,           const float,
-                        is_same<T, const double[size]>,          const double,
-                        is_same<T, const long double[size]>,     const long double
-                    > result2;
-            typedef typename
-                    mpl::eval_if<
-                        is_same<result1, mpl::void_>,
-                        result2,
-                        mpl::identity<result1>
-                    >::type type;
-        };
-
-    } // namespace 'range_detail'
-
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/safe_bool.hpp b/src/boost/range/detail/safe_bool.hpp
deleted file mode 100644
index 182e510..0000000
--- a/src/boost/range/detail/safe_bool.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-//  This header intentionally has no include guards.
-//
-//  Copyright (c) 2010 Neil Groves
-//  Distributed under the Boost Software License, Version 1.0.
-//  See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt
-//
-// This code utilises the experience gained during the evolution of
-// <boost/smart_ptr/operator_bool.hpp>
-#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
-#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
-
-#include <boost/config.hpp>
-#include <boost/range/config.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-template<class DataMemberPtr>
-class safe_bool
-{
-public:
-    typedef safe_bool this_type;
-
-#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_)
-    typedef bool unspecified_bool_type;
-    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
-    {
-        return x;
-    }
-#elif defined(_MANAGED)
-    static void unspecified_bool(this_type***)
-    {
-    }
-    typedef void(*unspecified_bool_type)(this_type***);
-    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
-    {
-        return x ? unspecified_bool : 0;
-    }
-#elif \
-    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
-    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
-    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
-
-    typedef bool (this_type::*unspecified_bool_type)() const;
-
-    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
-    {
-        return x ? &this_type::detail_safe_bool_member_fn : 0;
-    }
-private:
-    bool detail_safe_bool_member_fn() const { return false; }
-#else
-    typedef DataMemberPtr unspecified_bool_type;
-    static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p)
-    {
-        return x ? p : 0;
-    }
-#endif
-private:
-    safe_bool();
-    safe_bool(const safe_bool&);
-    void operator=(const safe_bool&);
-    ~safe_bool();
-};
-
-    } // namespace range_detail
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/detail/sfinae.hpp b/src/boost/range/detail/sfinae.hpp
deleted file mode 100644
index 5b2c61e..0000000
--- a/src/boost/range/detail/sfinae.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_SFINAE_HPP
-#define BOOST_RANGE_DETAIL_SFINAE_HPP
-
-#include <boost/range/config.hpp>
-#include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/detail/yes_no_type.hpp>
-#include <utility>
-
-
-namespace boost 
-{
-    namespace range_detail
-    {          
-        using type_traits::yes_type;
-        using type_traits::no_type;
-
-        //////////////////////////////////////////////////////////////////////
-        // string
-        //////////////////////////////////////////////////////////////////////
-        
-        yes_type is_string_impl( const char* const );
-        yes_type is_string_impl( const wchar_t* const );
-        no_type  is_string_impl( ... );
-        
-        template< std::size_t sz >
-        yes_type is_char_array_impl( char BOOST_RANGE_ARRAY_REF()[sz] );
-        template< std::size_t sz >
-        yes_type is_char_array_impl( const char BOOST_RANGE_ARRAY_REF()[sz] );
-        no_type  is_char_array_impl( ... );
-        
-        template< std::size_t sz >
-        yes_type is_wchar_t_array_impl( wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
-        template< std::size_t sz >
-        yes_type is_wchar_t_array_impl( const wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
-        no_type  is_wchar_t_array_impl( ... );
-                                     
-        yes_type is_char_ptr_impl( char* const );
-        no_type  is_char_ptr_impl( ... );
-        
-        yes_type is_const_char_ptr_impl( const char* const );
-        no_type  is_const_char_ptr_impl( ... );
-
-        yes_type is_wchar_t_ptr_impl( wchar_t* const );
-        no_type  is_wchar_t_ptr_impl( ... );
-        
-        yes_type is_const_wchar_t_ptr_impl( const wchar_t* const );
-        no_type  is_const_wchar_t_ptr_impl( ... );
-        
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-
-        template< typename Iterator >
-        yes_type is_pair_impl( const std::pair<Iterator,Iterator>* );
-        no_type  is_pair_impl( ... );
-
-        //////////////////////////////////////////////////////////////////////
-        // tags
-        //////////////////////////////////////////////////////////////////////
-
-        struct char_or_wchar_t_array_tag {};
-        
-    } // namespace 'range_detail'
-    
-} // namespace 'boost'
-
-#endif
diff --git a/src/boost/range/detail/size.hpp b/src/boost/range/detail/size.hpp
deleted file mode 100644
index fe52ba0..0000000
--- a/src/boost/range/detail/size.hpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-
-#ifndef BOOST_RANGE_DETAIL_SIZE_HPP
-#define BOOST_RANGE_DETAIL_SIZE_HPP
-
-#include <boost/config.hpp> // BOOST_MSVC
-#include <boost/detail/workaround.hpp>
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-# include <boost/range/detail/vc6/size.hpp>
-#else
-# include <boost/range/detail/implementation_help.hpp>
-# include <boost/range/detail/size_type.hpp>
-# include <boost/range/detail/common.hpp>
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
-#  include <boost/range/detail/remove_extent.hpp>
-# endif
-# include <iterator>
-
-namespace boost 
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_size_;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_size_<std_container_>
-        {
-            template< typename C >
-            static BOOST_RANGE_DEDUCED_TYPENAME C::size_type fun( const C& c )
-            {
-                return c.size();
-            };
-        };
-                    
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_size_<std_pair_>
-        {
-            template< typename P >
-            static BOOST_RANGE_DEDUCED_TYPENAME range_size<P>::type 
-            fun( const P& p )
-            {
-                return std::distance( p.first, p.second );
-            }
-        };
- 
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_size_<array_>
-        {
-        #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-            template< typename T, std::size_t sz >
-            static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return sz;
-            }
-        #else
-            template<typename T>
-            static std::size_t fun(T& t)
-            {
-                return remove_extent<T>::size;
-            }
-        #endif
-        };
-        
-        template<>
-        struct range_size_<char_array_>
-        {
-            template< typename T, std::size_t sz >
-            static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost::range_detail::array_size( boost_range_array );
-            }
-        };
-        
-        template<>
-        struct range_size_<wchar_t_array_>
-        {
-            template< typename T, std::size_t sz >
-            static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
-            {
-                return boost::range_detail::array_size( boost_range_array );
-            }
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // string
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_size_<char_ptr_>
-        {
-            static std::size_t fun( const char* s )
-            {
-                return boost::range_detail::str_size( s );
-            }
-        };
-
-        template<>
-        struct range_size_<const_char_ptr_>
-        {
-            static std::size_t fun( const char* s )
-            {
-                return boost::range_detail::str_size( s );
-            }
-        };
-        
-        template<>
-        struct range_size_<wchar_t_ptr_>
-        {
-            static std::size_t fun( const wchar_t* s )
-            {
-                return boost::range_detail::str_size( s );
-            }
-        };
-
-        template<>
-        struct range_size_<const_wchar_t_ptr_>
-        {
-            static std::size_t fun( const wchar_t* s )
-            {
-                return boost::range_detail::str_size( s );
-            }
-        };
-  
-    } // namespace 'range_detail'
-    
-
-    template< typename C >
-    BOOST_RANGE_DEDUCED_TYPENAME range_size<C>::type 
-    size( const C& c )
-    {
-        return range_detail::range_size_<  BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
-    }
-    
-} // namespace 'boost'
-
-# endif
-#endif
diff --git a/src/boost/range/detail/size_type.hpp b/src/boost/range/detail/size_type.hpp
deleted file mode 100644
index 78a60a4..0000000
--- a/src/boost/range/detail/size_type.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
-#define BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
-
-#include <boost/range/detail/common.hpp>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_size_type_
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef std::size_t type;
-            };
-        };
-
-        template<>
-        struct range_size_type_<std_container_>
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type;
-            };
-        };
-    }
-
-    template< typename C >
-    class range_size
-    {
-        typedef typename range_detail::range<C>::type c_type;
-    public:
-        typedef typename range_detail::range_size_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
-    };
-}
-
-#endif
-
diff --git a/src/boost/range/detail/sizer.hpp b/src/boost/range/detail/sizer.hpp
deleted file mode 100644
index b4c1c91..0000000
--- a/src/boost/range/detail/sizer.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_SIZER_HPP
-#define BOOST_RANGE_DETAIL_SIZER_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <cstddef>
-
-namespace boost 
-{
-    //////////////////////////////////////////////////////////////////////
-    // constant array size
-    //////////////////////////////////////////////////////////////////////
-    
-    template< typename T, std::size_t sz >
-    char (& sizer( const T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
-    
-    template< typename T, std::size_t sz >
-    char (& sizer( T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
-
-} // namespace 'boost'
-
-#endif
diff --git a/src/boost/range/detail/str_types.hpp b/src/boost/range/detail/str_types.hpp
deleted file mode 100644
index f8cab19..0000000
--- a/src/boost/range/detail/str_types.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_STR_TYPES_HPP
-#define BOOST_RANGE_DETAIL_STR_TYPES_HPP
-
-#include <boost/range/size_type.hpp>
-#include <boost/range/iterator.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_mutable_iterator<T*>
-    {
-        typedef T* type;
-    };
-
-    template< class T >
-    struct range_const_iterator<T*>
-    {
-        typedef const T* type;
-    };
-
-    template< class T >
-    struct range_size<T*>
-    {
-       typedef std::size_t type;
-    };    
-}
-
-#endif
diff --git a/src/boost/range/detail/value_type.hpp b/src/boost/range/detail/value_type.hpp
deleted file mode 100644
index 2784514..0000000
--- a/src/boost/range/detail/value_type.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
-#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
-
-#include <boost/range/detail/common.hpp>
-#include <boost/range/detail/remove_extent.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-//////////////////////////////////////////////////////////////////////////////
-// missing partial specialization  workaround.
-//////////////////////////////////////////////////////////////////////////////
-
-namespace boost 
-{
-    namespace range_detail 
-    {        
-        template< typename T >
-        struct range_value_type_;
-
-        template<>
-        struct range_value_type_<std_container_>
-        {
-            template< typename C >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME C::value_type type;
-            };
-        };
-
-        template<>
-        struct range_value_type_<std_pair_>
-        {
-            template< typename P >
-            struct pts
-            {
-                typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_value< BOOST_RANGE_DEDUCED_TYPENAME P::first_type >::type type;
-            };
-        };
-
-        template<>
-        struct range_value_type_<array_>
-        { 
-            template< typename T >
-            struct pts
-            {
-                typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type type;
-            };
-        };
-        
-    } 
-    
-    template< typename C >
-    class range_value
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
-    public:
-        typedef BOOST_DEDUCED_TYPENAME range_detail::range_value_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type; 
-    };
-
-}
-
-#endif
-
diff --git a/src/boost/range/detail/vc6/end.hpp b/src/boost/range/detail/vc6/end.hpp
deleted file mode 100644
index 4f76af5..0000000
--- a/src/boost/range/detail/vc6/end.hpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DETAIL_VC6_END_HPP
-#define BOOST_RANGE_DETAIL_VC6_END_HPP
-
-#include <boost/range/detail/implementation_help.hpp>
-#include <boost/range/detail/implementation_help.hpp>
-#include <boost/range/result_iterator.hpp>
-#include <boost/range/detail/common.hpp>
-#include <boost/range/detail/remove_extent.hpp>
-
-namespace boost 
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_end;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_end<std_container_>
-        {
-            template< typename C >
-            struct inner {
-                static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<C>::type 
-                fun( C& c )
-                {
-                    return c.end();
-                };
-            };
-        };
-                    
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_end<std_pair_>
-        {
-            template< typename P >
-            struct inner {
-                static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<P>::type 
-                fun( const P& p )
-                {
-                    return p.second;
-                }
-            };
-        };
- 
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_end<array_>  
-        {
-            template< typename T >
-            struct inner {
-                static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
-                fun(T& t)
-                {
-                    return t + remove_extent<T>::size;
-                }
-            };
-        };
-
-                
-        template<>
-        struct range_end<char_array_>
-        {
-            template< typename T >
-            struct inner {
-                static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
-                fun(T& t)
-                {
-                    return t + remove_extent<T>::size;
-                }
-            };
-        };
-        
-        template<>
-        struct range_end<wchar_t_array_>
-        {
-            template< typename T >
-            struct inner {
-                static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
-                fun(T& t)
-                {
-                    return t + remove_extent<T>::size;
-                }
-            };
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // string
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_end<char_ptr_>
-        {
-            template< typename T >
-            struct inner {
-                static char* fun( char* s )
-                {
-                    return boost::range_detail::str_end( s );
-                }
-            };
-        };
-
-        template<>
-        struct range_end<const_char_ptr_>
-        {
-            template< typename T >
-            struct inner {
-                static const char* fun( const char* s )
-                {
-                    return boost::range_detail::str_end( s );
-                }
-            };
-        };
-
-        template<>
-        struct range_end<wchar_t_ptr_>
-        {
-            template< typename T >
-            struct inner {
-                static wchar_t* fun( wchar_t* s )
-                {
-                    return boost::range_detail::str_end( s );
-                }
-            };
-        };
-
-
-        template<>
-        struct range_end<const_wchar_t_ptr_>
-        {
-            template< typename T >
-            struct inner {
-                static const wchar_t* fun( const wchar_t* s )
-                {
-                    return boost::range_detail::str_end( s );
-                }
-            };
-        };
-        
-    } // namespace 'range_detail'
-    
-    template< typename C >
-    inline BOOST_DEDUCED_TYPENAME range_result_iterator<C>::type 
-    end( C& c )
-    {
-        return range_detail::range_end<range_detail::range<C>::type>::inner<C>::fun( c );
-    }
-    
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/detail/vc6/size.hpp b/src/boost/range/detail/vc6/size.hpp
deleted file mode 100644
index 39f559f..0000000
--- a/src/boost/range/detail/vc6/size.hpp
+++ /dev/null
@@ -1,166 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-
-#ifndef BOOST_RANGE_DETAIL_VC6_SIZE_HPP
-#define BOOST_RANGE_DETAIL_VC6_SIZE_HPP
-
-#include <boost/range/detail/implementation_help.hpp>
-#include <boost/range/detail/size_type.hpp>
-#include <boost/range/detail/common.hpp>
-#include <boost/range/detail/remove_extent.hpp>
-#include <iterator>
-
-namespace boost 
-{
-    namespace range_detail
-    {
-        template< typename T >
-        struct range_size_;
-
-        //////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_size_<std_container_>
-        {
-            template< typename C >
-            struct inner {
-                static BOOST_RANGE_DEDUCED_TYPENAME C::size_type fun( const C& c )
-                {
-                    return c.size();
-                };
-            };
-        };
-                    
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-        
-        template<>
-        struct range_size_<std_pair_>
-        {
-            template< typename P >
-            struct inner {
-                static BOOST_RANGE_DEDUCED_TYPENAME range_size<P>::type 
-                fun( const P& p )
-                {
-                    return std::distance( p.first, p.second );
-                }
-            };
-        };
- 
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_size_<array_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun(T& t)
-                {
-                    return remove_extent<T>::size;
-                }
-            };
-        };
-        
-        template<>
-        struct range_size_<char_array_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun(T& t)
-                {
-                    return sizeof(T) / sizeof(T[0]);
-                }
-            };
-        };
-        
-        template<>
-        struct range_size_<wchar_t_array_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun(T& t)
-                {
-                    return sizeof(T) / sizeof(T[0]);
-                }
-            };
-        };
-
-        //////////////////////////////////////////////////////////////////////
-        // string
-        //////////////////////////////////////////////////////////////////////
-
-        template<>
-        struct range_size_<char_ptr_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun( const char* s )
-                {
-                    return boost::range_detail::str_size( s );
-                }
-            };
-        };
-
-        template<>
-        struct range_size_<const_char_ptr_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun( const char* s )
-                {
-                    return boost::range_detail::str_size( s );
-                }
-            };
-        };
-        
-        template<>
-        struct range_size_<wchar_t_ptr_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun( const wchar_t* s )
-                {
-                    return boost::range_detail::str_size( s );
-                }
-            };
-        };
-
-        template<>
-        struct range_size_<const_wchar_t_ptr_>
-        {
-            template<typename T>
-            struct inner {
-                static std::size_t fun( const wchar_t* s )
-                {
-                    return boost::range_detail::str_size( s );
-                }
-            };
-        };
-  
-    } // namespace 'range_detail'
-    
-
-    template< typename C >
-    BOOST_RANGE_DEDUCED_TYPENAME range_size<C>::type 
-    size( const C& c )
-    {
-        return range_detail::range_size_<range_detail::range<C>::type>::inner<C>::fun( c );
-    }
-    
-} // namespace 'boost'
-
-
-#endif
diff --git a/src/boost/range/difference_type.hpp b/src/boost/range/difference_type.hpp
deleted file mode 100644
index 164288f..0000000
--- a/src/boost/range/difference_type.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DIFFERENCE_TYPE_HPP
-#define BOOST_RANGE_DIFFERENCE_TYPE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_difference : iterator_difference< typename range_iterator<T>::type >
-    { };
-}
-
-#endif
diff --git a/src/boost/range/distance.hpp b/src/boost/range/distance.hpp
deleted file mode 100644
index 42a106d..0000000
--- a/src/boost/range/distance.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_DISTANCE_HPP
-#define BOOST_RANGE_DISTANCE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/difference_type.hpp>
-
-namespace boost 
-{
-
-    template< class T >
-    inline BOOST_DEDUCED_TYPENAME range_difference<T>::type 
-    distance( const T& r )
-    {
-        return std::distance( boost::begin( r ), boost::end( r ) );
-    }
-
-} // namespace 'boost'
-
-#endif
diff --git a/src/boost/range/empty.hpp b/src/boost/range/empty.hpp
deleted file mode 100644
index 78c4e85..0000000
--- a/src/boost/range/empty.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_EMPTY_HPP
-#define BOOST_RANGE_EMPTY_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-
-namespace boost 
-{ 
-
-    template< class T >
-    inline bool empty( const T& r )
-    {
-        return boost::begin( r ) == boost::end( r );
-    }
-
-} // namepace 'boost'
-
-
-#endif
diff --git a/src/boost/range/end.hpp b/src/boost/range/end.hpp
deleted file mode 100644
index d5e6526..0000000
--- a/src/boost/range/end.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_END_HPP
-#define BOOST_RANGE_END_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-#include <boost/range/detail/end.hpp>
-#else
-
-#include <boost/range/detail/implementation_help.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/const_iterator.hpp>
-
-namespace boost
-{
-
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-namespace range_detail
-{
-#endif
-
-        //////////////////////////////////////////////////////////////////////
-        // primary template
-        //////////////////////////////////////////////////////////////////////
-        template< typename C >
-        inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
-        range_end( C& c )
-        {
-            //
-            // If you get a compile-error here, it is most likely because
-            // you have not implemented range_begin() properly in
-            // the namespace of C
-            //
-            return c.end();
-        }
-
-        //////////////////////////////////////////////////////////////////////
-        // pair
-        //////////////////////////////////////////////////////////////////////
-
-        template< typename Iterator >
-        inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
-        {
-            return p.second;
-        }
-
-        template< typename Iterator >
-        inline Iterator range_end( std::pair<Iterator,Iterator>& p )
-        {
-            return p.second;
-        }
-
-        //////////////////////////////////////////////////////////////////////
-        // array
-        //////////////////////////////////////////////////////////////////////
-
-        template< typename T, std::size_t sz >
-        inline const T* range_end( const T (&a)[sz] )
-        {
-            return range_detail::array_end<T,sz>( a );
-        }
-
-        template< typename T, std::size_t sz >
-        inline T* range_end( T (&a)[sz] )
-        {
-            return range_detail::array_end<T,sz>( a );
-        }
-
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-} // namespace 'range_detail'
-#endif
-
-namespace range_adl_barrier
-{
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
-{
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-    using namespace range_detail;
-#endif
-    return range_end( r );
-}
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
-{
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-    using namespace range_detail;
-#endif
-    return range_end( r );
-}
-
-    } // namespace range_adl_barrier
-} // namespace 'boost'
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-namespace boost
-{
-    namespace range_adl_barrier
-    {
-        template< class T >
-        inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
-        const_end( const T& r )
-        {
-            return boost::range_adl_barrier::end( r );
-        }
-    } // namespace range_adl_barrier
-    using namespace range_adl_barrier;
-} // namespace boost
-
-#endif
-
diff --git a/src/boost/range/functions.hpp b/src/boost/range/functions.hpp
deleted file mode 100644
index b8b8608..0000000
--- a/src/boost/range/functions.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_FUNCTIONS_HPP
-#define BOOST_RANGE_FUNCTIONS_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/size.hpp>
-#include <boost/range/distance.hpp>
-#include <boost/range/empty.hpp>
-#include <boost/range/rbegin.hpp>
-#include <boost/range/rend.hpp>
-
-#endif
-
diff --git a/src/boost/range/has_range_iterator.hpp b/src/boost/range/has_range_iterator.hpp
deleted file mode 100644
index 8046eb4..0000000
--- a/src/boost/range/has_range_iterator.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
-#define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
-
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/has_xxx.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/utility/enable_if.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
-
-        template<class T, class Enabler = void>
-        struct has_range_iterator_impl
-            : boost::mpl::false_
-        {
-        };
-
-        template<class T>
-        struct has_range_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_mutable_iterator<T> > >::type>
-            : boost::mpl::true_
-        {
-        };
-
-        template<class T, class Enabler = void>
-        struct has_range_const_iterator_impl
-            : boost::mpl::false_
-        {
-        };
-
-        template<class T>
-        struct has_range_const_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_const_iterator<T> > >::type>
-            : boost::mpl::true_
-        {
-        };
-
-    } // namespace range_detail
-
-    template<class T>
-    struct has_range_iterator
-        : range_detail::has_range_iterator_impl<T>
-    {};
-
-    template<class T>
-    struct has_range_const_iterator
-        : range_detail::has_range_const_iterator_impl<T>
-    {};
-} // namespace boost
-
-#endif // include guard
-
diff --git a/src/boost/range/irange.hpp b/src/boost/range/irange.hpp
deleted file mode 100644
index 3b5a6cc..0000000
--- a/src/boost/range/irange.hpp
+++ /dev/null
@@ -1,230 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_IRANGE_HPP_INCLUDED
-#define BOOST_RANGE_IRANGE_HPP_INCLUDED
-
-#include <boost/assert.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        // integer_iterator is an iterator over an integer sequence that
-        // is bounded only by the limits of the underlying integer
-        // representation.
-        //
-        // This is useful for implementing the irange(first, last)
-        // function.
-        //
-        // Note:
-        // This use of this iterator and irange is appreciably less
-        // performant than the corresponding hand-written integer
-        // loop on many compilers.
-        template<typename Integer>
-        class integer_iterator
-            : public boost::iterator_facade<
-                        integer_iterator<Integer>,
-                        Integer,
-                        boost::random_access_traversal_tag,
-                        Integer,
-                        std::ptrdiff_t
-                    >
-        {
-            typedef boost::iterator_facade<
-                        integer_iterator<Integer>,
-                        Integer,
-                        boost::random_access_traversal_tag,
-                        Integer,
-                        std::ptrdiff_t
-                    > base_t;
-        public:
-            typedef typename base_t::value_type value_type;
-            typedef typename base_t::difference_type difference_type;
-            typedef typename base_t::reference reference;
-
-            integer_iterator() : m_value() {}
-            explicit integer_iterator(value_type x) : m_value(x) {}
-
-        private:
-            void increment()
-            {
-                ++m_value;
-            }
-
-            void decrement()
-            {
-                --m_value;
-            }
-
-            void advance(difference_type offset)
-            {
-                m_value += offset;
-            }
-
-            difference_type distance_to(const integer_iterator& other) const
-            {
-                return other.m_value - m_value;
-            }
-
-            bool equal(const integer_iterator& other) const
-            {
-                return m_value == other.m_value;
-            }
-
-            reference dereference() const
-            {
-                return m_value;
-            }
-
-            friend class ::boost::iterator_core_access;
-            value_type m_value;
-        };
-
-        // integer_iterator_with_step is similar in nature to the
-        // integer_iterator but provides the ability to 'move' in
-        // a number of steps specified at construction time.
-        //
-        // The three variable implementation provides the best guarantees
-        // of loop termination upon various combinations of input.
-        //
-        // While this design is less performant than some less
-        // safe alternatives, the use of ranges and iterators to
-        // perform counting will never be optimal anyhow, hence
-        // if optimal performance is desired a handcoded loop
-        // is the solution.
-        template<typename Integer>
-        class integer_iterator_with_step
-            : public boost::iterator_facade<
-                        integer_iterator_with_step<Integer>,
-                        Integer,
-                        boost::random_access_traversal_tag,
-                        Integer,
-                        std::ptrdiff_t
-                    >
-        {
-            typedef boost::iterator_facade<
-                        integer_iterator_with_step<Integer>,
-                        Integer,
-                        boost::random_access_traversal_tag,
-                        Integer,
-                        std::ptrdiff_t
-                    > base_t;
-        public:
-            typedef typename base_t::value_type value_type;
-            typedef typename base_t::difference_type difference_type;
-            typedef typename base_t::reference reference;
-
-            integer_iterator_with_step(value_type first, difference_type step, value_type step_size)
-                : m_first(first)
-                , m_step(step)
-                , m_step_size(step_size)
-            {
-            }
-
-        private:
-            void increment()
-            {
-                ++m_step;
-            }
-
-            void decrement()
-            {
-                --m_step;
-            }
-
-            void advance(difference_type offset)
-            {
-                m_step += offset;
-            }
-
-            difference_type distance_to(const integer_iterator_with_step& other) const
-            {
-                return other.m_step - m_step;
-            }
-
-            bool equal(const integer_iterator_with_step& other) const
-            {
-                return m_step == other.m_step;
-            }
-
-            reference dereference() const
-            {
-                return m_first + (m_step * m_step_size);
-            }
-
-            friend class ::boost::iterator_core_access;
-            value_type m_first;
-            value_type m_step;
-            difference_type m_step_size;
-        };
-
-    } // namespace range_detail
-
-    template<typename Integer>
-    class integer_range
-        : public iterator_range< range_detail::integer_iterator<Integer> >
-    {
-        typedef range_detail::integer_iterator<Integer> iterator_t;
-        typedef iterator_range<iterator_t> base_t;
-    public:
-        integer_range(Integer first, Integer last)
-            : base_t(iterator_t(first), iterator_t(last))
-        {
-        }
-    };
-
-    template<typename Integer>
-    class strided_integer_range
-    : public iterator_range< range_detail::integer_iterator_with_step<Integer> >
-    {
-        typedef range_detail::integer_iterator_with_step<Integer> iterator_t;
-        typedef iterator_range<iterator_t> base_t;
-    public:
-        template<typename Iterator>
-        strided_integer_range(Iterator first, Iterator last)
-            : base_t(first, last)
-        {
-        }
-    };
-
-    template<typename Integer>
-    integer_range<Integer>
-    irange(Integer first, Integer last)
-    {
-        BOOST_ASSERT( first <= last );
-        return integer_range<Integer>(first, last);
-    }
-
-    template<typename Integer, typename StepSize>
-    strided_integer_range<Integer>
-        irange(Integer first, Integer last, StepSize step_size)
-    {
-        BOOST_ASSERT( step_size != 0 );
-        BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
-        
-        typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
-
-        const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
-        const Integer l = step_size >= 0 ? last : first;
-        const Integer f = step_size >= 0 ? first : last;
-        const std::ptrdiff_t num_steps = (l + ((l-f) % sz) - f) / sz;
-        BOOST_ASSERT(num_steps >= 0);
-       
-        return strided_integer_range<Integer>(
-            iterator_t(first, 0, step_size),
-            iterator_t(first, num_steps, step_size));
-    }
-
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/istream_range.hpp b/src/boost/range/istream_range.hpp
deleted file mode 100644
index c3f2248..0000000
--- a/src/boost/range/istream_range.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//  Copyright Neil Groves 2010. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
-#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
-
-/*!
- * \file istream_range.hpp
- */
-
-#include <iterator>
-#include <istream>
-#include <boost/config.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace range
-    {
-        template<class Type, class Elem, class Traits> inline
-            iterator_range<std::istream_iterator<Type, Elem, Traits> >
-        istream_range(std::basic_istream<Elem, Traits>& in)
-        {
-            return iterator_range<std::istream_iterator<Type, Elem, Traits> >(
-                std::istream_iterator<Type>(in),
-                std::istream_iterator<Type>());
-        }
-    } // namespace range
-    using range::istream_range;
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/iterator.hpp b/src/boost/range/iterator.hpp
deleted file mode 100644
index ec73ddc..0000000
--- a/src/boost/range/iterator.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_ITERATOR_HPP
-#define BOOST_RANGE_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/mutable_iterator.hpp>
-#include <boost/range/const_iterator.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/mpl/eval_if.hpp>
-
-namespace boost
-{
-
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
-
-    namespace range_detail_vc7_1
-    {
-       template< typename C, typename Sig = void(C) >
-       struct range_iterator
-       {
-           typedef BOOST_RANGE_DEDUCED_TYPENAME
-               mpl::eval_if_c< is_const<C>::value,
-                               range_const_iterator< typename remove_const<C>::type >,
-                               range_mutable_iterator<C> >::type type;
-       };
-
-       template< typename C, typename T >
-       struct range_iterator< C, void(T[]) >
-       {
-           typedef T* type;
-       };
-    }
-
-#endif
-
-    template< typename C >
-    struct range_iterator
-    {
-#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
-
-        typedef BOOST_RANGE_DEDUCED_TYPENAME
-               range_detail_vc7_1::range_iterator<C>::type type;
-
-#else
-
-        typedef BOOST_RANGE_DEDUCED_TYPENAME
-            mpl::eval_if_c< is_const<C>::value,
-                            range_const_iterator< typename remove_const<C>::type >,
-                            range_mutable_iterator<C> >::type type;
-
-#endif
-    };
-
-} // namespace boost
-
-//#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-#endif
diff --git a/src/boost/range/iterator_range.hpp b/src/boost/range/iterator_range.hpp
deleted file mode 100644
index dfcd4d2..0000000
--- a/src/boost/range/iterator_range.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
-#define BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
-
-#include "boost/range/iterator_range_core.hpp"
-#include "boost/range/iterator_range_io.hpp"
-
-#endif // include guard
diff --git a/src/boost/range/iterator_range_core.hpp b/src/boost/range/iterator_range_core.hpp
deleted file mode 100644
index 60c7670..0000000
--- a/src/boost/range/iterator_range_core.hpp
+++ /dev/null
@@ -1,650 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
-#define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
-
-#include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
-#include <boost/detail/workaround.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
-    #pragma warning( push )
-    #pragma warning( disable : 4996 )
-#endif
-
-#include <boost/assert.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/type_traits/is_abstract.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/range/functions.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/algorithm/equal.hpp>
-#include <boost/range/detail/safe_bool.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <iterator>
-#include <algorithm>
-#include <cstddef>
-
-/*! \file
-    Defines the \c iterator_class and related functions.
-    \c iterator_range is a simple wrapper of iterator pair idiom. It provides
-    a rich subset of Container interface.
-*/
-
-
-namespace boost
-{
-    namespace iterator_range_detail
-    {
-        //
-        // The functions adl_begin and adl_end are implemented in a separate
-        // class for gcc-2.9x
-        //
-        template<class IteratorT>
-        struct iterator_range_impl {
-            template< class ForwardRange >
-            static IteratorT adl_begin( ForwardRange& r )
-            {
-                return static_cast<IteratorT>( boost::begin( r ) );
-            }
-
-            template< class ForwardRange >
-            static IteratorT adl_end( ForwardRange& r )
-            {
-                return static_cast<IteratorT>( boost::end( r ) );
-            }
-        };
-
-        template< class Left, class Right >
-        inline bool less_than( const Left& l, const Right& r )
-        {
-            return std::lexicographical_compare( boost::begin(l),
-                                                 boost::end(l),
-                                                 boost::begin(r),
-                                                 boost::end(r) );
-        }
-        
-        template< class Left, class Right >
-        inline bool greater_than( const Left& l, const Right& r )
-        {
-            return less_than(r,l);
-        }
-        
-        template< class Left, class Right >
-        inline bool less_or_equal_than( const Left& l, const Right& r )
-        {
-            return !iterator_range_detail::less_than(r,l);
-        }
-        
-        template< class Left, class Right >
-        inline bool greater_or_equal_than( const Left& l, const Right& r )
-        {
-            return !iterator_range_detail::less_than(l,r);
-        }
-
-        // This version is maintained since it is used in other boost libraries
-        // such as Boost.Assign
-        template< class Left, class Right >
-        inline bool equal(const Left& l, const Right& r)
-        {
-            return boost::equal(l, r);
-        }
-
-        struct range_tag { };
-        struct const_range_tag { };
-    }
-
-//  iterator range template class -----------------------------------------//
-
-        //! iterator_range class
-        /*!
-            An \c iterator_range delimits a range in a sequence by beginning and ending iterators.
-            An iterator_range can be passed to an algorithm which requires a sequence as an input.
-            For example, the \c toupper() function may be used most frequently on strings,
-            but can also be used on iterator_ranges:
-
-            \code
-                boost::tolower( find( s, "UPPERCASE STRING" ) );
-            \endcode
-
-            Many algorithms working with sequences take a pair of iterators,
-            delimiting a working range, as an arguments. The \c iterator_range class is an
-            encapsulation of a range identified by a pair of iterators.
-            It provides a collection interface,
-            so it is possible to pass an instance to an algorithm requiring a collection as an input.
-        */
-        template<class IteratorT>
-        class iterator_range
-        {
-            typedef range_detail::safe_bool< IteratorT iterator_range<IteratorT>::* > safe_bool_t;
-        protected: // Used by sub_range
-            //! implementation class
-            typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
-        public:
-            //! this type
-            typedef iterator_range<IteratorT> type;
-            typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type;
-            //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
-
-            //! Encapsulated value type
-            typedef BOOST_DEDUCED_TYPENAME
-                iterator_value<IteratorT>::type value_type;
-
-            //! Difference type
-            typedef BOOST_DEDUCED_TYPENAME
-                iterator_difference<IteratorT>::type difference_type;
-
-            //! Size type
-            typedef std::size_t size_type; // note: must be unsigned
-
-            //! This type
-            typedef iterator_range<IteratorT> this_type;
-
-            //! Reference type
-            //
-            // Needed because value-type is the same for
-            // const and non-const iterators
-            //
-            typedef BOOST_DEDUCED_TYPENAME
-                iterator_reference<IteratorT>::type reference;
-
-            //! const_iterator type
-            /*!
-                There is no distinction between const_iterator and iterator.
-                These typedefs are provides to fulfill container interface
-            */
-            typedef IteratorT const_iterator;
-            //! iterator type
-            typedef IteratorT iterator;
-
-        private: // for return value of operator()()
-            typedef BOOST_DEDUCED_TYPENAME
-                boost::mpl::if_< boost::is_abstract<value_type>,
-                                 reference, value_type >::type abstract_value_type;
-
-        public:
-            iterator_range() : m_Begin( iterator() ), m_End( iterator() )
-            { }
-
-            //! Constructor from a pair of iterators
-            template< class Iterator >
-            iterator_range( Iterator Begin, Iterator End ) :
-                m_Begin(Begin), m_End(End)
-            {}
-
-            //! Constructor from a Range
-            template< class Range >
-            iterator_range( const Range& r ) :
-                m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
-            {}
-
-            //! Constructor from a Range
-            template< class Range >
-            iterator_range( Range& r ) :
-                m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
-            {}
-
-            //! Constructor from a Range
-            template< class Range >
-            iterator_range( const Range& r, iterator_range_detail::const_range_tag ) :
-                m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
-            {}
-
-            //! Constructor from a Range
-            template< class Range >
-            iterator_range( Range& r, iterator_range_detail::range_tag ) :
-                m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
-            {}
-
-            #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
-            this_type& operator=( const this_type& r )
-            {
-                m_Begin  = r.begin();
-                m_End    = r.end();
-                return *this;
-            }
-            #endif
-
-            template< class Iterator >
-            iterator_range& operator=( const iterator_range<Iterator>& r )
-            {
-                m_Begin  = r.begin();
-                m_End    = r.end();
-                return *this;
-            }
-
-            template< class ForwardRange >
-            iterator_range& operator=( ForwardRange& r )
-            {
-                m_Begin  = impl::adl_begin( r );
-                m_End    = impl::adl_end( r );
-                return *this;
-            }
-
-            template< class ForwardRange >
-            iterator_range& operator=( const ForwardRange& r )
-            {
-                m_Begin  = impl::adl_begin( r );
-                m_End    = impl::adl_end( r );
-                return *this;
-            }
-
-            IteratorT begin() const
-            {
-                return m_Begin;
-            }
-
-            IteratorT end() const
-            {
-                return m_End;
-            }
-
-            difference_type size() const
-            {
-                return m_End - m_Begin;
-            }
-
-            bool empty() const
-            {
-                return m_Begin == m_End;
-            }
-
-            operator unspecified_bool_type() const
-            {
-                return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin);
-            }
-
-            bool operator!() const
-            {
-                return empty();
-            }
-
-            bool equal( const iterator_range& r ) const
-            {
-                return m_Begin == r.m_Begin && m_End == r.m_End;
-            }
-
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-            bool operator==( const iterator_range& r ) const
-            {
-                return boost::equal( *this, r );
-            }
-
-            bool operator!=( const iterator_range& r ) const
-            {
-                return !operator==(r);
-            }
-
-           bool operator<( const iterator_range& r ) const
-           {
-               return iterator_range_detail::less_than( *this, r );
-           }
-           
-           bool operator>( const iterator_range& r ) const
-           {
-               return iterator_range_detail::greater_than( *this, r );
-           }
-           
-           bool operator<=( const iterator_range& r ) const
-           {
-               return iterator_range_detail::less_or_equal_than( *this, r );
-           }
-           
-           bool operator>=( const iterator_range& r ) const
-           {
-               return iterator_range_detail::greater_or_equal_than( *this, r );
-           }
-
-#endif
-
-        public: // convenience
-           reference front() const
-           {
-               BOOST_ASSERT( !empty() );
-               return *m_Begin;
-           }
-
-           reference back() const
-           {
-               BOOST_ASSERT( !empty() );
-               IteratorT last( m_End );
-               return *--last;
-           }
-
-           // pop_front() - added to model the SinglePassRangePrimitiveConcept
-           void pop_front()
-           {
-               BOOST_ASSERT( !empty() );
-               ++m_Begin;
-           }
-
-           // pop_back() - added to model the BidirectionalRangePrimitiveConcept
-           void pop_back()
-           {
-               BOOST_ASSERT( !empty() );
-               --m_End;
-           }
-
-           reference operator[]( difference_type at ) const
-           {
-               BOOST_ASSERT( at >= 0 && at < size() );
-               return m_Begin[at];
-           }
-
-           //
-           // When storing transform iterators, operator[]()
-           // fails because it returns by reference. Therefore
-           // operator()() is provided for these cases.
-           //
-           abstract_value_type operator()( difference_type at ) const
-           {
-               BOOST_ASSERT( at >= 0 && at < size() );
-               return m_Begin[at];
-           }
-
-           iterator_range& advance_begin( difference_type n )
-           {
-               std::advance( m_Begin, n );
-               return *this;
-           }
-
-           iterator_range& advance_end( difference_type n )
-           {
-               std::advance( m_End, n );
-               return *this;
-           }
-
-        private:
-            // begin and end iterators
-            IteratorT m_Begin;
-            IteratorT m_End;
-
-        protected:
-            //
-            // Allow subclasses an easy way to access the
-            // base type
-            //
-            typedef iterator_range iterator_range_;
-        };
-
-//  iterator range free-standing operators ---------------------------//
-
-        /////////////////////////////////////////////////////////////////////
-        // comparison operators
-        /////////////////////////////////////////////////////////////////////
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator==( const ForwardRange& l,
-                                const iterator_range<IteratorT>& r )
-        {
-            return boost::equal( l, r );
-        }
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator!=( const ForwardRange& l,
-                                const iterator_range<IteratorT>& r )
-        {
-            return !boost::equal( l, r );
-        }
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator<( const ForwardRange& l,
-                               const iterator_range<IteratorT>& r )
-        {
-            return iterator_range_detail::less_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator<=( const ForwardRange& l,
-                                const iterator_range<IteratorT>& r )
-        {
-            return iterator_range_detail::less_or_equal_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator>( const ForwardRange& l,
-                               const iterator_range<IteratorT>& r )
-        {
-            return iterator_range_detail::greater_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator>=( const ForwardRange& l,
-                                const iterator_range<IteratorT>& r )
-        {
-            return iterator_range_detail::greater_or_equal_than( l, r );
-        }
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-#else
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator==( const iterator_range<Iterator1T>& l,
-                                const iterator_range<Iterator2T>& r )
-        {
-            return boost::equal( l, r );
-        }
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator==( const iterator_range<IteratorT>& l,
-                                const ForwardRange& r )
-        {
-            return boost::equal( l, r );
-        }
-
-
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator!=( const iterator_range<Iterator1T>& l,
-                                const iterator_range<Iterator2T>& r )
-        {
-            return !boost::equal( l, r );
-        }
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator!=( const iterator_range<IteratorT>& l,
-                                const ForwardRange& r )
-        {
-            return !boost::equal( l, r );
-        }
-
-
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator<( const iterator_range<Iterator1T>& l,
-                               const iterator_range<Iterator2T>& r )
-        {
-            return iterator_range_detail::less_than( l, r );
-        }
-
-        template< class IteratorT, class ForwardRange >
-        inline bool operator<( const iterator_range<IteratorT>& l,
-                               const ForwardRange& r )
-        {
-            return iterator_range_detail::less_than( l, r );
-        }
-        
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator<=( const iterator_range<Iterator1T>& l,
-                                const iterator_range<Iterator2T>& r )
-        {
-            return iterator_range_detail::less_or_equal_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator<=( const iterator_range<IteratorT>& l,
-                                const ForwardRange& r )
-        {
-            return iterator_range_detail::less_or_equal_than( l, r );
-        }
-        
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator>( const iterator_range<Iterator1T>& l,
-                               const iterator_range<Iterator2T>& r )
-        {
-            return iterator_range_detail::greater_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator>( const iterator_range<IteratorT>& l,
-                               const ForwardRange& r )
-        {
-            return iterator_range_detail::greater_than( l, r );
-        }
-        
-        template< class Iterator1T, class Iterator2T >
-        inline bool operator>=( const iterator_range<Iterator1T>& l,
-                                const iterator_range<Iterator2T>& r )
-        {
-            return iterator_range_detail::greater_or_equal_than( l, r );
-        }
-        
-        template< class IteratorT, class ForwardRange >
-        inline bool operator>=( const iterator_range<IteratorT>& l,
-                                const ForwardRange& r )
-        {
-            return iterator_range_detail::greater_or_equal_than( l, r );
-        }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-//  iterator range utilities -----------------------------------------//
-
-        //! iterator_range construct helper
-        /*!
-            Construct an \c iterator_range from a pair of iterators
-
-            \param Begin A begin iterator
-            \param End An end iterator
-            \return iterator_range object
-        */
-        template< typename IteratorT >
-        inline iterator_range< IteratorT >
-        make_iterator_range( IteratorT Begin, IteratorT End )
-        {
-            return iterator_range<IteratorT>( Begin, End );
-        }
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        template< typename Range >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
-        make_iterator_range( Range& r )
-        {
-            return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
-                ( boost::begin( r ), boost::end( r ) );
-        }
-
-#else
-        //! iterator_range construct helper
-        /*!
-            Construct an \c iterator_range from a \c Range containing the begin
-            and end iterators.
-        */
-        template< class ForwardRange >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
-        make_iterator_range( ForwardRange& r )
-        {
-           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
-                ( r, iterator_range_detail::range_tag() );
-        }
-
-        template< class ForwardRange >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
-        make_iterator_range( const ForwardRange& r )
-        {
-           return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
-                ( r, iterator_range_detail::const_range_tag() );
-        }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        namespace iterator_range_detail
-        {
-            template< class Range >
-            inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
-            make_range_impl( Range& r,
-                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
-                             BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
-            {
-                //
-                // Not worth the effort
-                //
-                //if( advance_begin == 0 && advance_end == 0 )
-                //    return make_iterator_range( r );
-                //
-
-                BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
-                    new_begin = boost::begin( r ),
-                    new_end   = boost::end( r );
-                std::advance( new_begin, advance_begin );
-                std::advance( new_end, advance_end );
-                return make_iterator_range( new_begin, new_end );
-            }
-        }
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        template< class Range >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
-        make_iterator_range( Range& r,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
-        {
-            //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
-            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
-        }
-
-#else
-
-        template< class Range >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
-        make_iterator_range( Range& r,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
-        {
-            //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
-            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
-        }
-
-        template< class Range >
-        inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
-        make_iterator_range( const Range& r,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
-                    BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
-        {
-            //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
-            return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
-        }
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-        //! copy a range into a sequence
-        /*!
-            Construct a new sequence of the specified type from the elements
-            in the given range
-
-            \param Range An input range
-            \return New sequence
-        */
-        template< typename SeqT, typename Range >
-        inline SeqT copy_range( const Range& r )
-        {
-            return SeqT( boost::begin( r ), boost::end( r ) );
-        }
-
-} // namespace 'boost'
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
-    #pragma warning( pop )
-#endif
-
-#endif
-
diff --git a/src/boost/range/iterator_range_io.hpp b/src/boost/range/iterator_range_io.hpp
deleted file mode 100644
index 51e3a4f..0000000
--- a/src/boost/range/iterator_range_io.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009.
-//  Use, modification and distribution is subject to the Boost Software
-//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
-#define BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
-    #pragma warning( push )
-    #pragma warning( disable : 4996 )
-#endif
-
-// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for Cray X1 patch.
-#ifndef BOOST_OLD_IOSTREAMS 
-# if defined(__STL_CONFIG_H) && \
-    !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \
-    /**/
-#  define BOOST_OLD_IOSTREAMS
-# endif
-#endif // #ifndef BOOST_OLD_IOSTREAMS
-
-#ifndef _STLP_NO_IOSTREAMS
-# ifndef BOOST_OLD_IOSTREAMS
-#  include <ostream>
-# else
-#  include <ostream.h>
-# endif
-#endif // _STLP_NO_IOSTREAMS
-
-#include <boost/range/iterator_range_core.hpp>
-#include <iterator>
-#include <algorithm>
-#include <cstddef>
-
-namespace boost
-{
-
-#ifndef _STLP_NO_IOSTREAMS
-# ifndef BOOST_OLD_IOSTREAMS   
-
-        //! iterator_range output operator
-        /*!
-            Output the range to an ostream. Elements are outputed
-            in a sequence without separators.
-        */
-        template< typename IteratorT, typename Elem, typename Traits >
-        inline std::basic_ostream<Elem,Traits>& operator<<( 
-                    std::basic_ostream<Elem, Traits>& Os,
-                    const iterator_range<IteratorT>& r )
-        {
-            std::copy( r.begin(), r.end(), 
-                       std::ostream_iterator< BOOST_DEDUCED_TYPENAME 
-                                              iterator_value<IteratorT>::type, 
-                                              Elem, Traits>(Os) );
-            return Os;
-        }
-
-# else
-
-        //! iterator_range output operator
-        /*!
-            Output the range to an ostream. Elements are outputed
-            in a sequence without separators.
-        */
-        template< typename IteratorT >
-        inline std::ostream& operator<<( 
-                    std::ostream& Os,
-                    const iterator_range<IteratorT>& r )
-        {
-            std::copy( r.begin(), r.end(), std::ostream_iterator<char>(Os));
-            return Os;
-        }
-
-# endif
-#endif // _STLP_NO_IOSTREAMS
-
-} // namespace boost
-
-#undef BOOST_OLD_IOSTREAMS
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
-    #pragma warning(pop)
-#endif
-
-#endif // include guard
diff --git a/src/boost/range/join.hpp b/src/boost/range/join.hpp
deleted file mode 100644
index aacc0a3..0000000
--- a/src/boost/range/join.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-#ifndef BOOST_RANGE_JOIN_HPP_INCLUDED
-#define BOOST_RANGE_JOIN_HPP_INCLUDED
-
-#include <boost/config.hpp>
-#include <boost/range/detail/join_iterator.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/iterator_range.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-
-template<class SinglePassRange1, class SinglePassRange2>
-class joined_type
-{
-public:
-    typedef iterator_range<
-        range_detail::join_iterator<
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-            BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
-            BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
-        >
-    > type;
-};
-
-    } // namespace range_detail
-
-namespace range
-{
-
-template<class SinglePassRange1, class SinglePassRange2>
-class joined_range
-    : public range_detail::joined_type<SinglePassRange1, SinglePassRange2>::type
-{
-    typedef range_detail::join_iterator<
-        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
-        BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
-        BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
-        > iterator_t;
-
-    typedef BOOST_DEDUCED_TYPENAME range_detail::joined_type<
-                    SinglePassRange1, SinglePassRange2>::type base_t;
-public:
-    joined_range(SinglePassRange1& rng1, SinglePassRange2& rng2)
-        : base_t(
-            iterator_t(rng1, rng2, range_detail::join_iterator_begin_tag()),
-            iterator_t(rng1, rng2, range_detail::join_iterator_end_tag())
-        )
-    {
-    }
-};
-
-template<class SinglePassRange1, class SinglePassRange2>
-joined_range<const SinglePassRange1, const SinglePassRange2>
-join(const SinglePassRange1& r1, const SinglePassRange2& r2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return joined_range<const SinglePassRange1, const SinglePassRange2>(r1, r2);
-}
-
-template<class SinglePassRange1, class SinglePassRange2>
-joined_range<SinglePassRange1, SinglePassRange2>
-join(SinglePassRange1& r1, SinglePassRange2& r2)
-{
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
-    BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
-
-    return joined_range<SinglePassRange1, SinglePassRange2>(r1, r2);
-}
-
-} // namespace range
-
-using ::boost::range::joined_range;
-using ::boost::range::join;
-
-} // namespace boost
-
-#endif // include guard
diff --git a/src/boost/range/metafunctions.hpp b/src/boost/range/metafunctions.hpp
deleted file mode 100644
index 469d9ae..0000000
--- a/src/boost/range/metafunctions.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_METAFUNCTIONS_HPP
-#define BOOST_RANGE_METAFUNCTIONS_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/iterator.hpp>
-#include <boost/range/has_range_iterator.hpp>
-#include <boost/range/result_iterator.hpp>
-#include <boost/range/reverse_iterator.hpp>
-#include <boost/range/const_reverse_iterator.hpp>
-#include <boost/range/reverse_result_iterator.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/category.hpp>
-#include <boost/range/reference.hpp>
-#include <boost/range/pointer.hpp>
-
-#endif
diff --git a/src/boost/range/mfc.hpp b/src/boost/range/mfc.hpp
deleted file mode 100644
index 058e54e..0000000
--- a/src/boost/range/mfc.hpp
+++ /dev/null
@@ -1,984 +0,0 @@
-#ifndef BOOST_RANGE_MFC_HPP
-#define BOOST_RANGE_MFC_HPP
-
-
-
-
-// Boost.Range MFC Extension
-//
-// Copyright Shunsuke Sogame 2005-2006.
-// Distributed under the Boost Software License, Version 1.0. 
-// (See accompanying file LICENSE_1_0.txt or copy at 
-// http://www.boost.org/LICENSE_1_0.txt)
-
-
-
-
-// config
-//
-
-
-#include <afx.h> // _MFC_VER
-
-
-#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-    #if (_MFC_VER < 0x0700) // dubious
-        #define BOOST_RANGE_MFC_NO_CPAIR
-    #endif
-#endif
-
-
-#if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
-    #if (_MFC_VER < 0x0700) // dubious
-        #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
-    #endif
-#endif
-
-
-// A const collection of old MFC doesn't return const reference.
-//
-#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
-    #if (_MFC_VER < 0x0700) // dubious
-        #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
-    #endif
-#endif
-
-
-
-
-// forward declarations
-//
-
-
-template< class Type, class ArgType >
-class CArray;
-
-template< class Type, class ArgType >
-class CList;
-
-template< class Key, class ArgKey, class Mapped, class ArgMapped >
-class CMap;
-
-template< class BaseClass, class PtrType >
-class CTypedPtrArray;
-
-template< class BaseClass, class PtrType >
-class CTypedPtrList;
-
-template< class BaseClass, class KeyPtrType, class MappedPtrType >
-class CTypedPtrMap;
-
-
-
-
-// extended customizations
-//
-
-
-#include <cstddef> // ptrdiff_t
-#include <utility> // pair
-#include <boost/assert.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/range/atl.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/const_iterator.hpp>
-#include <boost/range/detail/microsoft.hpp>
-#include <boost/range/end.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/iterator/iterator_categories.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/iterator/transform_iterator.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/remove_pointer.hpp>
-#include <boost/utility/addressof.hpp>
-#include <afx.h> // legacy CString
-#include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
-#include <tchar.h>
-
-
-namespace boost { namespace range_detail_microsoft {
-
-
-    // mfc_ptr_array_iterator
-    //
-    // 'void **' is not convertible to 'void const **',
-    // so we define...
-    //
-
-    template< class ArrayT, class PtrType >
-    struct mfc_ptr_array_iterator;
-
-    template< class ArrayT, class PtrType >
-    struct mfc_ptr_array_iterator_super
-    {
-        typedef iterator_adaptor<
-            mfc_ptr_array_iterator<ArrayT, PtrType>,
-            std::ptrdiff_t, // Base!
-            PtrType,        // Value
-            random_access_traversal_tag,
-            use_default,
-            std::ptrdiff_t  // Difference
-        > type;
-    };
-
-    template< class ArrayT, class PtrType >
-    struct mfc_ptr_array_iterator :
-        mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
-    {
-    private:
-        typedef mfc_ptr_array_iterator self_t;
-        typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
-        typedef typename super_t::reference ref_t;
-
-    public:
-        explicit mfc_ptr_array_iterator()
-        { }
-
-        explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
-            super_t(index), m_parr(boost::addressof(arr))
-        { }
-
-    template< class, class > friend struct mfc_ptr_array_iterator;
-        template< class ArrayT_, class PtrType_ >
-        mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
-            super_t(other.base()), m_parr(other.m_parr)
-        { }
-
-    private:
-        ArrayT *m_parr;
-
-    friend class iterator_core_access;
-        ref_t dereference() const
-        {
-            BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
-            return *( m_parr->GetData() + this->base() );
-        }
-
-        bool equal(self_t const& other) const
-        {
-            BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
-            return this->base() == other.base();
-        }
-    };
-
-    struct mfc_ptr_array_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return Iterator(x, 0);
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(x, x.GetSize());
-        }
-    };
-
-
-    // arrays
-    //
-
-    template< >
-    struct customization< ::CByteArray > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef BYTE val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CDWordArray > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef DWORD val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CObArray > :
-        mfc_ptr_array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
-            typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CPtrArray > :
-        mfc_ptr_array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
-            typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CStringArray > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ::CString val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CUIntArray > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef UINT val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CWordArray > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef WORD val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    // lists
-    //
-
-    template< >
-    struct customization< ::CObList > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef list_iterator<X, ::CObject *> mutable_iterator;
-    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
-            typedef list_iterator<X const, ::CObject const *> const_iterator;
-    #else
-            typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
-    #endif
-        };
-    };
-
-
-    template< >
-    struct customization< ::CPtrList > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef list_iterator<X, void *> mutable_iterator;
-    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
-            typedef list_iterator<X const, void const *> const_iterator;
-    #else
-            typedef list_iterator<X const, void const * const, void const * const> const_iterator;
-    #endif
-        };
-    };
-
-
-    template< >
-    struct customization< ::CStringList > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ::CString val_t;
-
-            typedef list_iterator<X, val_t> mutable_iterator;
-    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
-            typedef list_iterator<X const, val_t const> const_iterator;
-    #else
-            typedef list_iterator<X const, val_t const, val_t const> const_iterator;
-    #endif
-        };
-    };
-
-
-    // mfc_map_iterator
-    //
-
-    template< class MapT, class KeyT, class MappedT >
-    struct mfc_map_iterator;
-
-    template< class MapT, class KeyT, class MappedT >
-    struct mfc_map_iterator_super
-    {
-        typedef iterator_facade<
-            mfc_map_iterator<MapT, KeyT, MappedT>,
-            std::pair<KeyT, MappedT>,
-            forward_traversal_tag,
-            std::pair<KeyT, MappedT> const
-        > type;
-    };
-
-    template< class MapT, class KeyT, class MappedT >
-    struct mfc_map_iterator :
-        mfc_map_iterator_super<MapT, KeyT, MappedT>::type
-    {
-    private:
-        typedef mfc_map_iterator self_t;
-        typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
-        typedef typename super_t::reference ref_t;
-
-    public:
-        explicit mfc_map_iterator()
-        { }
-
-        explicit mfc_map_iterator(MapT const& map, POSITION pos) :
-            m_pmap(boost::addressof(map)), m_posNext(pos)
-        {
-            increment();
-        }
-
-        explicit mfc_map_iterator(MapT const& map) :
-            m_pmap(&map), m_pos(0) // end iterator
-        { }
-
-    template< class, class, class > friend struct mfc_map_iterator;
-        template< class MapT_, class KeyT_, class MappedT_>
-        mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
-            m_pmap(other.m_pmap),
-            m_pos(other.m_pos), m_posNext(other.m_posNext),
-            m_key(other.m_key), m_mapped(other.m_mapped)
-        { }
-
-    private:
-        MapT const *m_pmap;
-        POSITION m_pos, m_posNext;
-        KeyT m_key; MappedT m_mapped;
-
-    friend class iterator_core_access;
-        ref_t dereference() const
-        {
-            BOOST_ASSERT(m_pos != 0 && "out of range");
-            return std::make_pair(m_key, m_mapped);
-        }
-
-        void increment()
-        {
-            BOOST_ASSERT(m_pos != 0 && "out of range");
-
-            if (m_posNext == 0) {
-                m_pos = 0;
-                return;
-            }
-
-            m_pos = m_posNext;
-            m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
-        }
-
-        bool equal(self_t const& other) const
-        {
-            BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
-            return m_pos == other.m_pos;
-        }
-    };
-
-    struct mfc_map_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return Iterator(x, x.GetStartPosition());
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(x);
-        }
-    };
-
-
-#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-
-
-    // mfc_cpair_map_iterator
-    //
-    // used by ::CMap and ::CMapStringToString
-    //
-
-    template< class MapT, class PairT >
-    struct mfc_cpair_map_iterator;
-
-    template< class MapT, class PairT >
-    struct mfc_pget_map_iterator_super
-    {
-        typedef iterator_facade<
-            mfc_cpair_map_iterator<MapT, PairT>,
-            PairT,
-            forward_traversal_tag
-        > type;
-    };
-
-    template< class MapT, class PairT >
-    struct mfc_cpair_map_iterator :
-        mfc_pget_map_iterator_super<MapT, PairT>::type
-    {
-    private:
-        typedef mfc_cpair_map_iterator self_t;
-        typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
-        typedef typename super_t::reference ref_t;
-
-    public:
-        explicit mfc_cpair_map_iterator()
-        { }
-
-        explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
-            m_pmap(boost::addressof(map)), m_pp(pp)
-        { }
-
-    template< class, class > friend struct mfc_cpair_map_iterator;
-        template< class MapT_, class PairT_>
-        mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
-            m_pmap(other.m_pmap), m_pp(other.m_pp)
-        { }
-
-    private:
-        MapT  *m_pmap;
-        PairT *m_pp;
-
-    friend class iterator_core_access;
-        ref_t dereference() const
-        {
-            BOOST_ASSERT(m_pp != 0 && "out of range");
-            return *m_pp;
-        }
-
-        void increment()
-        {
-            BOOST_ASSERT(m_pp != 0 && "out of range");
-            m_pp = m_pmap->PGetNextAssoc(m_pp);
-        }
-
-        bool equal(self_t const& other) const
-        {
-            BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
-            return m_pp == other.m_pp;
-        }
-    };
-
-    struct mfc_cpair_map_functions
-    {
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            // Workaround:
-            // Assertion fails if empty.
-            // MFC document is wrong.
-    #if !defined(NDEBUG)
-            if (x.GetCount() == 0) 
-                return Iterator(x, 0);
-    #endif
-
-            return Iterator(x, x.PGetFirstAssoc());
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(x, 0);
-        }
-    };
-
-
-#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
-
-
-    // maps
-    //
-
-    template< >
-    struct customization< ::CMapPtrToWord > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef void *key_t;
-            typedef WORD mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapPtrToPtr > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef void *key_t;
-            typedef void *mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapStringToOb > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ::CString key_t;
-            typedef ::CObject *mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapStringToPtr > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef ::CString key_t;
-            typedef void *mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapStringToString > :
-    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-        mfc_cpair_map_functions
-    #else
-        mfc_map_functions
-    #endif
-    {
-        template< class X >
-        struct meta
-        {
-    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-            typedef typename X::CPair pair_t;
-
-            typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
-            typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
-    #else
-            typedef ::CString key_t;
-            typedef ::CString mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-    #endif
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapWordToOb > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef WORD key_t;
-            typedef ::CObject *mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    template< >
-    struct customization< ::CMapWordToPtr > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef WORD key_t;
-            typedef void *mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    // templates
-    //
-
-    template< class Type, class ArgType >
-    struct customization< ::CArray<Type, ArgType> > :
-        array_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef Type val_t;
-
-            typedef val_t *mutable_iterator;
-            typedef val_t const *const_iterator;
-        };
-    };
-
-
-    template< class Type, class ArgType >
-    struct customization< ::CList<Type, ArgType> > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef Type val_t;
-
-            typedef list_iterator<X, val_t> mutable_iterator;
-    #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
-            typedef list_iterator<X const, val_t const> const_iterator;
-    #else
-            typedef list_iterator<X const, val_t const, val_t const> const_iterator;
-    #endif
-        };
-    };
-
-
-    template< class Key, class ArgKey, class Mapped, class ArgMapped >
-    struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
-    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-        mfc_cpair_map_functions
-    #else
-        mfc_map_functions
-    #endif
-    {
-        template< class X >
-        struct meta
-        {
-    #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
-            typedef typename X::CPair pair_t;
-
-            typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
-            typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
-    #else
-            typedef Key key_t;
-            typedef Mapped mapped_t;
-
-            typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-    #endif            
-        };
-    };
-
-
-    template< class BaseClass, class PtrType >
-    struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
-    {
-        template< class X >
-        struct fun
-        {
-            typedef typename remove_pointer<PtrType>::type val_t;
-
-            typedef typename mpl::if_< is_const<X>,
-                val_t const,
-                val_t
-            >::type val_t_;
-
-            typedef val_t_ * const result_type;
-
-            template< class PtrType_ >
-            result_type operator()(PtrType_ p) const
-            {
-                return static_cast<result_type>(p);
-            }
-        };
-
-        template< class X >
-        struct meta
-        {
-            typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
-            typedef typename range_const_iterator<BaseClass>::type citer_t;
-
-            typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
-            typedef transform_iterator<fun<X const>, citer_t> const_iterator;
-        };
-
-        template< class Iterator, class X >
-        Iterator begin(X& x)
-        {
-            return Iterator(boost::begin<BaseClass>(x), fun<X>());
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return Iterator(boost::end<BaseClass>(x), fun<X>());
-        }
-    };
-
-
-    template< class BaseClass, class PtrType >
-    struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
-        list_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef typename remove_pointer<PtrType>::type val_t;
-
-            // not l-value
-            typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
-            typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
-        };
-    };
-
-
-    template< class BaseClass, class KeyPtrType, class MappedPtrType >
-    struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
-        mfc_map_functions
-    {
-        template< class X >
-        struct meta
-        {
-            typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
-            typedef mutable_iterator const_iterator;
-        };
-    };
-
-
-    // strings
-    //
-
-#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
-
-    template< >
-    struct customization< ::CString >
-    {
-        template< class X >
-        struct meta
-        {
-            // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
-            typedef TCHAR *mutable_iterator;
-            typedef TCHAR const *const_iterator;
-        };
-
-        template< class Iterator, class X >
-        typename mutable_<Iterator, X>::type begin(X& x)
-        {
-            return x.GetBuffer(0);
-        }
-
-        template< class Iterator, class X >
-        Iterator begin(X const& x)
-        {
-            return x;
-        }
-
-        template< class Iterator, class X >
-        Iterator end(X& x)
-        {
-            return begin<Iterator>(x) + x.GetLength();
-        }
-    };
-
-#endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
-
-
-} } // namespace boost::range_detail_microsoft
-
-
-
-
-// range customizations
-//
-
-
-// arrays
-//
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CByteArray
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CDWordArray
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CStringArray
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CUIntArray
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CWordArray
-)
-
-
-// lists
-//
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CObList
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CPtrList
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CStringList
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CObArray
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CPtrArray
-)
-
-
-// maps
-//
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapPtrToWord
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapPtrToPtr
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapStringToOb
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapStringToPtr
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapStringToString
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapWordToOb
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMapWordToPtr
-)
-
-
-// templates
-//
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CArray, 2
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CList, 2
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CMap, 4
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CTypedPtrArray, 2
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CTypedPtrList, 2
-)
-
-BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
-    boost::range_detail_microsoft::using_type_as_tag,
-    BOOST_PP_NIL, CTypedPtrMap, 3
-)
-
-
-// strings
-//
-#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
-
-    BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
-        boost::range_detail_microsoft::using_type_as_tag,
-        BOOST_PP_NIL, CString
-    )
-
-#endif
-
-
-
-
-#endif
diff --git a/src/boost/range/mutable_iterator.hpp b/src/boost/range/mutable_iterator.hpp
deleted file mode 100644
index 7beca66..0000000
--- a/src/boost/range/mutable_iterator.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP
-#define BOOST_RANGE_MUTABLE_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-#include <boost/range/detail/iterator.hpp>
-#else
-
-#include <boost/range/detail/extract_optional_type.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include <cstddef>
-#include <utility>
-
-namespace boost
-{
-    //////////////////////////////////////////////////////////////////////////
-    // default
-    //////////////////////////////////////////////////////////////////////////
-    
-    namespace range_detail {
-        BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator )
-    }
-
-    template< typename C >
-    struct range_mutable_iterator : range_detail::extract_iterator<C>
-    {};
-    
-    //////////////////////////////////////////////////////////////////////////
-    // pair
-    //////////////////////////////////////////////////////////////////////////
-
-    template< typename Iterator >
-    struct range_mutable_iterator< std::pair<Iterator,Iterator> >
-    {
-        typedef Iterator type;
-    };
-
-    //////////////////////////////////////////////////////////////////////////
-    // array
-    //////////////////////////////////////////////////////////////////////////
-
-    template< typename T, std::size_t sz >
-    struct range_mutable_iterator< T[sz] >
-    {
-        typedef T* type;
-    };
-
-} // namespace boost
-
-#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-#endif
diff --git a/src/boost/range/numeric.hpp b/src/boost/range/numeric.hpp
deleted file mode 100644
index bfd1049..0000000
--- a/src/boost/range/numeric.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file algorithm.hpp
-///   Contains range-based versions of the std algorithms
-//
-/////////////////////////////////////////////////////////////////////////////
-// Copyright 2009 Neil Groves.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-
-// Copyright 2006 Thorsten Ottosen.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// Copyright 2004 Eric Niebler.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#if defined(_MSC_VER) && _MSC_VER >= 1000
-    #pragma once
-#endif
-
-#ifndef BOOST_RANGE_NUMERIC_HPP
-#define BOOST_RANGE_NUMERIC_HPP
-
-#include <boost/config.hpp>
-#include <boost/assert.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/concepts.hpp>
-#include <boost/range/distance.hpp>
-#include <numeric>
-
-
-namespace boost
-{
-    template< class SinglePassRange, class Value >
-    inline Value accumulate( const SinglePassRange& rng, Value init )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::accumulate( boost::begin(rng), boost::end(rng), init );
-    }
-
-    template< class SinglePassRange, class Value, class BinaryOperation >
-    inline Value accumulate( const SinglePassRange& rng, Value init, BinaryOperation op )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::accumulate( boost::begin(rng), boost::end(rng), init, op );
-    }
-
-
-    template< class SinglePassRange1, class SinglePassRange2, class Value >
-    inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2, Value init )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-        BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
-        return std::inner_product( boost::begin(rng1), boost::end(rng1),
-            boost::begin(rng2), init );
-    }
-
-    template< class SinglePassRange1,
-              class SinglePassRange2,
-              class Value,
-              class BinaryOperation1, class BinaryOperation2 >
-    inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
-                                Value init,
-                                BinaryOperation1 op1, BinaryOperation2 op2 )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
-        BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
-
-        return std::inner_product( boost::begin(rng1), boost::end(rng1),
-                                   boost::begin(rng2), init, op1, op2 );
-    }
-
-    template< class SinglePassRange, class OutputIterator >
-    inline OutputIterator partial_sum ( const SinglePassRange& rng,
-                                        OutputIterator result )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::partial_sum( boost::begin(rng), boost::end(rng), result );
-    }
-
-    template< class SinglePassRange, class OutputIterator, class BinaryOperation >
-    inline OutputIterator partial_sum ( const SinglePassRange& rng, OutputIterator result,
-                                        BinaryOperation op )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::partial_sum( boost::begin(rng), boost::end(rng), result, op );
-    }
-
-    template< class SinglePassRange, class OutputIterator >
-    inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
-                                                OutputIterator result )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
-        return std::adjacent_difference( boost::begin(rng), boost::end(rng),
-                                         result );
-    }
-
-    template< class SinglePassRange, class OutputIterator, class BinaryOperation >
-    inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
-                                                OutputIterator result,
-                                                BinaryOperation op )
-    {
-        BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
-        return std::adjacent_difference( boost::begin(rng), boost::end(rng),
-                                         result, op );
-    }
-
-}
-
-#endif
diff --git a/src/boost/range/pointer.hpp b/src/boost/range/pointer.hpp
deleted file mode 100644
index e7431ff..0000000
--- a/src/boost/range/pointer.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2006. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_POINTER_TYPE_HPP
-#define BOOST_RANGE_POINTER_TYPE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_pointer : iterator_pointer< typename range_iterator<T>::type >
-    { };
-}
-
-#endif
diff --git a/src/boost/range/rbegin.hpp b/src/boost/range/rbegin.hpp
deleted file mode 100644
index 78e5f61..0000000
--- a/src/boost/range/rbegin.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_RBEGIN_HPP
-#define BOOST_RANGE_RBEGIN_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/end.hpp>
-#include <boost/range/reverse_iterator.hpp>
-
-namespace boost
-{
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-rbegin( C& c )
-{
-    return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::end( c ) );
-}
-
-#else
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-rbegin( C& c )
-{
-    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-        iter_type;
-    return iter_type( boost::end( c ) );
-}
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
-rbegin( const C& c )
-{
-    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
-        iter_type;
-    return iter_type( boost::end( c ) );
-}
-
-#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
-const_rbegin( const T& r )
-{
-    return boost::rbegin( r );
-}
-
-} // namespace 'boost'
-
-#endif
-
diff --git a/src/boost/range/reference.hpp b/src/boost/range/reference.hpp
deleted file mode 100644
index d308e43..0000000
--- a/src/boost/range/reference.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_REFERENCE_TYPE_HPP
-#define BOOST_RANGE_REFERENCE_TYPE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_reference : iterator_reference< typename range_iterator<T>::type >
-    { };
-}
-
-#endif
diff --git a/src/boost/range/rend.hpp b/src/boost/range/rend.hpp
deleted file mode 100644
index fd79aa2..0000000
--- a/src/boost/range/rend.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_REND_HPP
-#define BOOST_RANGE_REND_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/begin.hpp>
-#include <boost/range/reverse_iterator.hpp>
-
-namespace boost
-{
-
-#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-rend( C& c )
-{
-    return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::begin( c ) );
-}
-
-#else
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-rend( C& c )
-{
-    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
-               iter_type;
-    return iter_type( boost::begin( c ) );
-}
-
-template< class C >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
-rend( const C& c )
-{
-    typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
-        iter_type;
-    return iter_type( boost::begin( c ) );
-}
-
-#endif
-
-template< class T >
-inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
-const_rend( const T& r )
-{
-    return boost::rend( r );
-}
-
-} // namespace 'boost'
-
-#endif
-
diff --git a/src/boost/range/result_iterator.hpp b/src/boost/range/result_iterator.hpp
deleted file mode 100644
index ba09c5f..0000000
--- a/src/boost/range/result_iterator.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_RESULT_ITERATOR_HPP
-#define BOOST_RANGE_RESULT_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/range/iterator.hpp>
-
-namespace boost
-{
-    //
-    // This interface is deprecated, use range_iterator<T>
-    //
-    
-    template< typename C >
-    struct range_result_iterator : range_iterator<C>
-    { };
-    
-} // namespace boost
-
-
-#endif
diff --git a/src/boost/range/reverse_iterator.hpp b/src/boost/range/reverse_iterator.hpp
deleted file mode 100644
index f8e9221..0000000
--- a/src/boost/range/reverse_iterator.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_REVERSE_ITERATOR_HPP
-#define BOOST_RANGE_REVERSE_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-#include <boost/iterator/reverse_iterator.hpp>
-
-
-namespace boost
-{
-    //////////////////////////////////////////////////////////////////////////
-    // default
-    //////////////////////////////////////////////////////////////////////////
-    
-    template< typename C >
-    struct range_reverse_iterator
-    {
-        typedef reverse_iterator< 
-            BOOST_DEDUCED_TYPENAME range_iterator<C>::type > type;
-    };
-    
-
-} // namespace boost
-
-
-#endif
diff --git a/src/boost/range/reverse_result_iterator.hpp b/src/boost/range/reverse_result_iterator.hpp
deleted file mode 100644
index 62bf135..0000000
--- a/src/boost/range/reverse_result_iterator.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
-#define BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/range/reverse_iterator.hpp>
-
-namespace boost
-{
-    //
-    // This interface is deprecated, use range_reverse_iterator<T>
-    //
-   
-    template< typename C >
-    struct range_reverse_result_iterator : range_reverse_iterator<C>
-    { };
-    
-} // namespace boost
-
-#endif
diff --git a/src/boost/range/size.hpp b/src/boost/range/size.hpp
deleted file mode 100644
index 6ae74d1..0000000
--- a/src/boost/range/size.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_SIZE_HPP
-#define BOOST_RANGE_SIZE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/assert.hpp>
-
-namespace boost
-{
-    namespace range_detail
-    {
-        template<class SinglePassRange>
-        inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
-        range_calculate_size(const SinglePassRange& rng)
-        {
-            BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 &&
-                          "reachability invariant broken!" );
-            return boost::end(rng) - boost::begin(rng);
-        }
-    }
-
-    template<class SinglePassRange>
-    inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
-    size(const SinglePassRange& rng)
-    {
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
-    !BOOST_WORKAROUND(__GNUC__, < 3) \
-    /**/
-        using namespace range_detail;
-#endif
-        return range_calculate_size(rng);
-    }
-
-} // namespace 'boost'
-
-#endif
diff --git a/src/boost/range/size_type.hpp b/src/boost/range/size_type.hpp
deleted file mode 100644
index c6fb54b..0000000
--- a/src/boost/range/size_type.hpp
+++ /dev/null
@@ -1,89 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_SIZE_TYPE_HPP
-#define BOOST_RANGE_SIZE_TYPE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/difference_type.hpp>
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-#include <boost/range/detail/size_type.hpp>
-#else
-
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/make_unsigned.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <cstddef>
-#include <utility>
-
-namespace boost
-{
-    namespace detail
-    {
-
-        //////////////////////////////////////////////////////////////////////////
-        // default
-        //////////////////////////////////////////////////////////////////////////
-
-        template<typename T>
-        class has_size_type
-        {
-            typedef char no_type;
-            struct yes_type { char dummy[2]; };
-
-            template<typename C>
-            static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x);
-
-            template<typename C, typename Arg>
-            static no_type test(Arg x);
-
-        public:
-            static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
-        };
-
-        template<typename C, typename Enabler=void>
-        struct range_size
-        {
-            typedef BOOST_DEDUCED_TYPENAME make_unsigned<
-                BOOST_DEDUCED_TYPENAME range_difference<C>::type
-            >::type type;
-        };
-
-        template<typename C>
-        struct range_size<
-            C,
-            BOOST_DEDUCED_TYPENAME enable_if<has_size_type<C>, void>::type
-        >
-        {
-            typedef BOOST_DEDUCED_TYPENAME C::size_type type;
-        };
-
-    }
-
-    template< class T >
-    struct range_size :
-        detail::range_size<T>
-    { };
-
-    template< class T >
-    struct range_size<const T >
-        : detail::range_size<T>
-    { };
-
-} // namespace boost
-
-#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-
-#endif
diff --git a/src/boost/range/sub_range.hpp b/src/boost/range/sub_range.hpp
deleted file mode 100644
index 0b00086..0000000
--- a/src/boost/range/sub_range.hpp
+++ /dev/null
@@ -1,182 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Neil Groves 2009.
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_SUB_RANGE_HPP
-#define BOOST_RANGE_SUB_RANGE_HPP
-
-#include <boost/detail/workaround.hpp>
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) 
-    #pragma warning( push )
-    #pragma warning( disable : 4996 )
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/range/value_type.hpp>
-#include <boost/range/size_type.hpp>
-#include <boost/range/difference_type.hpp>
-#include <boost/range/algorithm/equal.hpp>
-#include <boost/assert.hpp>
-#include <boost/type_traits/is_reference.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-
-namespace boost
-{
-    
-    template< class ForwardRange > 
-    class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type > 
-    {
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
-        typedef iterator_range< iterator_t  > base;
-
-        typedef BOOST_DEDUCED_TYPENAME base::impl impl;
-    public:
-        typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type            value_type;
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type         iterator;
-        typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type   const_iterator;
-        typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type       difference_type;
-        typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type             size_type;
-        typedef BOOST_DEDUCED_TYPENAME base::reference                            reference;
-        
-    public: // for return value of front/back
-        typedef BOOST_DEDUCED_TYPENAME 
-                boost::mpl::if_< boost::is_reference<reference>,
-                                 const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference>::type&, 
-                                 reference >::type const_reference;
-
-    public:
-        sub_range() : base() 
-        { }
-        
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) 
-        sub_range( const sub_range& r ) 
-            : base( static_cast<const base&>( r ) )  
-        { }  
-#endif
-
-        template< class ForwardRange2 >
-        sub_range( ForwardRange2& r ) : 
-            
-#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
-            base( impl::adl_begin( r ), impl::adl_end( r ) )
-#else
-            base( r )
-#endif        
-        { }
-        
-        template< class ForwardRange2 >
-        sub_range( const ForwardRange2& r ) : 
-
-#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
-            base( impl::adl_begin( r ), impl::adl_end( r ) )
-#else
-            base( r )
-#endif                
-        { }
-
-        template< class Iter >
-        sub_range( Iter first, Iter last ) :
-            base( first, last )
-        { }
-        
-        template< class ForwardRange2 >
-        sub_range& operator=( ForwardRange2& r )
-        {
-            base::operator=( r );
-            return *this;
-        }
-
-        template< class ForwardRange2 >
-        sub_range& operator=( const ForwardRange2& r )
-        {
-            base::operator=( r );
-            return *this;
-        }   
-
-        sub_range& operator=( const sub_range& r )
-        {
-            base::operator=( static_cast<const base&>(r) );
-            return *this;            
-        }
-        
-    public:
-        
-        iterator        begin()          { return base::begin(); }
-        const_iterator  begin() const    { return base::begin(); }
-        iterator        end()            { return base::end();   }
-        const_iterator  end() const      { return base::end();   }
-        difference_type size() const     { return base::size();  }   
-
-        
-    public: // convenience
-        reference front()
-        {
-            return base::front();
-        }
-
-        const_reference front() const
-        {
-            return base::front();
-        }
-
-        reference back()
-        {
-            return base::back();
-        }
-
-        const_reference back() const
-        {
-            return base::back();
-        }
-
-        reference operator[]( difference_type sz )
-        {
-            return base::operator[](sz);
-        }
-
-        const_reference operator[]( difference_type sz ) const
-        {
-            return base::operator[](sz);
-        }
-
-    };
-
-    template< class ForwardRange, class ForwardRange2 >
-    inline bool operator==( const sub_range<ForwardRange>& l,
-                            const sub_range<ForwardRange2>& r )
-    {
-        return boost::equal( l, r );
-    }
-
-    template< class ForwardRange, class ForwardRange2 >
-    inline bool operator!=( const sub_range<ForwardRange>& l,
-                            const sub_range<ForwardRange2>& r )
-    {
-        return !boost::equal( l, r );
-    }
-
-    template< class ForwardRange, class ForwardRange2 >
-    inline bool operator<( const sub_range<ForwardRange>& l,
-                           const sub_range<ForwardRange2>& r )
-    {
-        return iterator_range_detail::less_than( l, r );
-    }
-
-
-} // namespace 'boost'
-
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) 
-    #pragma warning( pop )
-#endif
-
-#endif
-
diff --git a/src/boost/range/value_type.hpp b/src/boost/range/value_type.hpp
deleted file mode 100644
index 95c7580..0000000
--- a/src/boost/range/value_type.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Boost.Range library
-//
-//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
-//  distribution is subject to the Boost Software License, Version
-//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
-//  http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see http://www.boost.org/libs/range/
-//
-
-#ifndef BOOST_RANGE_VALUE_TYPE_HPP
-#define BOOST_RANGE_VALUE_TYPE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/range/config.hpp>
-#include <boost/range/iterator.hpp>
-
-//#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-//#include <boost/range/detail/value_type.hpp>
-//#else
-
-#include <boost/iterator/iterator_traits.hpp>
-
-namespace boost
-{
-    template< class T >
-    struct range_value : iterator_value< typename range_iterator<T>::type >
-    { };
-}
-
-#endif
diff --git a/src/clipper/CMakeLists.txt b/src/clipper/CMakeLists.txt
new file mode 100644
index 0000000..0128112
--- /dev/null
+++ b/src/clipper/CMakeLists.txt
@@ -0,0 +1,9 @@
+set( _clipper_srcs
+# headers
+    clipper.hpp clipper.cpp 
+)
+foreach( file ${_clipper_srcs} )
+  list( APPEND clipper_srcs clipper/${file} )
+endforeach()
+
+set( clipper_srcs ${clipper_srcs} PARENT_SCOPE )
diff --git a/src/clipper/License.txt b/src/clipper/License.txt
new file mode 100755
index 0000000..3d94797
--- /dev/null
+++ b/src/clipper/License.txt
@@ -0,0 +1,24 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+http://www.boost.org/LICENSE_1_0.txt
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/src/clipper/README b/src/clipper/README
new file mode 100755
index 0000000..a3ed26f
--- /dev/null
+++ b/src/clipper/README
@@ -0,0 +1,413 @@
+=====================================================================
+Clipper Change Log
+=====================================================================
+v6.4.2 (27 February 2017) Rev 512
+* Several minor bugfixes: #152 #160 #161 #162 
+
+v6.4 (2 July 2015) Rev 495
+* Numerous generally minor bugfixes 
+
+v6.2.1 (31 October 2014) Rev 482
+* Bugfix in ClipperOffset.Execute where the Polytree.IsHole property 
+  was returning incorrect values with negative offsets
+* Very minor improvement to join rounding in ClipperOffset
+* Fixed CPP OpenGL demo.
+
+v6.2.0 (17 October 2014) Rev 477
+* Numerous minor bugfixes, too many to list. 
+  (See revisions 454-475 in Sourceforge Repository)
+* The ZFillFunction (custom callback function) has had its parameters 
+  changed. 
+* Curves demo removed (temporarily).
+* Deprecated functions have been removed. 
+
+v6.1.5 (26 February 2014) Rev 460
+* Improved the joining of output polygons sharing a common edge 
+  when those common edges are horizontal.
+* Fixed a bug in ClipperOffset.AddPath() which would produce
+  incorrect solutions when open paths were added before closed paths.
+* Minor code tidy and performance improvement
+
+v6.1.4 (6 February 2014)
+* Fixed bugs in MinkowskiSum
+* Fixed minor bug when using Clipper.ForceSimplify.
+* Modified use_xyz callback so that all 4 vertices around an
+  intersection point are now passed to the callback function.
+
+v6.1.3a (22 January 2014) Rev 453
+* Fixed buggy PointInPolygon function (C++ and C# only). 
+  Note this bug only affected the newly exported function, the 
+  internal PointInPolygon function used by Clipper was OK.
+ 
+v6.1.3 (19 January 2014) Rev 452
+* Fixed potential endless loop condition when adding open 
+  paths to Clipper.
+* Fixed missing implementation of SimplifyPolygon function 
+  in C++ code.
+* Fixed incorrect upper range constant for polygon coordinates 
+  in Delphi code.
+* Added PointInPolygon function. 
+* Overloaded MinkowskiSum function to accommodate multi-contour 
+  paths.  
+
+v6.1.2 (15 December 2013) Rev 444
+* Fixed broken C++ header file.
+* Minor improvement to joining polygons.
+
+v6.1.1 (13 December 2013) Rev 441
+* Fixed a couple of bugs affecting open paths that could 
+  raise unhandled exceptions.
+  
+v6.1.0 (12 December 2013)
+* Deleted: Previously deprecated code has been removed. 
+* Modified: The OffsetPaths function is now deprecated as it has 
+  been replaced by the ClipperOffset class which is much more 
+  flexible. 
+* Bugfixes: Several minor bugs have been fixed including 
+  occasionally an incorrect nesting within the PolyTree structure.
+
+v6.0.0 (30 October 2013)
+* Added: Open path (polyline) clipping. A new 'Curves' demo 
+  application showcases this (see the 'Curves' directory). 
+* Update: Major improvement in the merging of 
+  shared/collinear edges in clip solutions (see Execute). 
+* Added: The IntPoint structure now has an optional 'Z' member. 
+  (See the precompiler directive use_xyz.) 
+* Added: Users can now force Clipper to use 32bit integers 
+  (via the precompiler directive use_int32) instead of using 
+  64bit integers.
+* Modified: To accommodate open paths, the Polygon and Polygons 
+  structures have been renamed Path and Paths respectively. The 
+  AddPolygon and AddPolygons methods of the ClipperBase class 
+  have been renamed AddPath and AddPaths respectively. Several 
+  other functions have been similarly renamed. 
+* Modified: The PolyNode Class has a new IsOpen property. 
+* Modified: The Clipper class has a new ZFillFunction property. 
+* Added: MinkowskiSum and MinkowskiDiff functions added. 
+* Added: Several other new functions have been added including 
+  PolyTreeToPaths, OpenPathsFromPolyTree and ClosedPathsFromPolyTree. 
+* Added: The Clipper constructor now accepts an optional InitOptions 
+  parameter to simplify setting properties. 
+* Bugfixes: Numerous minor bugs have been fixed. 
+* Deprecated: Version 6 is a major upgrade from previous versions 
+  and quite a number of changes have been made to exposed structures 
+  and functions. To minimize inconvenience to existing library users, 
+  some code has been retained and some added to maintain backward 
+  compatibility. However, because this code will be removed in a 
+  future update, it has been marked as deprecated and a precompiler 
+  directive use_deprecated has been defined.
+
+v5.1.6 (23 May 2013)
+* BugFix: CleanPolygon function was buggy.
+* Changed: The behaviour of the 'miter' JoinType has been 
+  changed so that when squaring occurs, it's no longer 
+  extended up to the miter limit but is squared off at 
+  exactly 'delta' units. (This improves the look of mitering 
+  with larger limits at acute angles.) 
+* Added: New OffsetPolyLines function
+* Update: Minor code refactoring and optimisations
+
+v5.1.5 (5 May 2013)
+* Added: ForceSimple property to Clipper class
+* Update: Improved documentation  
+
+v5.1.4 (24 March 2013)
+* Update: CleanPolygon function enhanced.
+* Update: Documentation improved.  
+
+v5.1.3 (14 March 2013)
+* Bugfix: Minor bugfixes.
+* Update: Documentation significantly improved.  
+
+v5.1.2 (26 February 2013)
+* Bugfix: PolyNode class was missing a constructor. 
+* Update: The MiterLimit parameter in the OffsetPolygons 
+  function has been renamed Limit and can now also be used to 
+  limit the number of vertices used to construct arcs when 
+  JoinType is set to jtRound.
+
+v5.1.0 (17 February 2013)
+* Update: ExPolygons has been replaced with the PolyTree & 
+  PolyNode classes to more fully represent the parent-child 
+  relationships of the polygons returned by Clipper. 
+* Added: New CleanPolygon and CleanPolygons functions. 
+* Bugfix: Another orientation bug fixed.
+
+v5.0.2 - 30 December 2012
+* Bugfix: Significant fixes in and tidy of the internal 
+  Int128 class (which is used only when polygon coordinate 
+  values are greater than �0x3FFFFFFF (~1.07e9)). 
+* Update: The Area algorithm has been updated and is faster. 
+* Update: Documentation updates. The newish but undocumented 
+  'CheckInputs' parameter of the OffsetPolygons function has been 
+  renamed 'AutoFix' and documented too. The comments on rounding 
+  have also been improved (ie clearer and expanded).
+
+v4.10.0 - 25 December 2012
+* Bugfix: Orientation bugs should now be resolved (finally!).
+* Bugfix: Bug in Int128 class
+
+v4.9.8 - 2 December 2012
+* Bugfix: Further fixes to rare Orientation bug.
+
+v4.9.7 - 29 November 2012
+* Bugfix: Bug that very rarely returned the wrong polygon 
+  orientation.
+* Bugfix: Obscure bug affecting OffsetPolygons when using 
+  jtRound for the JoinType parameter and when polygons also
+  contain very large coordinate values (> +/-100000000000).
+
+v4.9.6 - 9 November 2012
+* Bugfix: Another obscure bug related to joining polygons.
+
+v4.9.4 - 2 November 2012
+* Bugfix: Bugs in Int128 class occasionally causing 
+  wrong orientations.
+* Bugfix: Further fixes related to joining polygons.
+
+v4.9.0 - 9 October 2012
+* Bugfix: Obscure bug related to joining polygons.
+
+v4.8.9 - 25 September 2012
+* Bugfix: Obscure bug related to precision of intersections.
+          
+v4.8.8 - 30 August 2012
+* Bugfix: Fixed bug in OffsetPolygons function introduced in 
+  version 4.8.5.
+
+v4.8.7 - 24 August 2012
+* Bugfix: ReversePolygon function in C++ translation was broken.
+* Bugfix: Two obscure bugs affecting orientation fixed too.
+
+v4.8.6 - 11 August 2012
+* Bugfix: Potential for memory overflow errors when using 
+  ExPolygons structure.
+* Bugfix: The polygon coordinate range has been reduced to 
+  +/- 0x3FFFFFFFFFFFFFFF (4.6e18).
+* Update: ReversePolygons function was misnamed ReversePoints in C++.
+* Update: SimplifyPolygon function now takes a PolyFillType parameter.
+          
+v4.8.5 - 15 July 2012
+* Bugfix: Potential for memory overflow errors in OffsetPolygons().
+
+v4.8.4 - 1 June 2012
+* Bugfix: Another obscure bug affecting ExPolygons structure.
+
+v4.8.3 - 27 May 2012
+* Bugfix: Obscure bug causing incorrect removal of a vertex.
+
+v4.8.2 - 21 May 2012
+* Bugfix: Obscure bug could cause an exception when using 
+  ExPolygon structure.
+
+v4.8.1 - 12 May 2012
+* Update: Cody tidy and minor bug fixes.
+
+v4.8.0 - 30 April 2012
+* Bugfix: Occasional errors in orientation fixed. 
+* Update: Added notes on rounding to the documentation. 
+
+v4.7.6 - 11 April 2012
+* Fixed a bug in Orientation function (affecting C# translations only).
+* Minor documentation update.
+
+v4.7.5 - 28 March 2012
+* Bugfix: Fixed a recently introduced bug that occasionally caused an 
+  unhandled exception in C++ and C# translations. 
+
+v4.7.4 - 15 March 2012
+* Bugfix: Another minor bugfix.
+
+v4.7.2 - 4 March 2012
+* Bugfix: Fixed bug introduced in ver 4.7 which sometimes caused 
+  an exception if ExPolygon structure was passed to Clipper's 
+  Execute method. 
+
+v4.7.1 - 3 March 2012
+* Bugfix: Rare crash when JoinCommonEdges joined polygons that 
+  'cancelled' each other. 
+* Bugfix: Clipper's internal Orientation method occasionally 
+  returned wrong result. 
+* Update: Improved C# code (thanks to numerous excellent suggestions 
+  from David Piepgrass) 
+
+v4.7 - 10 February 2012
+* Improved the joining of output polygons sharing a common edge.
+
+v4.6.6 - 3 February 2012
+* Bugfix: Another obscure bug occasionally causing incorrect 
+  polygon orientation. 
+
+v4.6.5 - 17 January 2012
+* Bugfix: Obscure bug occasionally causing incorrect hole 
+  assignment in ExPolygon structure. 
+
+v4.6.4 - 8 November 2011
+* Added: SimplifyPolygon and SimplifyPolygons functions.
+
+v4.6.3 - 11 November 2011
+* Bugfix: Fixed another minor mitering bug in OffsetPolygons.
+
+v4.6.2 - 10 November 2011
+* Bugfix: Fixed a rare bug in the orientation of polygons 
+  returned by Clipper's Execute() method.
+* Bugfix: Previous update introduced a mitering bug in the
+  OffsetPolygons function.
+
+v4.6 - 29 October 2011
+* Added: Support for Positive and Negative polygon fill 
+  types (in addition to the EvenOdd and NonZero fill types).
+* Bugfix: The OffsetPolygons function was generating the 
+  occasional artefact when 'shrinking' polygons.
+
+v4.5.5 - 8 October 2011
+* Bugfix: Fixed an obscure bug in Clipper's JoinCommonEdges 
+  method. 
+* Update: Replaced IsClockwise function with Orientation 
+  function. The orientation issues affecting OffsetPolygons 
+  should now be finally resolved.
+* Change: The Area function once again returns a signed value.
+ 
+v4.5.1 - 28 September 2011
+* Deleted: The UseFullCoordinateRange property has been 
+  deleted since integer range is now managed implicitly. 
+* BugFix: Minor bug in OffsetPolygon mitering. 
+* Change: C# JoinType enum moved from Clipper class to 
+  ClipperLib namespace. 
+* Change: The Area function now returns the absolute area 
+  (irrespective of orientation). 
+* Change: The IsClockwise function now requires a second 
+  parameter - YAxisPositiveUpward - to accommodate displays 
+  with Y-axis oriented in either direction
+
+v4.4.4 - 10 September 2011
+* Change: Deleted jtButt from JoinType (used by the 
+  OffsetPolygons function). 
+* BugFix: Fixed another minor bug in OffsetPolygons function. 
+* Update: Further improvements to the help file
+
+v4.4.3 - 29 August 2011
+* BugFix: fixed a minor rounding issue in OffsetPolygons 
+  function (affected C++ & C# translations). 
+* BugFix: fixed a minor bug in OffsetPolygons' function 
+  declaration (affected C++ translation only). 
+* Change: 'clipper' namespace changed to 'ClipperLib' 
+  namespace in both C++ and C# code to remove the ambiguity 
+  between the Clipper class and the namespace. (This also 
+  required numerous updates to the accompanying demos.)
+
+v4.4.2 - 26 August 2011
+* BugFix: minor bugfixes in Clipper. 
+* Update: the OffsetPolygons function has been significantly 
+  improved by offering 4 different join styles. 
+
+v4.4.0 - 6 August 2011
+* BugFix: A number of minor bugs have been fixed that mostly 
+  affected the new ExPolygons structure. 
+
+v4.3.0 - 17 June 2011
+* New: ExPolygons structure that explicitly associates 'hole' 
+  polygons with their 'outer' container polygons.
+* New: Execute method overloaded so the solution parameter 
+  can now be either Polygons or ExPolygons.  
+* BugFix: Fixed a rare bug in solution polygons orientation. 
+
+v4.2.8 - 21 May 2011
+* Update: JoinCommonEdges() improved once more. 
+* BugFix: Several minor bugs fixed. 
+
+v4.2.6 - 1 May 2011
+* Bugfix: minor bug in SlopesEqual function.
+* Update: Merging of output polygons sharing common edges 
+  has been significantly inproved
+
+v4.2.4 - 26 April 2011
+  Input polygon coordinates can now contain the full range of 
+  signed 64bit integers (ie +/-9,223,372,036,854,775,807). This 
+  means that floating point values can be converted to and from 
+  Clipper's 64bit integer coordinates structure (IntPoint) and  
+  still retain a precision of up to 18 decimal places. However, 
+  since the large-integer math that supports this expanded range 
+  imposes a small cost on performance (~15%), a new property 
+  UseFullCoordinateRange has been added to the Clipper class to 
+  allow users the choice of whether or not to use this expanded 
+  coordinate range. If this property is disabled, coordinate values 
+  are restricted to +/-1,500,000,000.
+
+v4.2 - 12 April 2011
+  JoinCommonEdges() code significantly improved plus other minor 
+  improvements.
+
+v4.1.2 - 9 April 2011
+* Update: Minor code tidy. 
+* Bugfix: Possible endless loop in JoinCommonEdges() in clipper.pas.
+
+v4.1.1 - 8 April 2011
+* Update: All polygon coordinates are now stored as 64bit integers
+  (though they're still restricted to range -1.5e9 to +1.5e9 pending 
+  the inclusion of code supporting 64bit math).
+* Change: AddPolygon and AddPolygons methods now return boolean 
+  values. 
+* Bugfix: Bug in JoinCommonEdges() caused potential endless loop. 
+* Bugfix: Bug in IsClockwise(). (C++ code only)
+
+v4.0 - 5 April 2011
+* Clipper 4 is a major rewrite of earlier versions. The biggest 
+  change is that floating point values are no longer used, 
+  except for the storing of edge slope values. The main benefit 
+  of this is the issue of numerical robustness has been 
+  addressed. Due to other major code improvements Clipper v4 
+  is approximately 40% faster than Clipper v3. 
+* The AddPolyPolygon method has been renamed to AddPolygons. 
+* The IgnoreOrientation property has been removed. 
+* The clipper_misc library has been merged back into the 
+  main clipper library.
+  
+v3.1.0 - 17 February 2011
+* Bugfix: Obscure bug in TClipperBase.SetDx method that caused 
+  problems with very small edges ( edges <1/1000th pixel in size).
+  
+v3.0.3 - 9 February 2011
+* Bugfix: Significant bug, but only in C# code.
+* Update: Minor refactoring.
+
+v3.0 - 31 January 2011
+* Update: Major rewrite of the portion of code that calculates 
+  the output polygons' orientation.
+* Update: Help file significantly improved.
+* Change: Renamed ForceOrientation property to IgnoreOrientation. 
+  If the orientation of output polygons is not important, or can 
+  be managed separately, clipping routines can be sped up by about 
+  60% by setting IgnoreOrientation to true. Defaults to false.
+* Change: The OffsetPolygon and Area functions have been moved to 
+  the new unit - clipper_misc. 
+
+2.99 - 15 January 2011
+* Bugfix: Obscure bug in AddPolygon method could cause an endless loop. 
+
+2.8 - 20 November 2010
+* Updated: Output polygons which previously shared a common 
+  edge are now merged. 
+* Changed: The orientation of outer polygons is now clockwise 
+  when the display's Y axis is positive downwards (as is 
+  typical for most Windows applications). Inner polygons 
+  (holes) have the opposite orientation.
+* Added: Support module for Cairo Graphics Library (with demo). 
+* Updated: C# and C++ demos.
+
+2.522 - 15 October 2010
+* Added C# translation (thanks to Olivier Lejeune) and 
+  a link to Ruby bindings (thanks to Mike Owens).
+
+2.0 - 30 July 2010
+* Clipper now clips using both the Even-Odd (alternate) and 
+  Non-Zero (winding) polygon filling rules. (Previously Clipper 
+  assumed the Even-Odd rule for polygon filling.)
+  
+1.4c - 16 June 2010
+* Added C++ support for AGG graphics library 
+  
+1.2s - 2 June 2010
+* Added C++ translation of clipper.pas
+
+1.0 - 9 May 2010
\ No newline at end of file
diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp
new file mode 100755
index 0000000..d0e5ba2
--- /dev/null
+++ b/src/clipper/clipper.cpp
@@ -0,0 +1,4629 @@
+/*******************************************************************************
+*                                                                              *
+* Author    :  Angus Johnson                                                   *
+* Version   :  6.4.2                                                           *
+* Date      :  27 February 2017                                                *
+* Website   :  http://www.angusj.com                                           *
+* Copyright :  Angus Johnson 2010-2017                                         *
+*                                                                              *
+* License:                                                                     *
+* Use, modification & distribution is subject to Boost Software License Ver 1. *
+* http://www.boost.org/LICENSE_1_0.txt                                         *
+*                                                                              *
+* Attributions:                                                                *
+* The code in this library is an extension of Bala Vatti's clipping algorithm: *
+* "A generic solution to polygon clipping"                                     *
+* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63.             *
+* http://portal.acm.org/citation.cfm?id=129906                                 *
+*                                                                              *
+* Computer graphics and geometric modeling: implementation and algorithms      *
+* By Max K. Agoston                                                            *
+* Springer; 1 edition (January 4, 2005)                                        *
+* http://books.google.com/books?q=vatti+clipping+agoston                       *
+*                                                                              *
+* See also:                                                                    *
+* "Polygon Offsetting by Computing Winding Numbers"                            *
+* Paper no. DETC2005-85513 pp. 565-575                                         *
+* ASME 2005 International Design Engineering Technical Conferences             *
+* and Computers and Information in Engineering Conference (IDETC/CIE2005)      *
+* September 24-28, 2005 , Long Beach, California, USA                          *
+* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf              *
+*                                                                              *
+*******************************************************************************/
+
+/*******************************************************************************
+*                                                                              *
+* This is a translation of the Delphi Clipper library and the naming style     *
+* used has retained a Delphi flavour.                                          *
+*                                                                              *
+*******************************************************************************/
+
+#include "clipper.hpp"
+#include <cmath>
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+#include <cstring>
+#include <cstdlib>
+#include <ostream>
+#include <functional>
+
+namespace ClipperLib {
+
+static double const pi = 3.141592653589793238;
+static double const two_pi = pi *2;
+static double const def_arc_tolerance = 0.25;
+
+enum Direction { dRightToLeft, dLeftToRight };
+
+static int const Unassigned = -1;  //edge not currently 'owning' a solution
+static int const Skip = -2;        //edge that would otherwise close a path
+
+#define HORIZONTAL (-1.0E+40)
+#define TOLERANCE (1.0e-20)
+#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
+
+struct TEdge {
+  IntPoint Bot;
+  IntPoint Curr; //current (updated for every new scanbeam)
+  IntPoint Top;
+  double Dx;
+  PolyType PolyTyp;
+  EdgeSide Side; //side only refers to current side of solution poly
+  int WindDelta; //1 or -1 depending on winding direction
+  int WindCnt;
+  int WindCnt2; //winding count of the opposite polytype
+  int OutIdx;
+  TEdge *Next;
+  TEdge *Prev;
+  TEdge *NextInLML;
+  TEdge *NextInAEL;
+  TEdge *PrevInAEL;
+  TEdge *NextInSEL;
+  TEdge *PrevInSEL;
+};
+
+struct IntersectNode {
+  TEdge          *Edge1;
+  TEdge          *Edge2;
+  IntPoint        Pt;
+};
+
+struct LocalMinimum {
+  cInt          Y;
+  TEdge        *LeftBound;
+  TEdge        *RightBound;
+};
+
+struct OutPt;
+
+//OutRec: contains a path in the clipping solution. Edges in the AEL will
+//carry a pointer to an OutRec when they are part of the clipping solution.
+struct OutRec {
+  int       Idx;
+  bool      IsHole;
+  bool      IsOpen;
+  OutRec   *FirstLeft;  //see comments in clipper.pas
+  PolyNode *PolyNd;
+  OutPt    *Pts;
+  OutPt    *BottomPt;
+};
+
+struct OutPt {
+  int       Idx;
+  IntPoint  Pt;
+  OutPt    *Next;
+  OutPt    *Prev;
+};
+
+struct Join {
+  OutPt    *OutPt1;
+  OutPt    *OutPt2;
+  IntPoint  OffPt;
+};
+
+struct LocMinSorter
+{
+  inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2)
+  {
+    return locMin2.Y < locMin1.Y;
+  }
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline cInt Round(double val)
+{
+  if ((val < 0)) return static_cast<cInt>(val - 0.5); 
+  else return static_cast<cInt>(val + 0.5);
+}
+//------------------------------------------------------------------------------
+
+inline cInt Abs(cInt val)
+{
+  return val < 0 ? -val : val;
+}
+
+//------------------------------------------------------------------------------
+// PolyTree methods ...
+//------------------------------------------------------------------------------
+
+void PolyTree::Clear()
+{
+    for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
+      delete AllNodes[i];
+    AllNodes.resize(0); 
+    Childs.resize(0);
+}
+//------------------------------------------------------------------------------
+
+PolyNode* PolyTree::GetFirst() const
+{
+  if (!Childs.empty())
+      return Childs[0];
+  else
+      return 0;
+}
+//------------------------------------------------------------------------------
+
+int PolyTree::Total() const
+{
+  int result = (int)AllNodes.size();
+  //with negative offsets, ignore the hidden outer polygon ...
+  if (result > 0 && Childs[0] != AllNodes[0]) result--;
+  return result;
+}
+
+//------------------------------------------------------------------------------
+// PolyNode methods ...
+//------------------------------------------------------------------------------
+
+PolyNode::PolyNode(): Parent(0), Index(0), m_IsOpen(false)
+{
+}
+//------------------------------------------------------------------------------
+
+int PolyNode::ChildCount() const
+{
+  return (int)Childs.size();
+}
+//------------------------------------------------------------------------------
+
+void PolyNode::AddChild(PolyNode& child)
+{
+  unsigned cnt = (unsigned)Childs.size();
+  Childs.push_back(&child);
+  child.Parent = this;
+  child.Index = cnt;
+}
+//------------------------------------------------------------------------------
+
+PolyNode* PolyNode::GetNext() const
+{ 
+  if (!Childs.empty()) 
+      return Childs[0]; 
+  else
+      return GetNextSiblingUp();    
+}  
+//------------------------------------------------------------------------------
+
+PolyNode* PolyNode::GetNextSiblingUp() const
+{ 
+  if (!Parent) //protects against PolyTree.GetNextSiblingUp()
+      return 0;
+  else if (Index == Parent->Childs.size() - 1)
+      return Parent->GetNextSiblingUp();
+  else
+      return Parent->Childs[Index + 1];
+}  
+//------------------------------------------------------------------------------
+
+bool PolyNode::IsHole() const
+{ 
+  bool result = true;
+  PolyNode* node = Parent;
+  while (node)
+  {
+      result = !result;
+      node = node->Parent;
+  }
+  return result;
+}  
+//------------------------------------------------------------------------------
+
+bool PolyNode::IsOpen() const
+{ 
+  return m_IsOpen;
+}  
+//------------------------------------------------------------------------------
+
+#ifndef use_int32
+
+//------------------------------------------------------------------------------
+// Int128 class (enables safe math on signed 64bit integers)
+// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1
+//    Int128 val2((long64)9223372036854775807);
+//    Int128 val3 = val1 * val2;
+//    val3.AsString => "85070591730234615847396907784232501249" (8.5e+37)
+//------------------------------------------------------------------------------
+
+class Int128
+{
+  public:
+    ulong64 lo;
+    long64 hi;
+
+    Int128(long64 _lo = 0)
+    {
+      lo = (ulong64)_lo;   
+      if (_lo < 0)  hi = -1; else hi = 0; 
+    }
+
+
+    Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
+
+    Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
+    
+    Int128& operator = (const long64 &val)
+    {
+      lo = (ulong64)val;
+      if (val < 0) hi = -1; else hi = 0;
+      return *this;
+    }
+
+    bool operator == (const Int128 &val) const
+      {return (hi == val.hi && lo == val.lo);}
+
+    bool operator != (const Int128 &val) const
+      { return !(*this == val);}
+
+    bool operator > (const Int128 &val) const
+    {
+      if (hi != val.hi)
+        return hi > val.hi;
+      else
+        return lo > val.lo;
+    }
+
+    bool operator < (const Int128 &val) const
+    {
+      if (hi != val.hi)
+        return hi < val.hi;
+      else
+        return lo < val.lo;
+    }
+
+    bool operator >= (const Int128 &val) const
+      { return !(*this < val);}
+
+    bool operator <= (const Int128 &val) const
+      { return !(*this > val);}
+
+    Int128& operator += (const Int128 &rhs)
+    {
+      hi += rhs.hi;
+      lo += rhs.lo;
+      if (lo < rhs.lo) hi++;
+      return *this;
+    }
+
+    Int128 operator + (const Int128 &rhs) const
+    {
+      Int128 result(*this);
+      result+= rhs;
+      return result;
+    }
+
+    Int128& operator -= (const Int128 &rhs)
+    {
+      *this += -rhs;
+      return *this;
+    }
+
+    Int128 operator - (const Int128 &rhs) const
+    {
+      Int128 result(*this);
+      result -= rhs;
+      return result;
+    }
+
+    Int128 operator-() const //unary negation
+    {
+      if (lo == 0)
+        return Int128(-hi, 0);
+      else
+        return Int128(~hi, ~lo + 1);
+    }
+
+    operator double() const
+    {
+      const double shift64 = 18446744073709551616.0; //2^64
+      if (hi < 0)
+      {
+        if (lo == 0) return (double)hi * shift64;
+        else return -(double)(~lo + ~hi * shift64);
+      }
+      else
+        return (double)(lo + hi * shift64);
+    }
+
+};
+//------------------------------------------------------------------------------
+
+Int128 Int128Mul (long64 lhs, long64 rhs)
+{
+  bool negate = (lhs < 0) != (rhs < 0);
+
+  if (lhs < 0) lhs = -lhs;
+  ulong64 int1Hi = ulong64(lhs) >> 32;
+  ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF);
+
+  if (rhs < 0) rhs = -rhs;
+  ulong64 int2Hi = ulong64(rhs) >> 32;
+  ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF);
+
+  //nb: see comments in clipper.pas
+  ulong64 a = int1Hi * int2Hi;
+  ulong64 b = int1Lo * int2Lo;
+  ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;
+
+  Int128 tmp;
+  tmp.hi = long64(a + (c >> 32));
+  tmp.lo = long64(c << 32);
+  tmp.lo += long64(b);
+  if (tmp.lo < b) tmp.hi++;
+  if (negate) tmp = -tmp;
+  return tmp;
+};
+#endif
+
+//------------------------------------------------------------------------------
+// Miscellaneous global functions
+//------------------------------------------------------------------------------
+
+bool Orientation(const Path &poly)
+{
+    return Area(poly) >= 0;
+}
+//------------------------------------------------------------------------------
+
+double Area(const Path &poly)
+{
+  int size = (int)poly.size();
+  if (size < 3) return 0;
+
+  double a = 0;
+  for (int i = 0, j = size -1; i < size; ++i)
+  {
+    a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y);
+    j = i;
+  }
+  return -a * 0.5;
+}
+//------------------------------------------------------------------------------
+
+double Area(const OutPt *op)
+{
+  const OutPt *startOp = op;
+  if (!op) return 0;
+  double a = 0;
+  do {
+    a +=  (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y);
+    op = op->Next;
+  } while (op != startOp);
+  return a * 0.5;
+}
+//------------------------------------------------------------------------------
+
+double Area(const OutRec &outRec)
+{
+  return Area(outRec.Pts);
+}
+//------------------------------------------------------------------------------
+
+bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
+{
+  OutPt *pp2 = pp;
+  do
+  {
+    if (pp2->Pt == Pt) return true;
+    pp2 = pp2->Next;
+  }
+  while (pp2 != pp);
+  return false;
+}
+//------------------------------------------------------------------------------
+
+//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos
+//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
+int PointInPolygon(const IntPoint &pt, const Path &path)
+{
+  //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
+  int result = 0;
+  size_t cnt = path.size();
+  if (cnt < 3) return 0;
+  IntPoint ip = path[0];
+  for(size_t i = 1; i <= cnt; ++i)
+  {
+    IntPoint ipNext = (i == cnt ? path[0] : path[i]);
+    if (ipNext.Y == pt.Y)
+    {
+        if ((ipNext.X == pt.X) || (ip.Y == pt.Y && 
+          ((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1;
+    }
+    if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y))
+    {
+      if (ip.X >= pt.X)
+      {
+        if (ipNext.X > pt.X) result = 1 - result;
+        else
+        {
+          double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - 
+            (double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
+          if (!d) return -1;
+          if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
+        }
+      } else
+      {
+        if (ipNext.X > pt.X)
+        {
+          double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - 
+            (double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
+          if (!d) return -1;
+          if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
+        }
+      }
+    }
+    ip = ipNext;
+  } 
+  return result;
+}
+//------------------------------------------------------------------------------
+
+int PointInPolygon (const IntPoint &pt, OutPt *op)
+{
+  //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
+  int result = 0;
+  OutPt* startOp = op;
+  for(;;)
+  {
+    if (op->Next->Pt.Y == pt.Y)
+    {
+        if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y && 
+          ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1;
+    }
+    if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y))
+    {
+      if (op->Pt.X >= pt.X)
+      {
+        if (op->Next->Pt.X > pt.X) result = 1 - result;
+        else
+        {
+          double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - 
+            (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
+          if (!d) return -1;
+          if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
+        }
+      } else
+      {
+        if (op->Next->Pt.X > pt.X)
+        {
+          double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - 
+            (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
+          if (!d) return -1;
+          if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
+        }
+      }
+    } 
+    op = op->Next;
+    if (startOp == op) break;
+  } 
+  return result;
+}
+//------------------------------------------------------------------------------
+
+bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
+{
+  OutPt* op = OutPt1;
+  do
+  {
+    //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon
+    int res = PointInPolygon(op->Pt, OutPt2);
+    if (res >= 0) return res > 0;
+    op = op->Next; 
+  }
+  while (op != OutPt1);
+  return true; 
+}
+//----------------------------------------------------------------------
+
+bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
+{
+#ifndef use_int32
+  if (UseFullInt64Range)
+    return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) == 
+    Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y);
+  else 
+#endif
+    return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) == 
+    (e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y);
+}
+//------------------------------------------------------------------------------
+
+bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
+  const IntPoint pt3, bool UseFullInt64Range)
+{
+#ifndef use_int32
+  if (UseFullInt64Range)
+    return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y);
+  else 
+#endif
+    return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
+}
+//------------------------------------------------------------------------------
+
+bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
+  const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range)
+{
+#ifndef use_int32
+  if (UseFullInt64Range)
+    return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y);
+  else 
+#endif
+    return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
+}
+//------------------------------------------------------------------------------
+
+inline bool IsHorizontal(TEdge &e)
+{
+  return e.Dx == HORIZONTAL;
+}
+//------------------------------------------------------------------------------
+
+inline double GetDx(const IntPoint pt1, const IntPoint pt2)
+{
+  return (pt1.Y == pt2.Y) ?
+    HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
+}
+//---------------------------------------------------------------------------
+
+inline void SetDx(TEdge &e)
+{
+  cInt dy  = (e.Top.Y - e.Bot.Y);
+  if (dy == 0) e.Dx = HORIZONTAL;
+  else e.Dx = (double)(e.Top.X - e.Bot.X) / dy;
+}
+//---------------------------------------------------------------------------
+
+inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
+{
+  EdgeSide Side =  Edge1.Side;
+  Edge1.Side = Edge2.Side;
+  Edge2.Side = Side;
+}
+//------------------------------------------------------------------------------
+
+inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
+{
+  int OutIdx =  Edge1.OutIdx;
+  Edge1.OutIdx = Edge2.OutIdx;
+  Edge2.OutIdx = OutIdx;
+}
+//------------------------------------------------------------------------------
+
+inline cInt TopX(TEdge &edge, const cInt currentY)
+{
+  return ( currentY == edge.Top.Y ) ?
+    edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y));
+}
+//------------------------------------------------------------------------------
+
+void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
+{
+#ifdef use_xyz  
+  ip.Z = 0;
+#endif
+
+  double b1, b2;
+  if (Edge1.Dx == Edge2.Dx)
+  {
+    ip.Y = Edge1.Curr.Y;
+    ip.X = TopX(Edge1, ip.Y);
+    return;
+  }
+  else if (Edge1.Dx == 0)
+  {
+    ip.X = Edge1.Bot.X;
+    if (IsHorizontal(Edge2))
+      ip.Y = Edge2.Bot.Y;
+    else
+    {
+      b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx);
+      ip.Y = Round(ip.X / Edge2.Dx + b2);
+    }
+  }
+  else if (Edge2.Dx == 0)
+  {
+    ip.X = Edge2.Bot.X;
+    if (IsHorizontal(Edge1))
+      ip.Y = Edge1.Bot.Y;
+    else
+    {
+      b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx);
+      ip.Y = Round(ip.X / Edge1.Dx + b1);
+    }
+  } 
+  else 
+  {
+    b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
+    b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
+    double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
+    ip.Y = Round(q);
+    if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
+      ip.X = Round(Edge1.Dx * q + b1);
+    else 
+      ip.X = Round(Edge2.Dx * q + b2);
+  }
+
+  if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) 
+  {
+    if (Edge1.Top.Y > Edge2.Top.Y)
+      ip.Y = Edge1.Top.Y;
+    else
+      ip.Y = Edge2.Top.Y;
+    if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
+      ip.X = TopX(Edge1, ip.Y);
+    else
+      ip.X = TopX(Edge2, ip.Y);
+  } 
+  //finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ...
+  if (ip.Y > Edge1.Curr.Y)
+  {
+    ip.Y = Edge1.Curr.Y;
+    //use the more vertical edge to derive X ...
+    if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx))
+      ip.X = TopX(Edge2, ip.Y); else
+      ip.X = TopX(Edge1, ip.Y);
+  }
+}
+//------------------------------------------------------------------------------
+
+void ReversePolyPtLinks(OutPt *pp)
+{
+  if (!pp) return;
+  OutPt *pp1, *pp2;
+  pp1 = pp;
+  do {
+  pp2 = pp1->Next;
+  pp1->Next = pp1->Prev;
+  pp1->Prev = pp2;
+  pp1 = pp2;
+  } while( pp1 != pp );
+}
+//------------------------------------------------------------------------------
+
+void DisposeOutPts(OutPt*& pp)
+{
+  if (pp == 0) return;
+    pp->Prev->Next = 0;
+  while( pp )
+  {
+    OutPt *tmpPp = pp;
+    pp = pp->Next;
+    delete tmpPp;
+  }
+}
+//------------------------------------------------------------------------------
+
+inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
+{
+  std::memset(e, 0, sizeof(TEdge));
+  e->Next = eNext;
+  e->Prev = ePrev;
+  e->Curr = Pt;
+  e->OutIdx = Unassigned;
+}
+//------------------------------------------------------------------------------
+
+void InitEdge2(TEdge& e, PolyType Pt)
+{
+  if (e.Curr.Y >= e.Next->Curr.Y)
+  {
+    e.Bot = e.Curr;
+    e.Top = e.Next->Curr;
+  } else
+  {
+    e.Top = e.Curr;
+    e.Bot = e.Next->Curr;
+  }
+  SetDx(e);
+  e.PolyTyp = Pt;
+}
+//------------------------------------------------------------------------------
+
+TEdge* RemoveEdge(TEdge* e)
+{
+  //removes e from double_linked_list (but without removing from memory)
+  e->Prev->Next = e->Next;
+  e->Next->Prev = e->Prev;
+  TEdge* result = e->Next;
+  e->Prev = 0; //flag as removed (see ClipperBase.Clear)
+  return result;
+}
+//------------------------------------------------------------------------------
+
+inline void ReverseHorizontal(TEdge &e)
+{
+  //swap horizontal edges' Top and Bottom x's so they follow the natural
+  //progression of the bounds - ie so their xbots will align with the
+  //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
+  std::swap(e.Top.X, e.Bot.X);
+#ifdef use_xyz  
+  std::swap(e.Top.Z, e.Bot.Z);
+#endif
+}
+//------------------------------------------------------------------------------
+
+void SwapPoints(IntPoint &pt1, IntPoint &pt2)
+{
+  IntPoint tmp = pt1;
+  pt1 = pt2;
+  pt2 = tmp;
+}
+//------------------------------------------------------------------------------
+
+bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
+  IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
+{
+  //precondition: segments are Collinear.
+  if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y))
+  {
+    if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b);
+    if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b);
+    if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a;
+    if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b;
+    return pt1.X < pt2.X;
+  } else
+  {
+    if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b);
+    if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b);
+    if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a;
+    if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b;
+    return pt1.Y > pt2.Y;
+  }
+}
+//------------------------------------------------------------------------------
+
+bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
+{
+  OutPt *p = btmPt1->Prev;
+  while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev;
+  double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt));
+  p = btmPt1->Next;
+  while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next;
+  double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt));
+
+  p = btmPt2->Prev;
+  while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev;
+  double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt));
+  p = btmPt2->Next;
+  while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
+  double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
+
+  if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
+    std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
+      return Area(btmPt1) > 0; //if otherwise identical use orientation
+  else
+    return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
+}
+//------------------------------------------------------------------------------
+
+OutPt* GetBottomPt(OutPt *pp)
+{
+  OutPt* dups = 0;
+  OutPt* p = pp->Next;
+  while (p != pp)
+  {
+    if (p->Pt.Y > pp->Pt.Y)
+    {
+      pp = p;
+      dups = 0;
+    }
+    else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X)
+    {
+      if (p->Pt.X < pp->Pt.X)
+      {
+        dups = 0;
+        pp = p;
+      } else
+      {
+        if (p->Next != pp && p->Prev != pp) dups = p;
+      }
+    }
+    p = p->Next;
+  }
+  if (dups)
+  {
+    //there appears to be at least 2 vertices at BottomPt so ...
+    while (dups != p)
+    {
+      if (!FirstIsBottomPt(p, dups)) pp = dups;
+      dups = dups->Next;
+      while (dups->Pt != pp->Pt) dups = dups->Next;
+    }
+  }
+  return pp;
+}
+//------------------------------------------------------------------------------
+
+bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1,
+  const IntPoint pt2, const IntPoint pt3)
+{
+  if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
+    return false;
+  else if (pt1.X != pt3.X)
+    return (pt2.X > pt1.X) == (pt2.X < pt3.X);
+  else
+    return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y);
+}
+//------------------------------------------------------------------------------
+
+bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
+{
+  if (seg1a > seg1b) std::swap(seg1a, seg1b);
+  if (seg2a > seg2b) std::swap(seg2a, seg2b);
+  return (seg1a < seg2b) && (seg2a < seg1b);
+}
+
+//------------------------------------------------------------------------------
+// ClipperBase class methods ...
+//------------------------------------------------------------------------------
+
+ClipperBase::ClipperBase() //constructor
+{
+  m_CurrentLM = m_MinimaList.begin(); //begin() == end() here
+  m_UseFullRange = false;
+}
+//------------------------------------------------------------------------------
+
+ClipperBase::~ClipperBase() //destructor
+{
+  Clear();
+}
+//------------------------------------------------------------------------------
+
+void RangeTest(const IntPoint& Pt, bool& useFullRange)
+{
+  if (useFullRange)
+  {
+    if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) 
+      throw clipperException("Coordinate outside allowed range");
+  }
+  else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) 
+  {
+    useFullRange = true;
+    RangeTest(Pt, useFullRange);
+  }
+}
+//------------------------------------------------------------------------------
+
+TEdge* FindNextLocMin(TEdge* E)
+{
+  for (;;)
+  {
+    while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next;
+    if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break;
+    while (IsHorizontal(*E->Prev)) E = E->Prev;
+    TEdge* E2 = E;
+    while (IsHorizontal(*E)) E = E->Next;
+    if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz.
+    if (E2->Prev->Bot.X < E->Bot.X) E = E2;
+    break;
+  }
+  return E;
+}
+//------------------------------------------------------------------------------
+
+TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
+{
+  TEdge *Result = E;
+  TEdge *Horz = 0;
+
+  if (E->OutIdx == Skip)
+  {
+    //if edges still remain in the current bound beyond the skip edge then
+    //create another LocMin and call ProcessBound once more
+    if (NextIsForward)
+    {
+      while (E->Top.Y == E->Next->Bot.Y) E = E->Next;
+      //don't include top horizontals when parsing a bound a second time,
+      //they will be contained in the opposite bound ...
+      while (E != Result && IsHorizontal(*E)) E = E->Prev;
+    }
+    else
+    {
+      while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev;
+      while (E != Result && IsHorizontal(*E)) E = E->Next;
+    }
+
+    if (E == Result)
+    {
+      if (NextIsForward) Result = E->Next;
+      else Result = E->Prev;
+    }
+    else
+    {
+      //there are more edges in the bound beyond result starting with E
+      if (NextIsForward)
+        E = Result->Next;
+      else
+        E = Result->Prev;
+      MinimaList::value_type locMin;
+      locMin.Y = E->Bot.Y;
+      locMin.LeftBound = 0;
+      locMin.RightBound = E;
+      E->WindDelta = 0;
+      Result = ProcessBound(E, NextIsForward);
+      m_MinimaList.push_back(locMin);
+    }
+    return Result;
+  }
+
+  TEdge *EStart;
+
+  if (IsHorizontal(*E))
+  {
+    //We need to be careful with open paths because this may not be a
+    //true local minima (ie E may be following a skip edge).
+    //Also, consecutive horz. edges may start heading left before going right.
+    if (NextIsForward) 
+      EStart = E->Prev;
+    else 
+      EStart = E->Next;
+    if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge
+      {
+        if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X)
+          ReverseHorizontal(*E);
+      }
+      else if (EStart->Bot.X != E->Bot.X)
+        ReverseHorizontal(*E);
+  }
+  
+  EStart = E;
+  if (NextIsForward)
+  {
+    while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
+      Result = Result->Next;
+    if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
+    {
+      //nb: at the top of a bound, horizontals are added to the bound
+      //only when the preceding edge attaches to the horizontal's left vertex
+      //unless a Skip edge is encountered when that becomes the top divide
+      Horz = Result;
+      while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
+      if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
+    }
+    while (E != Result) 
+    {
+      E->NextInLML = E->Next;
+      if (IsHorizontal(*E) && E != EStart &&
+        E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
+      E = E->Next;
+    }
+    if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) 
+      ReverseHorizontal(*E);
+    Result = Result->Next; //move to the edge just beyond current bound
+  } else
+  {
+    while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip) 
+      Result = Result->Prev;
+    if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
+    {
+      Horz = Result;
+      while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
+      if (Horz->Next->Top.X == Result->Prev->Top.X ||
+          Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
+    }
+
+    while (E != Result)
+    {
+      E->NextInLML = E->Prev;
+      if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) 
+        ReverseHorizontal(*E);
+      E = E->Prev;
+    }
+    if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) 
+      ReverseHorizontal(*E);
+    Result = Result->Prev; //move to the edge just beyond current bound
+  }
+
+  return Result;
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
+{
+#ifdef use_lines
+  if (!Closed && PolyTyp == ptClip)
+    throw clipperException("AddPath: Open paths must be subject.");
+#else
+  if (!Closed)
+    throw clipperException("AddPath: Open paths have been disabled.");
+#endif
+
+  int highI = (int)pg.size() -1;
+  if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI;
+  while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
+  if ((Closed && highI < 2) || (!Closed && highI < 1)) return false;
+
+  //create a new edge array ...
+  TEdge *edges = new TEdge [highI +1];
+
+  bool IsFlat = true;
+  //1. Basic (first) edge initialization ...
+  try
+  {
+    edges[1].Curr = pg[1];
+    RangeTest(pg[0], m_UseFullRange);
+    RangeTest(pg[highI], m_UseFullRange);
+    InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
+    InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
+    for (int i = highI - 1; i >= 1; --i)
+    {
+      RangeTest(pg[i], m_UseFullRange);
+      InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
+    }
+  }
+  catch(...)
+  {
+    delete [] edges;
+    throw; //range test fails
+  }
+  TEdge *eStart = &edges[0];
+
+  //2. Remove duplicate vertices, and (when closed) collinear edges ...
+  TEdge *E = eStart, *eLoopStop = eStart;
+  for (;;)
+  {
+    //nb: allows matching start and end points when not Closed ...
+    if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart))
+    {
+      if (E == E->Next) break;
+      if (E == eStart) eStart = E->Next;
+      E = RemoveEdge(E);
+      eLoopStop = E;
+      continue;
+    }
+    if (E->Prev == E->Next) 
+      break; //only two vertices
+    else if (Closed &&
+      SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && 
+      (!m_PreserveCollinear ||
+      !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr)))
+    {
+      //Collinear edges are allowed for open paths but in closed paths
+      //the default is to merge adjacent collinear edges into a single edge.
+      //However, if the PreserveCollinear property is enabled, only overlapping
+      //collinear edges (ie spikes) will be removed from closed paths.
+      if (E == eStart) eStart = E->Next;
+      E = RemoveEdge(E);
+      E = E->Prev;
+      eLoopStop = E;
+      continue;
+    }
+    E = E->Next;
+    if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break;
+  }
+
+  if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next)))
+  {
+    delete [] edges;
+    return false;
+  }
+
+  if (!Closed)
+  { 
+    m_HasOpenPaths = true;
+    eStart->Prev->OutIdx = Skip;
+  }
+
+  //3. Do second stage of edge initialization ...
+  E = eStart;
+  do
+  {
+    InitEdge2(*E, PolyTyp);
+    E = E->Next;
+    if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false;
+  }
+  while (E != eStart);
+
+  //4. Finally, add edge bounds to LocalMinima list ...
+
+  //Totally flat paths must be handled differently when adding them
+  //to LocalMinima list to avoid endless loops etc ...
+  if (IsFlat) 
+  {
+    if (Closed) 
+    {
+      delete [] edges;
+      return false;
+    }
+    E->Prev->OutIdx = Skip;
+    MinimaList::value_type locMin;
+    locMin.Y = E->Bot.Y;
+    locMin.LeftBound = 0;
+    locMin.RightBound = E;
+    locMin.RightBound->Side = esRight;
+    locMin.RightBound->WindDelta = 0;
+    for (;;)
+    {
+      if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
+      if (E->Next->OutIdx == Skip) break;
+      E->NextInLML = E->Next;
+      E = E->Next;
+    }
+    m_MinimaList.push_back(locMin);
+    m_edges.push_back(edges);
+	  return true;
+  }
+
+  m_edges.push_back(edges);
+  bool leftBoundIsForward;
+  TEdge* EMin = 0;
+
+  //workaround to avoid an endless loop in the while loop below when
+  //open paths have matching start and end points ...
+  if (E->Prev->Bot == E->Prev->Top) E = E->Next;
+
+  for (;;)
+  {
+    E = FindNextLocMin(E);
+    if (E == EMin) break;
+    else if (!EMin) EMin = E;
+
+    //E and E.Prev now share a local minima (left aligned if horizontal).
+    //Compare their slopes to find which starts which bound ...
+    MinimaList::value_type locMin;
+    locMin.Y = E->Bot.Y;
+    if (E->Dx < E->Prev->Dx) 
+    {
+      locMin.LeftBound = E->Prev;
+      locMin.RightBound = E;
+      leftBoundIsForward = false; //Q.nextInLML = Q.prev
+    } else
+    {
+      locMin.LeftBound = E;
+      locMin.RightBound = E->Prev;
+      leftBoundIsForward = true; //Q.nextInLML = Q.next
+    }
+
+    if (!Closed) locMin.LeftBound->WindDelta = 0;
+    else if (locMin.LeftBound->Next == locMin.RightBound)
+      locMin.LeftBound->WindDelta = -1;
+    else locMin.LeftBound->WindDelta = 1;
+    locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta;
+
+    E = ProcessBound(locMin.LeftBound, leftBoundIsForward);
+    if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward);
+
+    TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward);
+    if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward);
+
+    if (locMin.LeftBound->OutIdx == Skip)
+      locMin.LeftBound = 0;
+    else if (locMin.RightBound->OutIdx == Skip)
+      locMin.RightBound = 0;
+    m_MinimaList.push_back(locMin);
+    if (!leftBoundIsForward) E = E2;
+  }
+  return true;
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
+{
+  bool result = false;
+  for (Paths::size_type i = 0; i < ppg.size(); ++i)
+    if (AddPath(ppg[i], PolyTyp, Closed)) result = true;
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::Clear()
+{
+  DisposeLocalMinimaList();
+  for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
+  {
+    TEdge* edges = m_edges[i];
+    delete [] edges;
+  }
+  m_edges.clear();
+  m_UseFullRange = false;
+  m_HasOpenPaths = false;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::Reset()
+{
+  m_CurrentLM = m_MinimaList.begin();
+  if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
+  std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());
+
+  m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
+  //reset all edges ...
+  for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
+  {
+    InsertScanbeam(lm->Y);
+    TEdge* e = lm->LeftBound;
+    if (e)
+    {
+      e->Curr = e->Bot;
+      e->Side = esLeft;
+      e->OutIdx = Unassigned;
+    }
+
+    e = lm->RightBound;
+    if (e)
+    {
+      e->Curr = e->Bot;
+      e->Side = esRight;
+      e->OutIdx = Unassigned;
+    }
+  }
+  m_ActiveEdges = 0;
+  m_CurrentLM = m_MinimaList.begin();
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeLocalMinimaList()
+{
+  m_MinimaList.clear();
+  m_CurrentLM = m_MinimaList.begin();
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
+{
+  if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false;
+  locMin = &(*m_CurrentLM);
+  ++m_CurrentLM;
+  return true;
+}
+//------------------------------------------------------------------------------
+
+IntRect ClipperBase::GetBounds()
+{
+  IntRect result;
+  MinimaList::iterator lm = m_MinimaList.begin();
+  if (lm == m_MinimaList.end())
+  {
+    result.left = result.top = result.right = result.bottom = 0;
+    return result;
+  }
+  result.left = lm->LeftBound->Bot.X;
+  result.top = lm->LeftBound->Bot.Y;
+  result.right = lm->LeftBound->Bot.X;
+  result.bottom = lm->LeftBound->Bot.Y;
+  while (lm != m_MinimaList.end())
+  {
+    //todo - needs fixing for open paths
+    result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y);
+    TEdge* e = lm->LeftBound;
+    for (;;) {
+      TEdge* bottomE = e;
+      while (e->NextInLML)
+      {
+        if (e->Bot.X < result.left) result.left = e->Bot.X;
+        if (e->Bot.X > result.right) result.right = e->Bot.X;
+        e = e->NextInLML;
+      }
+      result.left = std::min(result.left, e->Bot.X);
+      result.right = std::max(result.right, e->Bot.X);
+      result.left = std::min(result.left, e->Top.X);
+      result.right = std::max(result.right, e->Top.X);
+      result.top = std::min(result.top, e->Top.Y);
+      if (bottomE == lm->LeftBound) e = lm->RightBound;
+      else break;
+    }
+    ++lm;
+  }
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::InsertScanbeam(const cInt Y)
+{
+  m_Scanbeam.push(Y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::PopScanbeam(cInt &Y)
+{
+  if (m_Scanbeam.empty()) return false;
+  Y = m_Scanbeam.top();
+  m_Scanbeam.pop();
+  while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
+  return true;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeAllOutRecs(){
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+    DisposeOutRec(i);
+  m_PolyOuts.clear();
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
+{
+  OutRec *outRec = m_PolyOuts[index];
+  if (outRec->Pts) DisposeOutPts(outRec->Pts);
+  delete outRec;
+  m_PolyOuts[index] = 0;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DeleteFromAEL(TEdge *e)
+{
+  TEdge* AelPrev = e->PrevInAEL;
+  TEdge* AelNext = e->NextInAEL;
+  if (!AelPrev &&  !AelNext && (e != m_ActiveEdges)) return; //already deleted
+  if (AelPrev) AelPrev->NextInAEL = AelNext;
+  else m_ActiveEdges = AelNext;
+  if (AelNext) AelNext->PrevInAEL = AelPrev;
+  e->NextInAEL = 0;
+  e->PrevInAEL = 0;
+}
+//------------------------------------------------------------------------------
+
+OutRec* ClipperBase::CreateOutRec()
+{
+  OutRec* result = new OutRec;
+  result->IsHole = false;
+  result->IsOpen = false;
+  result->FirstLeft = 0;
+  result->Pts = 0;
+  result->BottomPt = 0;
+  result->PolyNd = 0;
+  m_PolyOuts.push_back(result);
+  result->Idx = (int)m_PolyOuts.size() - 1;
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+{
+  //check that one or other edge hasn't already been removed from AEL ...
+  if (Edge1->NextInAEL == Edge1->PrevInAEL ||
+    Edge2->NextInAEL == Edge2->PrevInAEL) return;
+
+  if (Edge1->NextInAEL == Edge2)
+  {
+    TEdge* Next = Edge2->NextInAEL;
+    if (Next) Next->PrevInAEL = Edge1;
+    TEdge* Prev = Edge1->PrevInAEL;
+    if (Prev) Prev->NextInAEL = Edge2;
+    Edge2->PrevInAEL = Prev;
+    Edge2->NextInAEL = Edge1;
+    Edge1->PrevInAEL = Edge2;
+    Edge1->NextInAEL = Next;
+  }
+  else if (Edge2->NextInAEL == Edge1)
+  {
+    TEdge* Next = Edge1->NextInAEL;
+    if (Next) Next->PrevInAEL = Edge2;
+    TEdge* Prev = Edge2->PrevInAEL;
+    if (Prev) Prev->NextInAEL = Edge1;
+    Edge1->PrevInAEL = Prev;
+    Edge1->NextInAEL = Edge2;
+    Edge2->PrevInAEL = Edge1;
+    Edge2->NextInAEL = Next;
+  }
+  else
+  {
+    TEdge* Next = Edge1->NextInAEL;
+    TEdge* Prev = Edge1->PrevInAEL;
+    Edge1->NextInAEL = Edge2->NextInAEL;
+    if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
+    Edge1->PrevInAEL = Edge2->PrevInAEL;
+    if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
+    Edge2->NextInAEL = Next;
+    if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
+    Edge2->PrevInAEL = Prev;
+    if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
+  }
+
+  if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
+  else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
+{
+  if (!e->NextInLML) 
+    throw clipperException("UpdateEdgeIntoAEL: invalid call");
+
+  e->NextInLML->OutIdx = e->OutIdx;
+  TEdge* AelPrev = e->PrevInAEL;
+  TEdge* AelNext = e->NextInAEL;
+  if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
+  else m_ActiveEdges = e->NextInLML;
+  if (AelNext) AelNext->PrevInAEL = e->NextInLML;
+  e->NextInLML->Side = e->Side;
+  e->NextInLML->WindDelta = e->WindDelta;
+  e->NextInLML->WindCnt = e->WindCnt;
+  e->NextInLML->WindCnt2 = e->WindCnt2;
+  e = e->NextInLML;
+  e->Curr = e->Bot;
+  e->PrevInAEL = AelPrev;
+  e->NextInAEL = AelNext;
+  if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::LocalMinimaPending()
+{
+  return (m_CurrentLM != m_MinimaList.end());
+}
+
+//------------------------------------------------------------------------------
+// TClipper methods ...
+//------------------------------------------------------------------------------
+
+Clipper::Clipper(int initOptions) : ClipperBase() //constructor
+{
+  m_ExecuteLocked = false;
+  m_UseFullRange = false;
+  m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
+  m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
+  m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
+  m_HasOpenPaths = false;
+#ifdef use_xyz  
+  m_ZFill = 0;
+#endif
+}
+//------------------------------------------------------------------------------
+
+#ifdef use_xyz  
+void Clipper::ZFillFunction(ZFillCallback zFillFunc)
+{  
+  m_ZFill = zFillFunc;
+}
+//------------------------------------------------------------------------------
+#endif
+
+bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
+{
+    return Execute(clipType, solution, fillType, fillType);
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType)
+{
+    return Execute(clipType, polytree, fillType, fillType);
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::Execute(ClipType clipType, Paths &solution,
+    PolyFillType subjFillType, PolyFillType clipFillType)
+{
+  if( m_ExecuteLocked ) return false;
+  if (m_HasOpenPaths)
+    throw clipperException("Error: PolyTree struct is needed for open path clipping.");
+  m_ExecuteLocked = true;
+  solution.resize(0);
+  m_SubjFillType = subjFillType;
+  m_ClipFillType = clipFillType;
+  m_ClipType = clipType;
+  m_UsingPolyTree = false;
+  bool succeeded = ExecuteInternal();
+  if (succeeded) BuildResult(solution);
+  DisposeAllOutRecs();
+  m_ExecuteLocked = false;
+  return succeeded;
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::Execute(ClipType clipType, PolyTree& polytree,
+    PolyFillType subjFillType, PolyFillType clipFillType)
+{
+  if( m_ExecuteLocked ) return false;
+  m_ExecuteLocked = true;
+  m_SubjFillType = subjFillType;
+  m_ClipFillType = clipFillType;
+  m_ClipType = clipType;
+  m_UsingPolyTree = true;
+  bool succeeded = ExecuteInternal();
+  if (succeeded) BuildResult2(polytree);
+  DisposeAllOutRecs();
+  m_ExecuteLocked = false;
+  return succeeded;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::FixHoleLinkage(OutRec &outrec)
+{
+  //skip OutRecs that (a) contain outermost polygons or
+  //(b) already have the correct owner/child linkage ...
+  if (!outrec.FirstLeft ||                
+      (outrec.IsHole != outrec.FirstLeft->IsHole &&
+      outrec.FirstLeft->Pts)) return;
+
+  OutRec* orfl = outrec.FirstLeft;
+  while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts))
+      orfl = orfl->FirstLeft;
+  outrec.FirstLeft = orfl;
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::ExecuteInternal()
+{
+  bool succeeded = true;
+  try {
+    Reset();
+    m_Maxima = MaximaList();
+    m_SortedEdges = 0;
+
+    succeeded = true;
+    cInt botY, topY;
+    if (!PopScanbeam(botY)) return false;
+    InsertLocalMinimaIntoAEL(botY);
+    while (PopScanbeam(topY) || LocalMinimaPending())
+    {
+      ProcessHorizontals();
+	    ClearGhostJoins();
+      if (!ProcessIntersections(topY))
+      {
+        succeeded = false;
+        break;
+      }
+      ProcessEdgesAtTopOfScanbeam(topY);
+      botY = topY;
+      InsertLocalMinimaIntoAEL(botY);
+    }
+  }
+  catch(...) 
+  {
+    succeeded = false;
+  }
+
+  if (succeeded)
+  {
+    //fix orientations ...
+    for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+    {
+      OutRec *outRec = m_PolyOuts[i];
+      if (!outRec->Pts || outRec->IsOpen) continue;
+      if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0))
+        ReversePolyPtLinks(outRec->Pts);
+    }
+
+    if (!m_Joins.empty()) JoinCommonEdges();
+
+    //unfortunately FixupOutPolygon() must be done after JoinCommonEdges()
+    for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+    {
+      OutRec *outRec = m_PolyOuts[i];
+      if (!outRec->Pts) continue;
+      if (outRec->IsOpen)
+        FixupOutPolyline(*outRec);
+      else
+        FixupOutPolygon(*outRec);
+    }
+
+    if (m_StrictSimple) DoSimplePolygons();
+  }
+
+  ClearJoins();
+  ClearGhostJoins();
+  return succeeded;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::SetWindingCount(TEdge &edge)
+{
+  TEdge *e = edge.PrevInAEL;
+  //find the edge of the same polytype that immediately preceeds 'edge' in AEL
+  while (e  && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
+  if (!e)
+  {
+    if (edge.WindDelta == 0)
+    {
+      PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
+      edge.WindCnt = (pft == pftNegative ? -1 : 1);
+    }
+    else
+      edge.WindCnt = edge.WindDelta;
+    edge.WindCnt2 = 0;
+    e = m_ActiveEdges; //ie get ready to calc WindCnt2
+  }   
+  else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
+  {
+    edge.WindCnt = 1;
+    edge.WindCnt2 = e->WindCnt2;
+    e = e->NextInAEL; //ie get ready to calc WindCnt2
+  }
+  else if (IsEvenOddFillType(edge))
+  {
+    //EvenOdd filling ...
+    if (edge.WindDelta == 0)
+    {
+      //are we inside a subj polygon ...
+      bool Inside = true;
+      TEdge *e2 = e->PrevInAEL;
+      while (e2)
+      {
+        if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) 
+          Inside = !Inside;
+        e2 = e2->PrevInAEL;
+      }
+      edge.WindCnt = (Inside ? 0 : 1);
+    }
+    else
+    {
+      edge.WindCnt = edge.WindDelta;
+    }
+    edge.WindCnt2 = e->WindCnt2;
+    e = e->NextInAEL; //ie get ready to calc WindCnt2
+  } 
+  else
+  {
+    //nonZero, Positive or Negative filling ...
+    if (e->WindCnt * e->WindDelta < 0)
+    {
+      //prev edge is 'decreasing' WindCount (WC) toward zero
+      //so we're outside the previous polygon ...
+      if (Abs(e->WindCnt) > 1)
+      {
+        //outside prev poly but still inside another.
+        //when reversing direction of prev poly use the same WC 
+        if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
+        //otherwise continue to 'decrease' WC ...
+        else edge.WindCnt = e->WindCnt + edge.WindDelta;
+      } 
+      else
+        //now outside all polys of same polytype so set own WC ...
+        edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
+    } else
+    {
+      //prev edge is 'increasing' WindCount (WC) away from zero
+      //so we're inside the previous polygon ...
+      if (edge.WindDelta == 0) 
+        edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
+      //if wind direction is reversing prev then use same WC
+      else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
+      //otherwise add to WC ...
+      else edge.WindCnt = e->WindCnt + edge.WindDelta;
+    }
+    edge.WindCnt2 = e->WindCnt2;
+    e = e->NextInAEL; //ie get ready to calc WindCnt2
+  }
+
+  //update WindCnt2 ...
+  if (IsEvenOddAltFillType(edge))
+  {
+    //EvenOdd filling ...
+    while (e != &edge)
+    {
+      if (e->WindDelta != 0)
+        edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0);
+      e = e->NextInAEL;
+    }
+  } else
+  {
+    //nonZero, Positive or Negative filling ...
+    while ( e != &edge )
+    {
+      edge.WindCnt2 += e->WindDelta;
+      e = e->NextInAEL;
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::IsEvenOddFillType(const TEdge& edge) const
+{
+  if (edge.PolyTyp == ptSubject)
+    return m_SubjFillType == pftEvenOdd; else
+    return m_ClipFillType == pftEvenOdd;
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
+{
+  if (edge.PolyTyp == ptSubject)
+    return m_ClipFillType == pftEvenOdd; else
+    return m_SubjFillType == pftEvenOdd;
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::IsContributing(const TEdge& edge) const
+{
+  PolyFillType pft, pft2;
+  if (edge.PolyTyp == ptSubject)
+  {
+    pft = m_SubjFillType;
+    pft2 = m_ClipFillType;
+  } else
+  {
+    pft = m_ClipFillType;
+    pft2 = m_SubjFillType;
+  }
+
+  switch(pft)
+  {
+    case pftEvenOdd: 
+      //return false if a subj line has been flagged as inside a subj polygon
+      if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;
+      break;
+    case pftNonZero:
+      if (Abs(edge.WindCnt) != 1) return false;
+      break;
+    case pftPositive: 
+      if (edge.WindCnt != 1) return false;
+      break;
+    default: //pftNegative
+      if (edge.WindCnt != -1) return false;
+  }
+
+  switch(m_ClipType)
+  {
+    case ctIntersection:
+      switch(pft2)
+      {
+        case pftEvenOdd: 
+        case pftNonZero: 
+          return (edge.WindCnt2 != 0);
+        case pftPositive: 
+          return (edge.WindCnt2 > 0);
+        default: 
+          return (edge.WindCnt2 < 0);
+      }
+      break;
+    case ctUnion:
+      switch(pft2)
+      {
+        case pftEvenOdd: 
+        case pftNonZero: 
+          return (edge.WindCnt2 == 0);
+        case pftPositive: 
+          return (edge.WindCnt2 <= 0);
+        default: 
+          return (edge.WindCnt2 >= 0);
+      }
+      break;
+    case ctDifference:
+      if (edge.PolyTyp == ptSubject)
+        switch(pft2)
+        {
+          case pftEvenOdd: 
+          case pftNonZero: 
+            return (edge.WindCnt2 == 0);
+          case pftPositive: 
+            return (edge.WindCnt2 <= 0);
+          default: 
+            return (edge.WindCnt2 >= 0);
+        }
+      else
+        switch(pft2)
+        {
+          case pftEvenOdd: 
+          case pftNonZero: 
+            return (edge.WindCnt2 != 0);
+          case pftPositive: 
+            return (edge.WindCnt2 > 0);
+          default: 
+            return (edge.WindCnt2 < 0);
+        }
+      break;
+    case ctXor:
+      if (edge.WindDelta == 0) //XOr always contributing unless open
+        switch(pft2)
+        {
+          case pftEvenOdd: 
+          case pftNonZero: 
+            return (edge.WindCnt2 == 0);
+          case pftPositive: 
+            return (edge.WindCnt2 <= 0);
+          default: 
+            return (edge.WindCnt2 >= 0);
+        }
+      else 
+        return true;
+      break;
+    default:
+      return true;
+  }
+}
+//------------------------------------------------------------------------------
+
+OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
+{
+  OutPt* result;
+  TEdge *e, *prevE;
+  if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx ))
+  {
+    result = AddOutPt(e1, Pt);
+    e2->OutIdx = e1->OutIdx;
+    e1->Side = esLeft;
+    e2->Side = esRight;
+    e = e1;
+    if (e->PrevInAEL == e2)
+      prevE = e2->PrevInAEL; 
+    else
+      prevE = e->PrevInAEL;
+  } else
+  {
+    result = AddOutPt(e2, Pt);
+    e1->OutIdx = e2->OutIdx;
+    e1->Side = esRight;
+    e2->Side = esLeft;
+    e = e2;
+    if (e->PrevInAEL == e1)
+        prevE = e1->PrevInAEL;
+    else
+        prevE = e->PrevInAEL;
+  }
+
+  if (prevE && prevE->OutIdx >= 0 && prevE->Top.Y < Pt.Y && e->Top.Y < Pt.Y) 
+  {
+    cInt xPrev = TopX(*prevE, Pt.Y);
+    cInt xE = TopX(*e, Pt.Y);
+    if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
+      SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange))
+    {
+      OutPt* outPt = AddOutPt(prevE, Pt);
+      AddJoin(result, outPt, e->Top);
+    }
+  }
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
+{
+  AddOutPt( e1, Pt );
+  if (e2->WindDelta == 0) AddOutPt(e2, Pt);
+  if( e1->OutIdx == e2->OutIdx )
+  {
+    e1->OutIdx = Unassigned;
+    e2->OutIdx = Unassigned;
+  }
+  else if (e1->OutIdx < e2->OutIdx) 
+    AppendPolygon(e1, e2); 
+  else 
+    AppendPolygon(e2, e1);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::AddEdgeToSEL(TEdge *edge)
+{
+  //SEL pointers in PEdge are reused to build a list of horizontal edges.
+  //However, we don't need to worry about order with horizontal edge processing.
+  if( !m_SortedEdges )
+  {
+    m_SortedEdges = edge;
+    edge->PrevInSEL = 0;
+    edge->NextInSEL = 0;
+  }
+  else
+  {
+    edge->NextInSEL = m_SortedEdges;
+    edge->PrevInSEL = 0;
+    m_SortedEdges->PrevInSEL = edge;
+    m_SortedEdges = edge;
+  }
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::PopEdgeFromSEL(TEdge *&edge)
+{
+  if (!m_SortedEdges) return false;
+  edge = m_SortedEdges;
+  DeleteFromSEL(m_SortedEdges);
+  return true;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::CopyAELToSEL()
+{
+  TEdge* e = m_ActiveEdges;
+  m_SortedEdges = e;
+  while ( e )
+  {
+    e->PrevInSEL = e->PrevInAEL;
+    e->NextInSEL = e->NextInAEL;
+    e = e->NextInAEL;
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt)
+{
+  Join* j = new Join;
+  j->OutPt1 = op1;
+  j->OutPt2 = op2;
+  j->OffPt = OffPt;
+  m_Joins.push_back(j);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::ClearJoins()
+{
+  for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
+    delete m_Joins[i];
+  m_Joins.resize(0);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::ClearGhostJoins()
+{
+  for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
+    delete m_GhostJoins[i];
+  m_GhostJoins.resize(0);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
+{
+  Join* j = new Join;
+  j->OutPt1 = op;
+  j->OutPt2 = 0;
+  j->OffPt = OffPt;
+  m_GhostJoins.push_back(j);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
+{
+  const LocalMinimum *lm;
+  while (PopLocalMinima(botY, lm))
+  {
+    TEdge* lb = lm->LeftBound;
+    TEdge* rb = lm->RightBound;
+    
+    OutPt *Op1 = 0;
+    if (!lb)
+    {
+      //nb: don't insert LB into either AEL or SEL
+      InsertEdgeIntoAEL(rb, 0);
+      SetWindingCount(*rb);
+      if (IsContributing(*rb))
+        Op1 = AddOutPt(rb, rb->Bot); 
+    } 
+    else if (!rb)
+    {
+      InsertEdgeIntoAEL(lb, 0);
+      SetWindingCount(*lb);
+      if (IsContributing(*lb))
+        Op1 = AddOutPt(lb, lb->Bot);
+      InsertScanbeam(lb->Top.Y);
+    }
+    else
+    {
+      InsertEdgeIntoAEL(lb, 0);
+      InsertEdgeIntoAEL(rb, lb);
+      SetWindingCount( *lb );
+      rb->WindCnt = lb->WindCnt;
+      rb->WindCnt2 = lb->WindCnt2;
+      if (IsContributing(*lb))
+        Op1 = AddLocalMinPoly(lb, rb, lb->Bot);      
+      InsertScanbeam(lb->Top.Y);
+    }
+
+     if (rb)
+     {
+		 if (IsHorizontal(*rb))
+		 {
+			 AddEdgeToSEL(rb);
+			 if (rb->NextInLML) 
+				 InsertScanbeam(rb->NextInLML->Top.Y);
+		 }
+		 else InsertScanbeam( rb->Top.Y );
+     }
+
+    if (!lb || !rb) continue;
+
+    //if any output polygons share an edge, they'll need joining later ...
+    if (Op1 && IsHorizontal(*rb) && 
+      m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
+    {
+      for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
+      {
+        Join* jr = m_GhostJoins[i];
+        //if the horizontal Rb and a 'ghost' horizontal overlap, then convert
+        //the 'ghost' join to a real join ready for later ...
+        if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X))
+          AddJoin(jr->OutPt1, Op1, jr->OffPt);
+      }
+    }
+
+    if (lb->OutIdx >= 0 && lb->PrevInAEL && 
+      lb->PrevInAEL->Curr.X == lb->Bot.X &&
+      lb->PrevInAEL->OutIdx >= 0 &&
+      SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
+      (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
+    {
+        OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
+        AddJoin(Op1, Op2, lb->Top);
+    }
+
+    if(lb->NextInAEL != rb)
+    {
+
+      if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
+        SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
+        (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
+      {
+          OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
+          AddJoin(Op1, Op2, rb->Top);
+      }
+
+      TEdge* e = lb->NextInAEL;
+      if (e)
+      {
+        while( e != rb )
+        {
+          //nb: For calculating winding counts etc, IntersectEdges() assumes
+          //that param1 will be to the Right of param2 ABOVE the intersection ...
+          IntersectEdges(rb , e , lb->Curr); //order important here
+          e = e->NextInAEL;
+        }
+      }
+    }
+    
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::DeleteFromSEL(TEdge *e)
+{
+  TEdge* SelPrev = e->PrevInSEL;
+  TEdge* SelNext = e->NextInSEL;
+  if( !SelPrev &&  !SelNext && (e != m_SortedEdges) ) return; //already deleted
+  if( SelPrev ) SelPrev->NextInSEL = SelNext;
+  else m_SortedEdges = SelNext;
+  if( SelNext ) SelNext->PrevInSEL = SelPrev;
+  e->NextInSEL = 0;
+  e->PrevInSEL = 0;
+}
+//------------------------------------------------------------------------------
+
+#ifdef use_xyz
+void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
+{
+  if (pt.Z != 0 || !m_ZFill) return;
+  else if (pt == e1.Bot) pt.Z = e1.Bot.Z;
+  else if (pt == e1.Top) pt.Z = e1.Top.Z;
+  else if (pt == e2.Bot) pt.Z = e2.Bot.Z;
+  else if (pt == e2.Top) pt.Z = e2.Top.Z;
+  else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt); 
+}
+//------------------------------------------------------------------------------
+#endif
+
+void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
+{
+  bool e1Contributing = ( e1->OutIdx >= 0 );
+  bool e2Contributing = ( e2->OutIdx >= 0 );
+
+#ifdef use_xyz
+        SetZ(Pt, *e1, *e2);
+#endif
+
+#ifdef use_lines
+  //if either edge is on an OPEN path ...
+  if (e1->WindDelta == 0 || e2->WindDelta == 0)
+  {
+    //ignore subject-subject open path intersections UNLESS they
+    //are both open paths, AND they are both 'contributing maximas' ...
+	if (e1->WindDelta == 0 && e2->WindDelta == 0) return;
+
+    //if intersecting a subj line with a subj poly ...
+    else if (e1->PolyTyp == e2->PolyTyp && 
+      e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
+    {
+      if (e1->WindDelta == 0)
+      {
+        if (e2Contributing)
+        {
+          AddOutPt(e1, Pt);
+          if (e1Contributing) e1->OutIdx = Unassigned;
+        }
+      }
+      else
+      {
+        if (e1Contributing)
+        {
+          AddOutPt(e2, Pt);
+          if (e2Contributing) e2->OutIdx = Unassigned;
+        }
+      }
+    }
+    else if (e1->PolyTyp != e2->PolyTyp)
+    {
+      //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
+      if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && 
+        (m_ClipType != ctUnion || e2->WindCnt2 == 0))
+      {
+        AddOutPt(e1, Pt);
+        if (e1Contributing) e1->OutIdx = Unassigned;
+      }
+      else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && 
+        (m_ClipType != ctUnion || e1->WindCnt2 == 0))
+      {
+        AddOutPt(e2, Pt);
+        if (e2Contributing) e2->OutIdx = Unassigned;
+      }
+    }
+    return;
+  }
+#endif
+
+  //update winding counts...
+  //assumes that e1 will be to the Right of e2 ABOVE the intersection
+  if ( e1->PolyTyp == e2->PolyTyp )
+  {
+    if ( IsEvenOddFillType( *e1) )
+    {
+      int oldE1WindCnt = e1->WindCnt;
+      e1->WindCnt = e2->WindCnt;
+      e2->WindCnt = oldE1WindCnt;
+    } else
+    {
+      if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
+      else e1->WindCnt += e2->WindDelta;
+      if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
+      else e2->WindCnt -= e1->WindDelta;
+    }
+  } else
+  {
+    if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
+    else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
+    if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
+    else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
+  }
+
+  PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
+  if (e1->PolyTyp == ptSubject)
+  {
+    e1FillType = m_SubjFillType;
+    e1FillType2 = m_ClipFillType;
+  } else
+  {
+    e1FillType = m_ClipFillType;
+    e1FillType2 = m_SubjFillType;
+  }
+  if (e2->PolyTyp == ptSubject)
+  {
+    e2FillType = m_SubjFillType;
+    e2FillType2 = m_ClipFillType;
+  } else
+  {
+    e2FillType = m_ClipFillType;
+    e2FillType2 = m_SubjFillType;
+  }
+
+  cInt e1Wc, e2Wc;
+  switch (e1FillType)
+  {
+    case pftPositive: e1Wc = e1->WindCnt; break;
+    case pftNegative: e1Wc = -e1->WindCnt; break;
+    default: e1Wc = Abs(e1->WindCnt);
+  }
+  switch(e2FillType)
+  {
+    case pftPositive: e2Wc = e2->WindCnt; break;
+    case pftNegative: e2Wc = -e2->WindCnt; break;
+    default: e2Wc = Abs(e2->WindCnt);
+  }
+
+  if ( e1Contributing && e2Contributing )
+  {
+    if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
+      (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
+    {
+      AddLocalMaxPoly(e1, e2, Pt); 
+    }
+    else
+    {
+      AddOutPt(e1, Pt);
+      AddOutPt(e2, Pt);
+      SwapSides( *e1 , *e2 );
+      SwapPolyIndexes( *e1 , *e2 );
+    }
+  }
+  else if ( e1Contributing )
+  {
+    if (e2Wc == 0 || e2Wc == 1) 
+    {
+      AddOutPt(e1, Pt);
+      SwapSides(*e1, *e2);
+      SwapPolyIndexes(*e1, *e2);
+    }
+  }
+  else if ( e2Contributing )
+  {
+    if (e1Wc == 0 || e1Wc == 1) 
+    {
+      AddOutPt(e2, Pt);
+      SwapSides(*e1, *e2);
+      SwapPolyIndexes(*e1, *e2);
+    }
+  } 
+  else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
+  {
+    //neither edge is currently contributing ...
+
+    cInt e1Wc2, e2Wc2;
+    switch (e1FillType2)
+    {
+      case pftPositive: e1Wc2 = e1->WindCnt2; break;
+      case pftNegative : e1Wc2 = -e1->WindCnt2; break;
+      default: e1Wc2 = Abs(e1->WindCnt2);
+    }
+    switch (e2FillType2)
+    {
+      case pftPositive: e2Wc2 = e2->WindCnt2; break;
+      case pftNegative: e2Wc2 = -e2->WindCnt2; break;
+      default: e2Wc2 = Abs(e2->WindCnt2);
+    }
+
+    if (e1->PolyTyp != e2->PolyTyp)
+    {
+      AddLocalMinPoly(e1, e2, Pt);
+    }
+    else if (e1Wc == 1 && e2Wc == 1)
+      switch( m_ClipType ) {
+        case ctIntersection:
+          if (e1Wc2 > 0 && e2Wc2 > 0)
+            AddLocalMinPoly(e1, e2, Pt);
+          break;
+        case ctUnion:
+          if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
+            AddLocalMinPoly(e1, e2, Pt);
+          break;
+        case ctDifference:
+          if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
+              ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
+                AddLocalMinPoly(e1, e2, Pt);
+          break;
+        case ctXor:
+          AddLocalMinPoly(e1, e2, Pt);
+      }
+    else
+      SwapSides( *e1, *e2 );
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
+{
+  TEdge *e2 = e->PrevInAEL;
+  TEdge *eTmp = 0;
+  while (e2)
+  {
+    if (e2->OutIdx >= 0 && e2->WindDelta != 0)
+    {
+      if (!eTmp) eTmp = e2;
+      else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;        
+    }
+    e2 = e2->PrevInAEL;
+  }
+  if (!eTmp)
+  {
+    outrec->FirstLeft = 0;
+    outrec->IsHole = false;
+  }
+  else
+  {
+    outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
+    outrec->IsHole = !outrec->FirstLeft->IsHole;
+  }
+}
+//------------------------------------------------------------------------------
+
+OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
+{
+  //work out which polygon fragment has the correct hole state ...
+  if (!outRec1->BottomPt) 
+    outRec1->BottomPt = GetBottomPt(outRec1->Pts);
+  if (!outRec2->BottomPt) 
+    outRec2->BottomPt = GetBottomPt(outRec2->Pts);
+  OutPt *OutPt1 = outRec1->BottomPt;
+  OutPt *OutPt2 = outRec2->BottomPt;
+  if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1;
+  else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2;
+  else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1;
+  else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2;
+  else if (OutPt1->Next == OutPt1) return outRec2;
+  else if (OutPt2->Next == OutPt2) return outRec1;
+  else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1;
+  else return outRec2;
+}
+//------------------------------------------------------------------------------
+
+bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
+{
+  do
+  {
+    outRec1 = outRec1->FirstLeft;
+    if (outRec1 == outRec2) return true;
+  } while (outRec1);
+  return false;
+}
+//------------------------------------------------------------------------------
+
+OutRec* Clipper::GetOutRec(int Idx)
+{
+  OutRec* outrec = m_PolyOuts[Idx];
+  while (outrec != m_PolyOuts[outrec->Idx])
+    outrec = m_PolyOuts[outrec->Idx];
+  return outrec;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
+{
+  //get the start and ends of both output polygons ...
+  OutRec *outRec1 = m_PolyOuts[e1->OutIdx];
+  OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
+
+  OutRec *holeStateRec;
+  if (OutRec1RightOfOutRec2(outRec1, outRec2))
+    holeStateRec = outRec2;
+  else if (OutRec1RightOfOutRec2(outRec2, outRec1))
+    holeStateRec = outRec1;
+  else 
+    holeStateRec = GetLowermostRec(outRec1, outRec2);
+
+  //get the start and ends of both output polygons and
+  //join e2 poly onto e1 poly and delete pointers to e2 ...
+
+  OutPt* p1_lft = outRec1->Pts;
+  OutPt* p1_rt = p1_lft->Prev;
+  OutPt* p2_lft = outRec2->Pts;
+  OutPt* p2_rt = p2_lft->Prev;
+
+  //join e2 poly onto e1 poly and delete pointers to e2 ...
+  if(  e1->Side == esLeft )
+  {
+    if(  e2->Side == esLeft )
+    {
+      //z y x a b c
+      ReversePolyPtLinks(p2_lft);
+      p2_lft->Next = p1_lft;
+      p1_lft->Prev = p2_lft;
+      p1_rt->Next = p2_rt;
+      p2_rt->Prev = p1_rt;
+      outRec1->Pts = p2_rt;
+    } else
+    {
+      //x y z a b c
+      p2_rt->Next = p1_lft;
+      p1_lft->Prev = p2_rt;
+      p2_lft->Prev = p1_rt;
+      p1_rt->Next = p2_lft;
+      outRec1->Pts = p2_lft;
+    }
+  } else
+  {
+    if(  e2->Side == esRight )
+    {
+      //a b c z y x
+      ReversePolyPtLinks(p2_lft);
+      p1_rt->Next = p2_rt;
+      p2_rt->Prev = p1_rt;
+      p2_lft->Next = p1_lft;
+      p1_lft->Prev = p2_lft;
+    } else
+    {
+      //a b c x y z
+      p1_rt->Next = p2_lft;
+      p2_lft->Prev = p1_rt;
+      p1_lft->Prev = p2_rt;
+      p2_rt->Next = p1_lft;
+    }
+  }
+
+  outRec1->BottomPt = 0;
+  if (holeStateRec == outRec2)
+  {
+    if (outRec2->FirstLeft != outRec1)
+      outRec1->FirstLeft = outRec2->FirstLeft;
+    outRec1->IsHole = outRec2->IsHole;
+  }
+  outRec2->Pts = 0;
+  outRec2->BottomPt = 0;
+  outRec2->FirstLeft = outRec1;
+
+  int OKIdx = e1->OutIdx;
+  int ObsoleteIdx = e2->OutIdx;
+
+  e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
+  e2->OutIdx = Unassigned;
+
+  TEdge* e = m_ActiveEdges;
+  while( e )
+  {
+    if( e->OutIdx == ObsoleteIdx )
+    {
+      e->OutIdx = OKIdx;
+      e->Side = e1->Side;
+      break;
+    }
+    e = e->NextInAEL;
+  }
+
+  outRec2->Idx = outRec1->Idx;
+}
+//------------------------------------------------------------------------------
+
+OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
+{
+  if(  e->OutIdx < 0 )
+  {
+    OutRec *outRec = CreateOutRec();
+    outRec->IsOpen = (e->WindDelta == 0);
+    OutPt* newOp = new OutPt;
+    outRec->Pts = newOp;
+    newOp->Idx = outRec->Idx;
+    newOp->Pt = pt;
+    newOp->Next = newOp;
+    newOp->Prev = newOp;
+    if (!outRec->IsOpen)
+      SetHoleState(e, outRec);
+    e->OutIdx = outRec->Idx;
+    return newOp;
+  } else
+  {
+    OutRec *outRec = m_PolyOuts[e->OutIdx];
+    //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
+    OutPt* op = outRec->Pts;
+
+	bool ToFront = (e->Side == esLeft);
+	if (ToFront && (pt == op->Pt)) return op;
+    else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev;
+
+    OutPt* newOp = new OutPt;
+    newOp->Idx = outRec->Idx;
+    newOp->Pt = pt;
+    newOp->Next = op;
+    newOp->Prev = op->Prev;
+    newOp->Prev->Next = newOp;
+    op->Prev = newOp;
+    if (ToFront) outRec->Pts = newOp;
+    return newOp;
+  }
+}
+//------------------------------------------------------------------------------
+
+OutPt* Clipper::GetLastOutPt(TEdge *e)
+{
+	OutRec *outRec = m_PolyOuts[e->OutIdx];
+	if (e->Side == esLeft)
+		return outRec->Pts;
+	else
+		return outRec->Pts->Prev;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::ProcessHorizontals()
+{
+  TEdge* horzEdge;
+  while (PopEdgeFromSEL(horzEdge))
+    ProcessHorizontal(horzEdge);
+}
+//------------------------------------------------------------------------------
+
+inline bool IsMinima(TEdge *e)
+{
+  return e  && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e);
+}
+//------------------------------------------------------------------------------
+
+inline bool IsMaxima(TEdge *e, const cInt Y)
+{
+  return e && e->Top.Y == Y && !e->NextInLML;
+}
+//------------------------------------------------------------------------------
+
+inline bool IsIntermediate(TEdge *e, const cInt Y)
+{
+  return e->Top.Y == Y && e->NextInLML;
+}
+//------------------------------------------------------------------------------
+
+TEdge *GetMaximaPair(TEdge *e)
+{
+  if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
+    return e->Next;
+  else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
+    return e->Prev;
+  else return 0;
+}
+//------------------------------------------------------------------------------
+
+TEdge *GetMaximaPairEx(TEdge *e)
+{
+  //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
+  TEdge* result = GetMaximaPair(e);
+  if (result && (result->OutIdx == Skip ||
+    (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2)
+{
+  if(  !( Edge1->NextInSEL ) &&  !( Edge1->PrevInSEL ) ) return;
+  if(  !( Edge2->NextInSEL ) &&  !( Edge2->PrevInSEL ) ) return;
+
+  if(  Edge1->NextInSEL == Edge2 )
+  {
+    TEdge* Next = Edge2->NextInSEL;
+    if( Next ) Next->PrevInSEL = Edge1;
+    TEdge* Prev = Edge1->PrevInSEL;
+    if( Prev ) Prev->NextInSEL = Edge2;
+    Edge2->PrevInSEL = Prev;
+    Edge2->NextInSEL = Edge1;
+    Edge1->PrevInSEL = Edge2;
+    Edge1->NextInSEL = Next;
+  }
+  else if(  Edge2->NextInSEL == Edge1 )
+  {
+    TEdge* Next = Edge1->NextInSEL;
+    if( Next ) Next->PrevInSEL = Edge2;
+    TEdge* Prev = Edge2->PrevInSEL;
+    if( Prev ) Prev->NextInSEL = Edge1;
+    Edge1->PrevInSEL = Prev;
+    Edge1->NextInSEL = Edge2;
+    Edge2->PrevInSEL = Edge1;
+    Edge2->NextInSEL = Next;
+  }
+  else
+  {
+    TEdge* Next = Edge1->NextInSEL;
+    TEdge* Prev = Edge1->PrevInSEL;
+    Edge1->NextInSEL = Edge2->NextInSEL;
+    if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1;
+    Edge1->PrevInSEL = Edge2->PrevInSEL;
+    if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1;
+    Edge2->NextInSEL = Next;
+    if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2;
+    Edge2->PrevInSEL = Prev;
+    if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2;
+  }
+
+  if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1;
+  else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2;
+}
+//------------------------------------------------------------------------------
+
+TEdge* GetNextInAEL(TEdge *e, Direction dir)
+{
+  return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL;
+}
+//------------------------------------------------------------------------------
+
+void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right)
+{
+  if (HorzEdge.Bot.X < HorzEdge.Top.X)
+  {
+    Left = HorzEdge.Bot.X;
+    Right = HorzEdge.Top.X;
+    Dir = dLeftToRight;
+  } else
+  {
+    Left = HorzEdge.Top.X;
+    Right = HorzEdge.Bot.X;
+    Dir = dRightToLeft;
+  }
+}
+//------------------------------------------------------------------------
+
+/*******************************************************************************
+* Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or    *
+* Bottom of a scanbeam) are processed as if layered. The order in which HEs    *
+* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#]    *
+* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs),      *
+* and with other non-horizontal edges [*]. Once these intersections are        *
+* processed, intermediate HEs then 'promote' the Edge above (NextInLML) into   *
+* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs.    *
+*******************************************************************************/
+
+void Clipper::ProcessHorizontal(TEdge *horzEdge)
+{
+  Direction dir;
+  cInt horzLeft, horzRight;
+  bool IsOpen = (horzEdge->WindDelta == 0);
+
+  GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
+
+  TEdge* eLastHorz = horzEdge, *eMaxPair = 0;
+  while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) 
+    eLastHorz = eLastHorz->NextInLML;
+  if (!eLastHorz->NextInLML)
+    eMaxPair = GetMaximaPair(eLastHorz);
+
+  MaximaList::const_iterator maxIt;
+  MaximaList::const_reverse_iterator maxRit;
+  if (m_Maxima.size() > 0)
+  {
+      //get the first maxima in range (X) ...
+      if (dir == dLeftToRight)
+      {
+          maxIt = m_Maxima.begin();
+          while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++;
+          if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X)
+              maxIt = m_Maxima.end();
+      }
+      else
+      {
+          maxRit = m_Maxima.rbegin();
+          while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) maxRit++;
+          if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X)
+              maxRit = m_Maxima.rend();
+      }
+  }
+
+  OutPt* op1 = 0;
+
+  for (;;) //loop through consec. horizontal edges
+  {
+		  
+    bool IsLastHorz = (horzEdge == eLastHorz);
+    TEdge* e = GetNextInAEL(horzEdge, dir);
+    while(e)
+    {
+
+        //this code block inserts extra coords into horizontal edges (in output
+        //polygons) whereever maxima touch these horizontal edges. This helps
+        //'simplifying' polygons (ie if the Simplify property is set).
+        if (m_Maxima.size() > 0)
+        {
+            if (dir == dLeftToRight)
+            {
+                while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X) 
+                {
+                  if (horzEdge->OutIdx >= 0 && !IsOpen)
+                    AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y));
+                  maxIt++;
+                }
+            }
+            else
+            {
+                while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X)
+                {
+                  if (horzEdge->OutIdx >= 0 && !IsOpen)
+                    AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y));
+                  maxRit++;
+                }
+            }
+        };
+
+        if ((dir == dLeftToRight && e->Curr.X > horzRight) ||
+			(dir == dRightToLeft && e->Curr.X < horzLeft)) break;
+
+		//Also break if we've got to the end of an intermediate horizontal edge ...
+		//nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
+		if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && 
+			e->Dx < horzEdge->NextInLML->Dx) break;
+
+    if (horzEdge->OutIdx >= 0 && !IsOpen)  //note: may be done multiple times
+		{
+#ifdef use_xyz
+			if (dir == dLeftToRight) SetZ(e->Curr, *horzEdge, *e);
+			else SetZ(e->Curr, *e, *horzEdge);
+#endif      
+			op1 = AddOutPt(horzEdge, e->Curr);
+			TEdge* eNextHorz = m_SortedEdges;
+			while (eNextHorz)
+			{
+				if (eNextHorz->OutIdx >= 0 &&
+					HorzSegmentsOverlap(horzEdge->Bot.X,
+					horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
+				{
+                    OutPt* op2 = GetLastOutPt(eNextHorz);
+                    AddJoin(op2, op1, eNextHorz->Top);
+				}
+				eNextHorz = eNextHorz->NextInSEL;
+			}
+			AddGhostJoin(op1, horzEdge->Bot);
+		}
+		
+		//OK, so far we're still in range of the horizontal Edge  but make sure
+        //we're at the last of consec. horizontals when matching with eMaxPair
+        if(e == eMaxPair && IsLastHorz)
+        {
+          if (horzEdge->OutIdx >= 0)
+            AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top);
+          DeleteFromAEL(horzEdge);
+          DeleteFromAEL(eMaxPair);
+          return;
+        }
+        
+		if(dir == dLeftToRight)
+        {
+          IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
+          IntersectEdges(horzEdge, e, Pt);
+        }
+        else
+        {
+          IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
+          IntersectEdges( e, horzEdge, Pt);
+        }
+        TEdge* eNext = GetNextInAEL(e, dir);
+        SwapPositionsInAEL( horzEdge, e );
+        e = eNext;
+    } //end while(e)
+
+	//Break out of loop if HorzEdge.NextInLML is not also horizontal ...
+	if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break;
+
+	UpdateEdgeIntoAEL(horzEdge);
+    if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot);
+    GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
+
+  } //end for (;;)
+
+  if (horzEdge->OutIdx >= 0 && !op1)
+  {
+      op1 = GetLastOutPt(horzEdge);
+      TEdge* eNextHorz = m_SortedEdges;
+      while (eNextHorz)
+      {
+          if (eNextHorz->OutIdx >= 0 &&
+              HorzSegmentsOverlap(horzEdge->Bot.X,
+              horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
+          {
+              OutPt* op2 = GetLastOutPt(eNextHorz);
+              AddJoin(op2, op1, eNextHorz->Top);
+          }
+          eNextHorz = eNextHorz->NextInSEL;
+      }
+      AddGhostJoin(op1, horzEdge->Top);
+  }
+
+  if (horzEdge->NextInLML)
+  {
+    if(horzEdge->OutIdx >= 0)
+    {
+      op1 = AddOutPt( horzEdge, horzEdge->Top);
+      UpdateEdgeIntoAEL(horzEdge);
+      if (horzEdge->WindDelta == 0) return;
+      //nb: HorzEdge is no longer horizontal here
+      TEdge* ePrev = horzEdge->PrevInAEL;
+      TEdge* eNext = horzEdge->NextInAEL;
+      if (ePrev && ePrev->Curr.X == horzEdge->Bot.X &&
+        ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 &&
+        (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
+        SlopesEqual(*horzEdge, *ePrev, m_UseFullRange)))
+      {
+        OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot);
+        AddJoin(op1, op2, horzEdge->Top);
+      }
+      else if (eNext && eNext->Curr.X == horzEdge->Bot.X &&
+        eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 &&
+        eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
+        SlopesEqual(*horzEdge, *eNext, m_UseFullRange))
+      {
+        OutPt* op2 = AddOutPt(eNext, horzEdge->Bot);
+        AddJoin(op1, op2, horzEdge->Top);
+      }
+    }
+    else
+      UpdateEdgeIntoAEL(horzEdge); 
+  }
+  else
+  {
+    if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top);
+    DeleteFromAEL(horzEdge);
+  }
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::ProcessIntersections(const cInt topY)
+{
+  if( !m_ActiveEdges ) return true;
+  try {
+    BuildIntersectList(topY);
+    size_t IlSize = m_IntersectList.size();
+    if (IlSize == 0) return true;
+    if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
+    else return false;
+  }
+  catch(...) 
+  {
+    m_SortedEdges = 0;
+    DisposeIntersectNodes();
+    throw clipperException("ProcessIntersections error");
+  }
+  m_SortedEdges = 0;
+  return true;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::DisposeIntersectNodes()
+{
+  for (size_t i = 0; i < m_IntersectList.size(); ++i )
+    delete m_IntersectList[i];
+  m_IntersectList.clear();
+}
+//------------------------------------------------------------------------------
+
+void Clipper::BuildIntersectList(const cInt topY)
+{
+  if ( !m_ActiveEdges ) return;
+
+  //prepare for sorting ...
+  TEdge* e = m_ActiveEdges;
+  m_SortedEdges = e;
+  while( e )
+  {
+    e->PrevInSEL = e->PrevInAEL;
+    e->NextInSEL = e->NextInAEL;
+    e->Curr.X = TopX( *e, topY );
+    e = e->NextInAEL;
+  }
+
+  //bubblesort ...
+  bool isModified;
+  do
+  {
+    isModified = false;
+    e = m_SortedEdges;
+    while( e->NextInSEL )
+    {
+      TEdge *eNext = e->NextInSEL;
+      IntPoint Pt;
+      if(e->Curr.X > eNext->Curr.X)
+      {
+        IntersectPoint(*e, *eNext, Pt);
+        if (Pt.Y < topY) Pt = IntPoint(TopX(*e, topY), topY);
+        IntersectNode * newNode = new IntersectNode;
+        newNode->Edge1 = e;
+        newNode->Edge2 = eNext;
+        newNode->Pt = Pt;
+        m_IntersectList.push_back(newNode);
+
+        SwapPositionsInSEL(e, eNext);
+        isModified = true;
+      }
+      else
+        e = eNext;
+    }
+    if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0;
+    else break;
+  }
+  while ( isModified );
+  m_SortedEdges = 0; //important
+}
+//------------------------------------------------------------------------------
+
+
+void Clipper::ProcessIntersectList()
+{
+  for (size_t i = 0; i < m_IntersectList.size(); ++i)
+  {
+    IntersectNode* iNode = m_IntersectList[i];
+    {
+      IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt);
+      SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 );
+    }
+    delete iNode;
+  }
+  m_IntersectList.clear();
+}
+//------------------------------------------------------------------------------
+
+bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
+{
+  return node2->Pt.Y < node1->Pt.Y;
+}
+//------------------------------------------------------------------------------
+
+inline bool EdgesAdjacent(const IntersectNode &inode)
+{
+  return (inode.Edge1->NextInSEL == inode.Edge2) ||
+    (inode.Edge1->PrevInSEL == inode.Edge2);
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::FixupIntersectionOrder()
+{
+  //pre-condition: intersections are sorted Bottom-most first.
+  //Now it's crucial that intersections are made only between adjacent edges,
+  //so to ensure this the order of intersections may need adjusting ...
+  CopyAELToSEL();
+  std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort);
+  size_t cnt = m_IntersectList.size();
+  for (size_t i = 0; i < cnt; ++i) 
+  {
+    if (!EdgesAdjacent(*m_IntersectList[i]))
+    {
+      size_t j = i + 1;
+      while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++;
+      if (j == cnt)  return false;
+      std::swap(m_IntersectList[i], m_IntersectList[j]);
+    }
+    SwapPositionsInSEL(m_IntersectList[i]->Edge1, m_IntersectList[i]->Edge2);
+  }
+  return true;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::DoMaxima(TEdge *e)
+{
+  TEdge* eMaxPair = GetMaximaPairEx(e);
+  if (!eMaxPair)
+  {
+    if (e->OutIdx >= 0)
+      AddOutPt(e, e->Top);
+    DeleteFromAEL(e);
+    return;
+  }
+
+  TEdge* eNext = e->NextInAEL;
+  while(eNext && eNext != eMaxPair)
+  {
+    IntersectEdges(e, eNext, e->Top);
+    SwapPositionsInAEL(e, eNext);
+    eNext = e->NextInAEL;
+  }
+
+  if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned)
+  {
+    DeleteFromAEL(e);
+    DeleteFromAEL(eMaxPair);
+  }
+  else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 )
+  {
+    if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top);
+    DeleteFromAEL(e);
+    DeleteFromAEL(eMaxPair);
+  }
+#ifdef use_lines
+  else if (e->WindDelta == 0)
+  {
+    if (e->OutIdx >= 0) 
+    {
+      AddOutPt(e, e->Top);
+      e->OutIdx = Unassigned;
+    }
+    DeleteFromAEL(e);
+
+    if (eMaxPair->OutIdx >= 0)
+    {
+      AddOutPt(eMaxPair, e->Top);
+      eMaxPair->OutIdx = Unassigned;
+    }
+    DeleteFromAEL(eMaxPair);
+  } 
+#endif
+  else throw clipperException("DoMaxima error");
+}
+//------------------------------------------------------------------------------
+
+void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
+{
+  TEdge* e = m_ActiveEdges;
+  while( e )
+  {
+    //1. process maxima, treating them as if they're 'bent' horizontal edges,
+    //   but exclude maxima with horizontal edges. nb: e can't be a horizontal.
+    bool IsMaximaEdge = IsMaxima(e, topY);
+
+    if(IsMaximaEdge)
+    {
+      TEdge* eMaxPair = GetMaximaPairEx(e);
+      IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
+    }
+
+    if(IsMaximaEdge)
+    {
+      if (m_StrictSimple) m_Maxima.push_back(e->Top.X);
+      TEdge* ePrev = e->PrevInAEL;
+      DoMaxima(e);
+      if( !ePrev ) e = m_ActiveEdges;
+      else e = ePrev->NextInAEL;
+    }
+    else
+    {
+      //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ...
+      if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML))
+      {
+        UpdateEdgeIntoAEL(e);
+        if (e->OutIdx >= 0)
+          AddOutPt(e, e->Bot);
+        AddEdgeToSEL(e);
+      } 
+      else
+      {
+        e->Curr.X = TopX( *e, topY );
+        e->Curr.Y = topY;
+#ifdef use_xyz
+		e->Curr.Z = topY == e->Top.Y ? e->Top.Z : (topY == e->Bot.Y ? e->Bot.Z : 0);
+#endif
+	  }
+
+      //When StrictlySimple and 'e' is being touched by another edge, then
+      //make sure both edges have a vertex here ...
+      if (m_StrictSimple)
+      {  
+        TEdge* ePrev = e->PrevInAEL;
+        if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
+          (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0))
+        {
+          IntPoint pt = e->Curr;
+#ifdef use_xyz
+          SetZ(pt, *ePrev, *e);
+#endif
+          OutPt* op = AddOutPt(ePrev, pt);
+          OutPt* op2 = AddOutPt(e, pt);
+          AddJoin(op, op2, pt); //StrictlySimple (type-3) join
+        }
+      }
+
+      e = e->NextInAEL;
+    }
+  }
+
+  //3. Process horizontals at the Top of the scanbeam ...
+  m_Maxima.sort();
+  ProcessHorizontals();
+  m_Maxima.clear();
+
+  //4. Promote intermediate vertices ...
+  e = m_ActiveEdges;
+  while(e)
+  {
+    if(IsIntermediate(e, topY))
+    {
+      OutPt* op = 0;
+      if( e->OutIdx >= 0 ) 
+        op = AddOutPt(e, e->Top);
+      UpdateEdgeIntoAEL(e);
+
+      //if output polygons share an edge, they'll need joining later ...
+      TEdge* ePrev = e->PrevInAEL;
+      TEdge* eNext = e->NextInAEL;
+      if (ePrev && ePrev->Curr.X == e->Bot.X &&
+        ePrev->Curr.Y == e->Bot.Y && op &&
+        ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
+        SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) &&
+        (e->WindDelta != 0) && (ePrev->WindDelta != 0))
+      {
+        OutPt* op2 = AddOutPt(ePrev, e->Bot);
+        AddJoin(op, op2, e->Top);
+      }
+      else if (eNext && eNext->Curr.X == e->Bot.X &&
+        eNext->Curr.Y == e->Bot.Y && op &&
+        eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
+        SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) &&
+        (e->WindDelta != 0) && (eNext->WindDelta != 0))
+      {
+        OutPt* op2 = AddOutPt(eNext, e->Bot);
+        AddJoin(op, op2, e->Top);
+      }
+    }
+    e = e->NextInAEL;
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::FixupOutPolyline(OutRec &outrec)
+{
+  OutPt *pp = outrec.Pts;
+  OutPt *lastPP = pp->Prev;
+  while (pp != lastPP)
+  {
+    pp = pp->Next;
+    if (pp->Pt == pp->Prev->Pt)
+    {
+      if (pp == lastPP) lastPP = pp->Prev;
+      OutPt *tmpPP = pp->Prev;
+      tmpPP->Next = pp->Next;
+      pp->Next->Prev = tmpPP;
+      delete pp;
+      pp = tmpPP;
+    }
+  }
+
+  if (pp == pp->Prev)
+  {
+    DisposeOutPts(pp);
+    outrec.Pts = 0;
+    return;
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::FixupOutPolygon(OutRec &outrec)
+{
+    //FixupOutPolygon() - removes duplicate points and simplifies consecutive
+    //parallel edges by removing the middle vertex.
+    OutPt *lastOK = 0;
+    outrec.BottomPt = 0;
+    OutPt *pp = outrec.Pts;
+    bool preserveCol = m_PreserveCollinear || m_StrictSimple;
+
+    for (;;)
+    {
+        if (pp->Prev == pp || pp->Prev == pp->Next)
+        {
+            DisposeOutPts(pp);
+            outrec.Pts = 0;
+            return;
+        }
+
+        //test for duplicate points and collinear edges ...
+        if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) ||
+            (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) &&
+            (!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt))))
+        {
+            lastOK = 0;
+            OutPt *tmp = pp;
+            pp->Prev->Next = pp->Next;
+            pp->Next->Prev = pp->Prev;
+            pp = pp->Prev;
+            delete tmp;
+        }
+        else if (pp == lastOK) break;
+        else
+        {
+            if (!lastOK) lastOK = pp;
+            pp = pp->Next;
+        }
+    }
+    outrec.Pts = pp;
+}
+//------------------------------------------------------------------------------
+
+int PointCount(OutPt *Pts)
+{
+    if (!Pts) return 0;
+    int result = 0;
+    OutPt* p = Pts;
+    do
+    {
+        result++;
+        p = p->Next;
+    }
+    while (p != Pts);
+    return result;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::BuildResult(Paths &polys)
+{
+  polys.reserve(m_PolyOuts.size());
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+  {
+    if (!m_PolyOuts[i]->Pts) continue;
+    Path pg;
+    OutPt* p = m_PolyOuts[i]->Pts->Prev;
+    int cnt = PointCount(p);
+    if (cnt < 2) continue;
+    pg.reserve(cnt);
+    for (int i = 0; i < cnt; ++i)
+    {
+      pg.push_back(p->Pt);
+      p = p->Prev;
+    }
+    polys.push_back(pg);
+  }
+}
+//------------------------------------------------------------------------------
+
+void Clipper::BuildResult2(PolyTree& polytree)
+{
+    polytree.Clear();
+    polytree.AllNodes.reserve(m_PolyOuts.size());
+    //add each output polygon/contour to polytree ...
+    for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++)
+    {
+        OutRec* outRec = m_PolyOuts[i];
+        int cnt = PointCount(outRec->Pts);
+        if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue;
+        FixHoleLinkage(*outRec);
+        PolyNode* pn = new PolyNode();
+        //nb: polytree takes ownership of all the PolyNodes
+        polytree.AllNodes.push_back(pn);
+        outRec->PolyNd = pn;
+        pn->Parent = 0;
+        pn->Index = 0;
+        pn->Contour.reserve(cnt);
+        OutPt *op = outRec->Pts->Prev;
+        for (int j = 0; j < cnt; j++)
+        {
+            pn->Contour.push_back(op->Pt);
+            op = op->Prev;
+        }
+    }
+
+    //fixup PolyNode links etc ...
+    polytree.Childs.reserve(m_PolyOuts.size());
+    for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++)
+    {
+        OutRec* outRec = m_PolyOuts[i];
+        if (!outRec->PolyNd) continue;
+        if (outRec->IsOpen) 
+        {
+          outRec->PolyNd->m_IsOpen = true;
+          polytree.AddChild(*outRec->PolyNd);
+        }
+        else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd) 
+          outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd);
+        else
+          polytree.AddChild(*outRec->PolyNd);
+    }
+}
+//------------------------------------------------------------------------------
+
+void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
+{
+  //just swap the contents (because fIntersectNodes is a single-linked-list)
+  IntersectNode inode = int1; //gets a copy of Int1
+  int1.Edge1 = int2.Edge1;
+  int1.Edge2 = int2.Edge2;
+  int1.Pt = int2.Pt;
+  int2.Edge1 = inode.Edge1;
+  int2.Edge2 = inode.Edge2;
+  int2.Pt = inode.Pt;
+}
+//------------------------------------------------------------------------------
+
+inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
+{
+  if (e2.Curr.X == e1.Curr.X) 
+  {
+    if (e2.Top.Y > e1.Top.Y)
+      return e2.Top.X < TopX(e1, e2.Top.Y); 
+      else return e1.Top.X > TopX(e2, e1.Top.Y);
+  } 
+  else return e2.Curr.X < e1.Curr.X;
+}
+//------------------------------------------------------------------------------
+
+bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, 
+    cInt& Left, cInt& Right)
+{
+  if (a1 < a2)
+  {
+    if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);}
+    else {Left = std::max(a1,b2); Right = std::min(a2,b1);}
+  } 
+  else
+  {
+    if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);}
+    else {Left = std::max(a2,b2); Right = std::min(a1,b1);}
+  }
+  return Left < Right;
+}
+//------------------------------------------------------------------------------
+
+inline void UpdateOutPtIdxs(OutRec& outrec)
+{  
+  OutPt* op = outrec.Pts;
+  do
+  {
+    op->Idx = outrec.Idx;
+    op = op->Prev;
+  }
+  while(op != outrec.Pts);
+}
+//------------------------------------------------------------------------------
+
+void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge)
+{
+  if(!m_ActiveEdges)
+  {
+    edge->PrevInAEL = 0;
+    edge->NextInAEL = 0;
+    m_ActiveEdges = edge;
+  }
+  else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge))
+  {
+      edge->PrevInAEL = 0;
+      edge->NextInAEL = m_ActiveEdges;
+      m_ActiveEdges->PrevInAEL = edge;
+      m_ActiveEdges = edge;
+  } 
+  else
+  {
+    if(!startEdge) startEdge = m_ActiveEdges;
+    while(startEdge->NextInAEL  && 
+      !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge))
+        startEdge = startEdge->NextInAEL;
+    edge->NextInAEL = startEdge->NextInAEL;
+    if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge;
+    edge->PrevInAEL = startEdge;
+    startEdge->NextInAEL = edge;
+  }
+}
+//----------------------------------------------------------------------
+
+OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
+{
+  OutPt* result = new OutPt;
+  result->Pt = outPt->Pt;
+  result->Idx = outPt->Idx;
+  if (InsertAfter)
+  {
+    result->Next = outPt->Next;
+    result->Prev = outPt;
+    outPt->Next->Prev = result;
+    outPt->Next = result;
+  } 
+  else
+  {
+    result->Prev = outPt->Prev;
+    result->Next = outPt;
+    outPt->Prev->Next = result;
+    outPt->Prev = result;
+  }
+  return result;
+}
+//------------------------------------------------------------------------------
+
+bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
+  const IntPoint Pt, bool DiscardLeft)
+{
+  Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
+  Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight);
+  if (Dir1 == Dir2) return false;
+
+  //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we
+  //want Op1b to be on the Right. (And likewise with Op2 and Op2b.)
+  //So, to facilitate this while inserting Op1b and Op2b ...
+  //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b,
+  //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.)
+  if (Dir1 == dLeftToRight) 
+  {
+    while (op1->Next->Pt.X <= Pt.X && 
+      op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)  
+        op1 = op1->Next;
+    if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
+    op1b = DupOutPt(op1, !DiscardLeft);
+    if (op1b->Pt != Pt) 
+    {
+      op1 = op1b;
+      op1->Pt = Pt;
+      op1b = DupOutPt(op1, !DiscardLeft);
+    }
+  } 
+  else
+  {
+    while (op1->Next->Pt.X >= Pt.X && 
+      op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) 
+        op1 = op1->Next;
+    if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
+    op1b = DupOutPt(op1, DiscardLeft);
+    if (op1b->Pt != Pt)
+    {
+      op1 = op1b;
+      op1->Pt = Pt;
+      op1b = DupOutPt(op1, DiscardLeft);
+    }
+  }
+
+  if (Dir2 == dLeftToRight)
+  {
+    while (op2->Next->Pt.X <= Pt.X && 
+      op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
+        op2 = op2->Next;
+    if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
+    op2b = DupOutPt(op2, !DiscardLeft);
+    if (op2b->Pt != Pt)
+    {
+      op2 = op2b;
+      op2->Pt = Pt;
+      op2b = DupOutPt(op2, !DiscardLeft);
+    };
+  } else
+  {
+    while (op2->Next->Pt.X >= Pt.X && 
+      op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) 
+        op2 = op2->Next;
+    if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
+    op2b = DupOutPt(op2, DiscardLeft);
+    if (op2b->Pt != Pt)
+    {
+      op2 = op2b;
+      op2->Pt = Pt;
+      op2b = DupOutPt(op2, DiscardLeft);
+    };
+  };
+
+  if ((Dir1 == dLeftToRight) == DiscardLeft)
+  {
+    op1->Prev = op2;
+    op2->Next = op1;
+    op1b->Next = op2b;
+    op2b->Prev = op1b;
+  }
+  else
+  {
+    op1->Next = op2;
+    op2->Prev = op1;
+    op1b->Prev = op2b;
+    op2b->Next = op1b;
+  }
+  return true;
+}
+//------------------------------------------------------------------------------
+
+bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
+{
+  OutPt *op1 = j->OutPt1, *op1b;
+  OutPt *op2 = j->OutPt2, *op2b;
+
+  //There are 3 kinds of joins for output polygons ...
+  //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere
+  //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
+  //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
+  //location at the Bottom of the overlapping segment (& Join.OffPt is above).
+  //3. StrictSimple joins where edges touch but are not collinear and where
+  //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point.
+  bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y);
+
+  if (isHorizontal  && (j->OffPt == j->OutPt1->Pt) &&
+  (j->OffPt == j->OutPt2->Pt))
+  {
+    //Strictly Simple join ...
+    if (outRec1 != outRec2) return false;
+    op1b = j->OutPt1->Next;
+    while (op1b != op1 && (op1b->Pt == j->OffPt)) 
+      op1b = op1b->Next;
+    bool reverse1 = (op1b->Pt.Y > j->OffPt.Y);
+    op2b = j->OutPt2->Next;
+    while (op2b != op2 && (op2b->Pt == j->OffPt)) 
+      op2b = op2b->Next;
+    bool reverse2 = (op2b->Pt.Y > j->OffPt.Y);
+    if (reverse1 == reverse2) return false;
+    if (reverse1)
+    {
+      op1b = DupOutPt(op1, false);
+      op2b = DupOutPt(op2, true);
+      op1->Prev = op2;
+      op2->Next = op1;
+      op1b->Next = op2b;
+      op2b->Prev = op1b;
+      j->OutPt1 = op1;
+      j->OutPt2 = op1b;
+      return true;
+    } else
+    {
+      op1b = DupOutPt(op1, true);
+      op2b = DupOutPt(op2, false);
+      op1->Next = op2;
+      op2->Prev = op1;
+      op1b->Prev = op2b;
+      op2b->Next = op1b;
+      j->OutPt1 = op1;
+      j->OutPt2 = op1b;
+      return true;
+    }
+  } 
+  else if (isHorizontal)
+  {
+    //treat horizontal joins differently to non-horizontal joins since with
+    //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
+    //may be anywhere along the horizontal edge.
+    op1b = op1;
+    while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2)
+      op1 = op1->Prev;
+    while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2)
+      op1b = op1b->Next;
+    if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon'
+
+    op2b = op2;
+    while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b)
+      op2 = op2->Prev;
+    while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1)
+      op2b = op2b->Next;
+    if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon'
+
+    cInt Left, Right;
+    //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges
+    if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right))
+      return false;
+
+    //DiscardLeftSide: when overlapping edges are joined, a spike will created
+    //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
+    //on the discard Side as either may still be needed for other joins ...
+    IntPoint Pt;
+    bool DiscardLeftSide;
+    if (op1->Pt.X >= Left && op1->Pt.X <= Right) 
+    {
+      Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X);
+    } 
+    else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) 
+    {
+      Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X);
+    } 
+    else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right)
+    {
+      Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X;
+    } 
+    else
+    {
+      Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X);
+    }
+    j->OutPt1 = op1; j->OutPt2 = op2;
+    return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
+  } else
+  {
+    //nb: For non-horizontal joins ...
+    //    1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
+    //    2. Jr.OutPt1.Pt > Jr.OffPt.Y
+
+    //make sure the polygons are correctly oriented ...
+    op1b = op1->Next;
+    while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next;
+    bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) ||
+      !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange));
+    if (Reverse1)
+    {
+      op1b = op1->Prev;
+      while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev;
+      if ((op1b->Pt.Y > op1->Pt.Y) ||
+        !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false;
+    };
+    op2b = op2->Next;
+    while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next;
+    bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) ||
+      !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange));
+    if (Reverse2)
+    {
+      op2b = op2->Prev;
+      while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev;
+      if ((op2b->Pt.Y > op2->Pt.Y) ||
+        !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false;
+    }
+
+    if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
+      ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false;
+
+    if (Reverse1)
+    {
+      op1b = DupOutPt(op1, false);
+      op2b = DupOutPt(op2, true);
+      op1->Prev = op2;
+      op2->Next = op1;
+      op1b->Next = op2b;
+      op2b->Prev = op1b;
+      j->OutPt1 = op1;
+      j->OutPt2 = op1b;
+      return true;
+    } else
+    {
+      op1b = DupOutPt(op1, true);
+      op2b = DupOutPt(op2, false);
+      op1->Next = op2;
+      op2->Prev = op1;
+      op1b->Prev = op2b;
+      op2b->Next = op1b;
+      j->OutPt1 = op1;
+      j->OutPt2 = op1b;
+      return true;
+    }
+  }
+}
+//----------------------------------------------------------------------
+
+static OutRec* ParseFirstLeft(OutRec* FirstLeft)
+{
+  while (FirstLeft && !FirstLeft->Pts)
+    FirstLeft = FirstLeft->FirstLeft;
+  return FirstLeft;
+}
+//------------------------------------------------------------------------------
+
+void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
+{ 
+  //tests if NewOutRec contains the polygon before reassigning FirstLeft
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+  {
+    OutRec* outRec = m_PolyOuts[i];
+    OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+    if (outRec->Pts  && firstLeft == OldOutRec)
+    {
+      if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
+        outRec->FirstLeft = NewOutRec;
+    }
+  }
+}
+//----------------------------------------------------------------------
+
+void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
+{
+  //A polygon has split into two such that one is now the inner of the other.
+  //It's possible that these polygons now wrap around other polygons, so check
+  //every polygon that's also contained by OuterOutRec's FirstLeft container
+  //(including 0) to see if they've become inner to the new inner polygon ...
+  OutRec* orfl = OuterOutRec->FirstLeft;
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+  {
+    OutRec* outRec = m_PolyOuts[i];
+
+    if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec)
+      continue;
+    OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+    if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec)
+      continue;
+    if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts))
+      outRec->FirstLeft = InnerOutRec;
+    else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts))
+      outRec->FirstLeft = OuterOutRec;
+    else if (outRec->FirstLeft == InnerOutRec || outRec->FirstLeft == OuterOutRec)
+      outRec->FirstLeft = orfl;
+  }
+}
+//----------------------------------------------------------------------
+void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec)
+{
+  //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+  {
+    OutRec* outRec = m_PolyOuts[i];
+    OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+    if (outRec->Pts && firstLeft == OldOutRec)
+      outRec->FirstLeft = NewOutRec;
+  }
+}
+//----------------------------------------------------------------------
+
+void Clipper::JoinCommonEdges()
+{
+  for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
+  {
+    Join* join = m_Joins[i];
+
+    OutRec *outRec1 = GetOutRec(join->OutPt1->Idx);
+    OutRec *outRec2 = GetOutRec(join->OutPt2->Idx);
+
+    if (!outRec1->Pts || !outRec2->Pts) continue;
+    if (outRec1->IsOpen || outRec2->IsOpen) continue;
+
+    //get the polygon fragment with the correct hole state (FirstLeft)
+    //before calling JoinPoints() ...
+    OutRec *holeStateRec;
+    if (outRec1 == outRec2) holeStateRec = outRec1;
+    else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
+    else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
+    else holeStateRec = GetLowermostRec(outRec1, outRec2);
+
+    if (!JoinPoints(join, outRec1, outRec2)) continue;
+
+    if (outRec1 == outRec2)
+    {
+      //instead of joining two polygons, we've just created a new one by
+      //splitting one polygon into two.
+      outRec1->Pts = join->OutPt1;
+      outRec1->BottomPt = 0;
+      outRec2 = CreateOutRec();
+      outRec2->Pts = join->OutPt2;
+
+      //update all OutRec2.Pts Idx's ...
+      UpdateOutPtIdxs(*outRec2);
+
+      if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
+      {
+        //outRec1 contains outRec2 ...
+        outRec2->IsHole = !outRec1->IsHole;
+        outRec2->FirstLeft = outRec1;
+
+        if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
+
+        if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
+          ReversePolyPtLinks(outRec2->Pts);
+            
+      } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
+      {
+        //outRec2 contains outRec1 ...
+        outRec2->IsHole = outRec1->IsHole;
+        outRec1->IsHole = !outRec2->IsHole;
+        outRec2->FirstLeft = outRec1->FirstLeft;
+        outRec1->FirstLeft = outRec2;
+
+        if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);
+
+        if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
+          ReversePolyPtLinks(outRec1->Pts);
+      } 
+      else
+      {
+        //the 2 polygons are completely separate ...
+        outRec2->IsHole = outRec1->IsHole;
+        outRec2->FirstLeft = outRec1->FirstLeft;
+
+        //fixup FirstLeft pointers that may need reassigning to OutRec2
+        if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2);
+      }
+     
+    } else
+    {
+      //joined 2 polygons together ...
+
+      outRec2->Pts = 0;
+      outRec2->BottomPt = 0;
+      outRec2->Idx = outRec1->Idx;
+
+      outRec1->IsHole = holeStateRec->IsHole;
+      if (holeStateRec == outRec2) 
+        outRec1->FirstLeft = outRec2->FirstLeft;
+      outRec2->FirstLeft = outRec1;
+
+      if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// ClipperOffset support functions ...
+//------------------------------------------------------------------------------
+
+DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
+{
+  if(pt2.X == pt1.X && pt2.Y == pt1.Y) 
+    return DoublePoint(0, 0);
+
+  double Dx = (double)(pt2.X - pt1.X);
+  double dy = (double)(pt2.Y - pt1.Y);
+  double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy );
+  Dx *= f;
+  dy *= f;
+  return DoublePoint(dy, -Dx);
+}
+
+//------------------------------------------------------------------------------
+// ClipperOffset class
+//------------------------------------------------------------------------------
+
+ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance)
+{
+  this->MiterLimit = miterLimit;
+  this->ArcTolerance = arcTolerance;
+  m_lowest.X = -1;
+}
+//------------------------------------------------------------------------------
+
+ClipperOffset::~ClipperOffset()
+{
+  Clear();
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::Clear()
+{
+  for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
+    delete m_polyNodes.Childs[i];
+  m_polyNodes.Childs.clear();
+  m_lowest.X = -1;
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType)
+{
+  int highI = (int)path.size() - 1;
+  if (highI < 0) return;
+  PolyNode* newNode = new PolyNode();
+  newNode->m_jointype = joinType;
+  newNode->m_endtype = endType;
+
+  //strip duplicate points from path and also get index to the lowest point ...
+  if (endType == etClosedLine || endType == etClosedPolygon)
+    while (highI > 0 && path[0] == path[highI]) highI--;
+  newNode->Contour.reserve(highI + 1);
+  newNode->Contour.push_back(path[0]);
+  int j = 0, k = 0;
+  for (int i = 1; i <= highI; i++)
+    if (newNode->Contour[j] != path[i])
+    {
+      j++;
+      newNode->Contour.push_back(path[i]);
+      if (path[i].Y > newNode->Contour[k].Y ||
+        (path[i].Y == newNode->Contour[k].Y &&
+        path[i].X < newNode->Contour[k].X)) k = j;
+    }
+  if (endType == etClosedPolygon && j < 2)
+  {
+    delete newNode;
+    return;
+  }
+  m_polyNodes.AddChild(*newNode);
+
+  //if this path's lowest pt is lower than all the others then update m_lowest
+  if (endType != etClosedPolygon) return;
+  if (m_lowest.X < 0)
+    m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
+  else
+  {
+    IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y];
+    if (newNode->Contour[k].Y > ip.Y ||
+      (newNode->Contour[k].Y == ip.Y &&
+      newNode->Contour[k].X < ip.X))
+      m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
+  }
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::AddPaths(const Paths& paths, JoinType joinType, EndType endType)
+{
+  for (Paths::size_type i = 0; i < paths.size(); ++i)
+    AddPath(paths[i], joinType, endType);
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::FixOrientations()
+{
+  //fixup orientations of all closed paths if the orientation of the
+  //closed path with the lowermost vertex is wrong ...
+  if (m_lowest.X >= 0 && 
+    !Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour))
+  {
+    for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
+    {
+      PolyNode& node = *m_polyNodes.Childs[i];
+      if (node.m_endtype == etClosedPolygon ||
+        (node.m_endtype == etClosedLine && Orientation(node.Contour)))
+          ReversePath(node.Contour);
+    }
+  } else
+  {
+    for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
+    {
+      PolyNode& node = *m_polyNodes.Childs[i];
+      if (node.m_endtype == etClosedLine && !Orientation(node.Contour))
+        ReversePath(node.Contour);
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::Execute(Paths& solution, double delta)
+{
+  solution.clear();
+  FixOrientations();
+  DoOffset(delta);
+  
+  //now clean up 'corners' ...
+  Clipper clpr;
+  clpr.AddPaths(m_destPolys, ptSubject, true);
+  if (delta > 0)
+  {
+    clpr.Execute(ctUnion, solution, pftPositive, pftPositive);
+  }
+  else
+  {
+    IntRect r = clpr.GetBounds();
+    Path outer(4);
+    outer[0] = IntPoint(r.left - 10, r.bottom + 10);
+    outer[1] = IntPoint(r.right + 10, r.bottom + 10);
+    outer[2] = IntPoint(r.right + 10, r.top - 10);
+    outer[3] = IntPoint(r.left - 10, r.top - 10);
+
+    clpr.AddPath(outer, ptSubject, true);
+    clpr.ReverseSolution(true);
+    clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
+    if (solution.size() > 0) solution.erase(solution.begin());
+  }
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::Execute(PolyTree& solution, double delta)
+{
+  solution.Clear();
+  FixOrientations();
+  DoOffset(delta);
+
+  //now clean up 'corners' ...
+  Clipper clpr;
+  clpr.AddPaths(m_destPolys, ptSubject, true);
+  if (delta > 0)
+  {
+    clpr.Execute(ctUnion, solution, pftPositive, pftPositive);
+  }
+  else
+  {
+    IntRect r = clpr.GetBounds();
+    Path outer(4);
+    outer[0] = IntPoint(r.left - 10, r.bottom + 10);
+    outer[1] = IntPoint(r.right + 10, r.bottom + 10);
+    outer[2] = IntPoint(r.right + 10, r.top - 10);
+    outer[3] = IntPoint(r.left - 10, r.top - 10);
+
+    clpr.AddPath(outer, ptSubject, true);
+    clpr.ReverseSolution(true);
+    clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
+    //remove the outer PolyNode rectangle ...
+    if (solution.ChildCount() == 1 && solution.Childs[0]->ChildCount() > 0)
+    {
+      PolyNode* outerNode = solution.Childs[0];
+      solution.Childs.reserve(outerNode->ChildCount());
+      solution.Childs[0] = outerNode->Childs[0];
+      solution.Childs[0]->Parent = outerNode->Parent;
+      for (int i = 1; i < outerNode->ChildCount(); ++i)
+        solution.AddChild(*outerNode->Childs[i]);
+    }
+    else
+      solution.Clear();
+  }
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::DoOffset(double delta)
+{
+  m_destPolys.clear();
+  m_delta = delta;
+
+  //if Zero offset, just copy any CLOSED polygons to m_p and return ...
+  if (NEAR_ZERO(delta)) 
+  {
+    m_destPolys.reserve(m_polyNodes.ChildCount());
+    for (int i = 0; i < m_polyNodes.ChildCount(); i++)
+    {
+      PolyNode& node = *m_polyNodes.Childs[i];
+      if (node.m_endtype == etClosedPolygon)
+        m_destPolys.push_back(node.Contour);
+    }
+    return;
+  }
+
+  //see offset_triginometry3.svg in the documentation folder ...
+  if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit);
+  else m_miterLim = 0.5;
+
+  double y;
+  if (ArcTolerance <= 0.0) y = def_arc_tolerance;
+  else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) 
+    y = std::fabs(delta) * def_arc_tolerance;
+  else y = ArcTolerance;
+  //see offset_triginometry2.svg in the documentation folder ...
+  double steps = pi / std::acos(1 - y / std::fabs(delta));
+  if (steps > std::fabs(delta) * pi) 
+    steps = std::fabs(delta) * pi;  //ie excessive precision check
+  m_sin = std::sin(two_pi / steps);
+  m_cos = std::cos(two_pi / steps);
+  m_StepsPerRad = steps / two_pi;
+  if (delta < 0.0) m_sin = -m_sin;
+
+  m_destPolys.reserve(m_polyNodes.ChildCount() * 2);
+  for (int i = 0; i < m_polyNodes.ChildCount(); i++)
+  {
+    PolyNode& node = *m_polyNodes.Childs[i];
+    m_srcPoly = node.Contour;
+
+    int len = (int)m_srcPoly.size();
+    if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon)))
+        continue;
+
+    m_destPoly.clear();
+    if (len == 1)
+    {
+      if (node.m_jointype == jtRound)
+      {
+        double X = 1.0, Y = 0.0;
+        for (cInt j = 1; j <= steps; j++)
+        {
+          m_destPoly.push_back(IntPoint(
+            Round(m_srcPoly[0].X + X * delta),
+            Round(m_srcPoly[0].Y + Y * delta)));
+          double X2 = X;
+          X = X * m_cos - m_sin * Y;
+          Y = X2 * m_sin + Y * m_cos;
+        }
+      }
+      else
+      {
+        double X = -1.0, Y = -1.0;
+        for (int j = 0; j < 4; ++j)
+        {
+          m_destPoly.push_back(IntPoint(
+            Round(m_srcPoly[0].X + X * delta),
+            Round(m_srcPoly[0].Y + Y * delta)));
+          if (X < 0) X = 1;
+          else if (Y < 0) Y = 1;
+          else X = -1;
+        }
+      }
+      m_destPolys.push_back(m_destPoly);
+      continue;
+    }
+    //build m_normals ...
+    m_normals.clear();
+    m_normals.reserve(len);
+    for (int j = 0; j < len - 1; ++j)
+      m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1]));
+    if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon)
+      m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0]));
+    else
+      m_normals.push_back(DoublePoint(m_normals[len - 2]));
+
+    if (node.m_endtype == etClosedPolygon)
+    {
+      int k = len - 1;
+      for (int j = 0; j < len; ++j)
+        OffsetPoint(j, k, node.m_jointype);
+      m_destPolys.push_back(m_destPoly);
+    }
+    else if (node.m_endtype == etClosedLine)
+    {
+      int k = len - 1;
+      for (int j = 0; j < len; ++j)
+        OffsetPoint(j, k, node.m_jointype);
+      m_destPolys.push_back(m_destPoly);
+      m_destPoly.clear();
+      //re-build m_normals ...
+      DoublePoint n = m_normals[len -1];
+      for (int j = len - 1; j > 0; j--)
+        m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
+      m_normals[0] = DoublePoint(-n.X, -n.Y);
+      k = 0;
+      for (int j = len - 1; j >= 0; j--)
+        OffsetPoint(j, k, node.m_jointype);
+      m_destPolys.push_back(m_destPoly);
+    }
+    else
+    {
+      int k = 0;
+      for (int j = 1; j < len - 1; ++j)
+        OffsetPoint(j, k, node.m_jointype);
+
+      IntPoint pt1;
+      if (node.m_endtype == etOpenButt)
+      {
+        int j = len - 1;
+        pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X *
+          delta), (cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
+        m_destPoly.push_back(pt1);
+        pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X *
+          delta), (cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
+        m_destPoly.push_back(pt1);
+      }
+      else
+      {
+        int j = len - 1;
+        k = len - 2;
+        m_sinA = 0;
+        m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y);
+        if (node.m_endtype == etOpenSquare)
+          DoSquare(j, k);
+        else
+          DoRound(j, k);
+      }
+
+      //re-build m_normals ...
+      for (int j = len - 1; j > 0; j--)
+        m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
+      m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y);
+
+      k = len - 1;
+      for (int j = k - 1; j > 0; --j) OffsetPoint(j, k, node.m_jointype);
+
+      if (node.m_endtype == etOpenButt)
+      {
+        pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta),
+          (cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
+        m_destPoly.push_back(pt1);
+        pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta),
+          (cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
+        m_destPoly.push_back(pt1);
+      }
+      else
+      {
+        k = 1;
+        m_sinA = 0;
+        if (node.m_endtype == etOpenSquare)
+          DoSquare(0, 1);
+        else
+          DoRound(0, 1);
+      }
+      m_destPolys.push_back(m_destPoly);
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::OffsetPoint(int j, int& k, JoinType jointype)
+{
+  //cross product ...
+  m_sinA = (m_normals[k].X * m_normals[j].Y - m_normals[j].X * m_normals[k].Y);
+  if (std::fabs(m_sinA * m_delta) < 1.0) 
+  {
+    //dot product ...
+    double cosA = (m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y ); 
+    if (cosA > 0) // angle => 0 degrees
+    {
+      m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
+        Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
+      return; 
+    }
+    //else angle => 180 degrees   
+  }
+  else if (m_sinA > 1.0) m_sinA = 1.0;
+  else if (m_sinA < -1.0) m_sinA = -1.0;
+
+  if (m_sinA * m_delta < 0)
+  {
+    m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
+      Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
+    m_destPoly.push_back(m_srcPoly[j]);
+    m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
+      Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
+  }
+  else
+    switch (jointype)
+    {
+      case jtMiter:
+        {
+          double r = 1 + (m_normals[j].X * m_normals[k].X +
+            m_normals[j].Y * m_normals[k].Y);
+          if (r >= m_miterLim) DoMiter(j, k, r); else DoSquare(j, k);
+          break;
+        }
+      case jtSquare: DoSquare(j, k); break;
+      case jtRound: DoRound(j, k); break;
+    }
+  k = j;
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::DoSquare(int j, int k)
+{
+  double dx = std::tan(std::atan2(m_sinA,
+      m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y) / 4);
+  m_destPoly.push_back(IntPoint(
+      Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)),
+      Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx))));
+  m_destPoly.push_back(IntPoint(
+      Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)),
+      Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx))));
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::DoMiter(int j, int k, double r)
+{
+  double q = m_delta / r;
+  m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q),
+      Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q)));
+}
+//------------------------------------------------------------------------------
+
+void ClipperOffset::DoRound(int j, int k)
+{
+  double a = std::atan2(m_sinA,
+  m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y);
+  int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1);
+
+  double X = m_normals[k].X, Y = m_normals[k].Y, X2;
+  for (int i = 0; i < steps; ++i)
+  {
+    m_destPoly.push_back(IntPoint(
+        Round(m_srcPoly[j].X + X * m_delta),
+        Round(m_srcPoly[j].Y + Y * m_delta)));
+    X2 = X;
+    X = X * m_cos - m_sin * Y;
+    Y = X2 * m_sin + Y * m_cos;
+  }
+  m_destPoly.push_back(IntPoint(
+  Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
+  Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
+}
+
+//------------------------------------------------------------------------------
+// Miscellaneous public functions
+//------------------------------------------------------------------------------
+
+void Clipper::DoSimplePolygons()
+{
+  PolyOutList::size_type i = 0;
+  while (i < m_PolyOuts.size()) 
+  {
+    OutRec* outrec = m_PolyOuts[i++];
+    OutPt* op = outrec->Pts;
+    if (!op || outrec->IsOpen) continue;
+    do //for each Pt in Polygon until duplicate found do ...
+    {
+      OutPt* op2 = op->Next;
+      while (op2 != outrec->Pts) 
+      {
+        if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) 
+        {
+          //split the polygon into two ...
+          OutPt* op3 = op->Prev;
+          OutPt* op4 = op2->Prev;
+          op->Prev = op4;
+          op4->Next = op;
+          op2->Prev = op3;
+          op3->Next = op2;
+
+          outrec->Pts = op;
+          OutRec* outrec2 = CreateOutRec();
+          outrec2->Pts = op2;
+          UpdateOutPtIdxs(*outrec2);
+          if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts))
+          {
+            //OutRec2 is contained by OutRec1 ...
+            outrec2->IsHole = !outrec->IsHole;
+            outrec2->FirstLeft = outrec;
+            if (m_UsingPolyTree) FixupFirstLefts2(outrec2, outrec);
+          }
+          else
+            if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts))
+          {
+            //OutRec1 is contained by OutRec2 ...
+            outrec2->IsHole = outrec->IsHole;
+            outrec->IsHole = !outrec2->IsHole;
+            outrec2->FirstLeft = outrec->FirstLeft;
+            outrec->FirstLeft = outrec2;
+            if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2);
+            }
+            else
+          {
+            //the 2 polygons are separate ...
+            outrec2->IsHole = outrec->IsHole;
+            outrec2->FirstLeft = outrec->FirstLeft;
+            if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2);
+            }
+          op2 = op; //ie get ready for the Next iteration
+        }
+        op2 = op2->Next;
+      }
+      op = op->Next;
+    }
+    while (op != outrec->Pts);
+  }
+}
+//------------------------------------------------------------------------------
+
+void ReversePath(Path& p)
+{
+  std::reverse(p.begin(), p.end());
+}
+//------------------------------------------------------------------------------
+
+void ReversePaths(Paths& p)
+{
+  for (Paths::size_type i = 0; i < p.size(); ++i)
+    ReversePath(p[i]);
+}
+//------------------------------------------------------------------------------
+
+void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType)
+{
+  Clipper c;
+  c.StrictlySimple(true);
+  c.AddPath(in_poly, ptSubject, true);
+  c.Execute(ctUnion, out_polys, fillType, fillType);
+}
+//------------------------------------------------------------------------------
+
+void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType)
+{
+  Clipper c;
+  c.StrictlySimple(true);
+  c.AddPaths(in_polys, ptSubject, true);
+  c.Execute(ctUnion, out_polys, fillType, fillType);
+}
+//------------------------------------------------------------------------------
+
+void SimplifyPolygons(Paths &polys, PolyFillType fillType)
+{
+  SimplifyPolygons(polys, polys, fillType);
+}
+//------------------------------------------------------------------------------
+
+inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
+{
+  double Dx = ((double)pt1.X - pt2.X);
+  double dy = ((double)pt1.Y - pt2.Y);
+  return (Dx*Dx + dy*dy);
+}
+//------------------------------------------------------------------------------
+
+double DistanceFromLineSqrd(
+  const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2)
+{
+  //The equation of a line in general form (Ax + By + C = 0)
+  //given 2 points (x�,y�) & (x�,y�) is ...
+  //(y� - y�)x + (x� - x�)y + (y� - y�)x� - (x� - x�)y� = 0
+  //A = (y� - y�); B = (x� - x�); C = (y� - y�)x� - (x� - x�)y�
+  //perpendicular distance of point (x�,y�) = (Ax� + By� + C)/Sqrt(A� + B�)
+  //see http://en.wikipedia.org/wiki/Perpendicular_distance
+  double A = double(ln1.Y - ln2.Y);
+  double B = double(ln2.X - ln1.X);
+  double C = A * ln1.X  + B * ln1.Y;
+  C = A * pt.X + B * pt.Y - C;
+  return (C * C) / (A * A + B * B);
+}
+//---------------------------------------------------------------------------
+
+bool SlopesNearCollinear(const IntPoint& pt1, 
+    const IntPoint& pt2, const IntPoint& pt3, double distSqrd)
+{
+  //this function is more accurate when the point that's geometrically
+  //between the other 2 points is the one that's tested for distance.
+  //ie makes it more likely to pick up 'spikes' ...
+	if (Abs(pt1.X - pt2.X) > Abs(pt1.Y - pt2.Y))
+	{
+    if ((pt1.X > pt2.X) == (pt1.X < pt3.X))
+      return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
+    else if ((pt2.X > pt1.X) == (pt2.X < pt3.X))
+      return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
+		else
+	    return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
+	}
+	else
+	{
+    if ((pt1.Y > pt2.Y) == (pt1.Y < pt3.Y))
+      return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
+    else if ((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y))
+      return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
+		else
+      return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
+	}
+}
+//------------------------------------------------------------------------------
+
+bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
+{
+    double Dx = (double)pt1.X - pt2.X;
+    double dy = (double)pt1.Y - pt2.Y;
+    return ((Dx * Dx) + (dy * dy) <= distSqrd);
+}
+//------------------------------------------------------------------------------
+
+OutPt* ExcludeOp(OutPt* op)
+{
+  OutPt* result = op->Prev;
+  result->Next = op->Next;
+  op->Next->Prev = result;
+  result->Idx = 0;
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
+{
+  //distance = proximity in units/pixels below which vertices
+  //will be stripped. Default ~= sqrt(2).
+  
+  size_t size = in_poly.size();
+  
+  if (size == 0) 
+  {
+    out_poly.clear();
+    return;
+  }
+
+  OutPt* outPts = new OutPt[size];
+  for (size_t i = 0; i < size; ++i)
+  {
+    outPts[i].Pt = in_poly[i];
+    outPts[i].Next = &outPts[(i + 1) % size];
+    outPts[i].Next->Prev = &outPts[i];
+    outPts[i].Idx = 0;
+  }
+
+  double distSqrd = distance * distance;
+  OutPt* op = &outPts[0];
+  while (op->Idx == 0 && op->Next != op->Prev) 
+  {
+    if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd))
+    {
+      op = ExcludeOp(op);
+      size--;
+    } 
+    else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd))
+    {
+      ExcludeOp(op->Next);
+      op = ExcludeOp(op);
+      size -= 2;
+    }
+    else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd))
+    {
+      op = ExcludeOp(op);
+      size--;
+    }
+    else
+    {
+      op->Idx = 1;
+      op = op->Next;
+    }
+  }
+
+  if (size < 3) size = 0;
+  out_poly.resize(size);
+  for (size_t i = 0; i < size; ++i)
+  {
+    out_poly[i] = op->Pt;
+    op = op->Next;
+  }
+  delete [] outPts;
+}
+//------------------------------------------------------------------------------
+
+void CleanPolygon(Path& poly, double distance)
+{
+  CleanPolygon(poly, poly, distance);
+}
+//------------------------------------------------------------------------------
+
+void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance)
+{
+  out_polys.resize(in_polys.size());
+  for (Paths::size_type i = 0; i < in_polys.size(); ++i)
+    CleanPolygon(in_polys[i], out_polys[i], distance);
+}
+//------------------------------------------------------------------------------
+
+void CleanPolygons(Paths& polys, double distance)
+{
+  CleanPolygons(polys, polys, distance);
+}
+//------------------------------------------------------------------------------
+
+void Minkowski(const Path& poly, const Path& path, 
+  Paths& solution, bool isSum, bool isClosed)
+{
+  int delta = (isClosed ? 1 : 0);
+  size_t polyCnt = poly.size();
+  size_t pathCnt = path.size();
+  Paths pp;
+  pp.reserve(pathCnt);
+  if (isSum)
+    for (size_t i = 0; i < pathCnt; ++i)
+    {
+      Path p;
+      p.reserve(polyCnt);
+      for (size_t j = 0; j < poly.size(); ++j)
+        p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y));
+      pp.push_back(p);
+    }
+  else
+    for (size_t i = 0; i < pathCnt; ++i)
+    {
+      Path p;
+      p.reserve(polyCnt);
+      for (size_t j = 0; j < poly.size(); ++j)
+        p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y));
+      pp.push_back(p);
+    }
+
+  solution.clear();
+  solution.reserve((pathCnt + delta) * (polyCnt + 1));
+  for (size_t i = 0; i < pathCnt - 1 + delta; ++i)
+    for (size_t j = 0; j < polyCnt; ++j)
+    {
+      Path quad;
+      quad.reserve(4);
+      quad.push_back(pp[i % pathCnt][j % polyCnt]);
+      quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]);
+      quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]);
+      quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]);
+      if (!Orientation(quad)) ReversePath(quad);
+      solution.push_back(quad);
+    }
+}
+//------------------------------------------------------------------------------
+
+void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed)
+{
+  Minkowski(pattern, path, solution, true, pathIsClosed);
+  Clipper c;
+  c.AddPaths(solution, ptSubject, true);
+  c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
+}
+//------------------------------------------------------------------------------
+
+void TranslatePath(const Path& input, Path& output, const IntPoint delta)
+{
+  //precondition: input != output
+  output.resize(input.size());
+  for (size_t i = 0; i < input.size(); ++i)
+    output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y);
+}
+//------------------------------------------------------------------------------
+
+void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed)
+{
+  Clipper c;
+  for (size_t i = 0; i < paths.size(); ++i)
+  {
+    Paths tmp;
+    Minkowski(pattern, paths[i], tmp, true, pathIsClosed);
+    c.AddPaths(tmp, ptSubject, true);
+    if (pathIsClosed)
+    {
+      Path tmp2;
+      TranslatePath(paths[i], tmp2, pattern[0]);
+      c.AddPath(tmp2, ptClip, true);
+    }
+  }
+    c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
+}
+//------------------------------------------------------------------------------
+
+void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution)
+{
+  Minkowski(poly1, poly2, solution, false, true);
+  Clipper c;
+  c.AddPaths(solution, ptSubject, true);
+  c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
+}
+//------------------------------------------------------------------------------
+
+enum NodeType {ntAny, ntOpen, ntClosed};
+
+void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, Paths& paths)
+{
+  bool match = true;
+  if (nodetype == ntClosed) match = !polynode.IsOpen();
+  else if (nodetype == ntOpen) return;
+
+  if (!polynode.Contour.empty() && match)
+    paths.push_back(polynode.Contour);
+  for (int i = 0; i < polynode.ChildCount(); ++i)
+    AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths);
+}
+//------------------------------------------------------------------------------
+
+void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
+{
+  paths.resize(0); 
+  paths.reserve(polytree.Total());
+  AddPolyNodeToPaths(polytree, ntAny, paths);
+}
+//------------------------------------------------------------------------------
+
+void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
+{
+  paths.resize(0); 
+  paths.reserve(polytree.Total());
+  AddPolyNodeToPaths(polytree, ntClosed, paths);
+}
+//------------------------------------------------------------------------------
+
+void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths)
+{
+  paths.resize(0); 
+  paths.reserve(polytree.Total());
+  //Open paths are top level only, so ...
+  for (int i = 0; i < polytree.ChildCount(); ++i)
+    if (polytree.Childs[i]->IsOpen())
+      paths.push_back(polytree.Childs[i]->Contour);
+}
+//------------------------------------------------------------------------------
+
+std::ostream& operator <<(std::ostream &s, const IntPoint &p)
+{
+  s << "(" << p.X << "," << p.Y << ")";
+  return s;
+}
+//------------------------------------------------------------------------------
+
+std::ostream& operator <<(std::ostream &s, const Path &p)
+{
+  if (p.empty()) return s;
+  Path::size_type last = p.size() -1;
+  for (Path::size_type i = 0; i < last; i++)
+    s << "(" << p[i].X << "," << p[i].Y << "), ";
+  s << "(" << p[last].X << "," << p[last].Y << ")\n";
+  return s;
+}
+//------------------------------------------------------------------------------
+
+std::ostream& operator <<(std::ostream &s, const Paths &p)
+{
+  for (Paths::size_type i = 0; i < p.size(); i++)
+    s << p[i];
+  s << "\n";
+  return s;
+}
+//------------------------------------------------------------------------------
+
+} //ClipperLib namespace
diff --git a/src/clipper/clipper.hpp b/src/clipper/clipper.hpp
new file mode 100755
index 0000000..df1f813
--- /dev/null
+++ b/src/clipper/clipper.hpp
@@ -0,0 +1,406 @@
+/*******************************************************************************
+*                                                                              *
+* Author    :  Angus Johnson                                                   *
+* Version   :  6.4.2                                                           *
+* Date      :  27 February 2017                                                *
+* Website   :  http://www.angusj.com                                           *
+* Copyright :  Angus Johnson 2010-2017                                         *
+*                                                                              *
+* License:                                                                     *
+* Use, modification & distribution is subject to Boost Software License Ver 1. *
+* http://www.boost.org/LICENSE_1_0.txt                                         *
+*                                                                              *
+* Attributions:                                                                *
+* The code in this library is an extension of Bala Vatti's clipping algorithm: *
+* "A generic solution to polygon clipping"                                     *
+* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63.             *
+* http://portal.acm.org/citation.cfm?id=129906                                 *
+*                                                                              *
+* Computer graphics and geometric modeling: implementation and algorithms      *
+* By Max K. Agoston                                                            *
+* Springer; 1 edition (January 4, 2005)                                        *
+* http://books.google.com/books?q=vatti+clipping+agoston                       *
+*                                                                              *
+* See also:                                                                    *
+* "Polygon Offsetting by Computing Winding Numbers"                            *
+* Paper no. DETC2005-85513 pp. 565-575                                         *
+* ASME 2005 International Design Engineering Technical Conferences             *
+* and Computers and Information in Engineering Conference (IDETC/CIE2005)      *
+* September 24-28, 2005 , Long Beach, California, USA                          *
+* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf              *
+*                                                                              *
+*******************************************************************************/
+
+#ifndef clipper_hpp
+#define clipper_hpp
+
+#define CLIPPER_VERSION "6.4.2"
+
+//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
+//improve performance but coordinate values are limited to the range +/- 46340
+//#define use_int32
+
+//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
+//#define use_xyz
+
+//use_lines: Enables line clipping. Adds a very minor cost to performance.
+#define use_lines
+  
+//use_deprecated: Enables temporary support for the obsolete functions
+//#define use_deprecated  
+
+#include <vector>
+#include <list>
+#include <set>
+#include <stdexcept>
+#include <cstring>
+#include <cstdlib>
+#include <ostream>
+#include <functional>
+#include <queue>
+
+namespace ClipperLib {
+
+enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
+enum PolyType { ptSubject, ptClip };
+//By far the most widely used winding rules for polygon filling are
+//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
+//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
+//see http://glprogramming.com/red/chapter11.html
+enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
+
+#ifdef use_int32
+  typedef int cInt;
+  static cInt const loRange = 0x7FFF;
+  static cInt const hiRange = 0x7FFF;
+#else
+  typedef signed long long cInt;
+  static cInt const loRange = 0x3FFFFFFF;
+  static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
+  typedef signed long long long64;     //used by Int128 class
+  typedef unsigned long long ulong64;
+
+#endif
+
+struct IntPoint {
+  cInt X;
+  cInt Y;
+#ifdef use_xyz
+  cInt Z;
+  IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
+#else
+  IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
+#endif
+
+  friend inline bool operator== (const IntPoint& a, const IntPoint& b)
+  {
+    return a.X == b.X && a.Y == b.Y;
+  }
+  friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
+  {
+    return a.X != b.X  || a.Y != b.Y; 
+  }
+};
+//------------------------------------------------------------------------------
+
+typedef std::vector< IntPoint > Path;
+typedef std::vector< Path > Paths;
+
+inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
+inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
+
+std::ostream& operator <<(std::ostream &s, const IntPoint &p);
+std::ostream& operator <<(std::ostream &s, const Path &p);
+std::ostream& operator <<(std::ostream &s, const Paths &p);
+
+struct DoublePoint
+{
+  double X;
+  double Y;
+  DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
+  DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
+};
+//------------------------------------------------------------------------------
+
+#ifdef use_xyz
+typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
+#endif
+
+enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
+enum JoinType {jtSquare, jtRound, jtMiter};
+enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
+
+class PolyNode;
+typedef std::vector< PolyNode* > PolyNodes;
+
+class PolyNode 
+{ 
+public:
+    PolyNode();
+    virtual ~PolyNode(){};
+    Path Contour;
+    PolyNodes Childs;
+    PolyNode* Parent;
+    PolyNode* GetNext() const;
+    bool IsHole() const;
+    bool IsOpen() const;
+    int ChildCount() const;
+private:
+    //PolyNode& operator =(PolyNode& other); 
+    unsigned Index; //node index in Parent.Childs
+    bool m_IsOpen;
+    JoinType m_jointype;
+    EndType m_endtype;
+    PolyNode* GetNextSiblingUp() const;
+    void AddChild(PolyNode& child);
+    friend class Clipper; //to access Index
+    friend class ClipperOffset; 
+};
+
+class PolyTree: public PolyNode
+{ 
+public:
+    ~PolyTree(){ Clear(); };
+    PolyNode* GetFirst() const;
+    void Clear();
+    int Total() const;
+private:
+  //PolyTree& operator =(PolyTree& other);
+  PolyNodes AllNodes;
+    friend class Clipper; //to access AllNodes
+};
+
+bool Orientation(const Path &poly);
+double Area(const Path &poly);
+int PointInPolygon(const IntPoint &pt, const Path &path);
+
+void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
+void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
+void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
+
+void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
+void CleanPolygon(Path& poly, double distance = 1.415);
+void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
+void CleanPolygons(Paths& polys, double distance = 1.415);
+
+void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
+void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
+void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
+
+void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
+void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
+void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
+
+void ReversePath(Path& p);
+void ReversePaths(Paths& p);
+
+struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
+
+//enums that are used internally ...
+enum EdgeSide { esLeft = 1, esRight = 2};
+
+//forward declarations (for stuff used internally) ...
+struct TEdge;
+struct IntersectNode;
+struct LocalMinimum;
+struct OutPt;
+struct OutRec;
+struct Join;
+
+typedef std::vector < OutRec* > PolyOutList;
+typedef std::vector < TEdge* > EdgeList;
+typedef std::vector < Join* > JoinList;
+typedef std::vector < IntersectNode* > IntersectList;
+
+//------------------------------------------------------------------------------
+
+//ClipperBase is the ancestor to the Clipper class. It should not be
+//instantiated directly. This class simply abstracts the conversion of sets of
+//polygon coordinates into edge objects that are stored in a LocalMinima list.
+class ClipperBase
+{
+public:
+  ClipperBase();
+  virtual ~ClipperBase();
+  virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
+  bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
+  virtual void Clear();
+  IntRect GetBounds();
+  bool PreserveCollinear() {return m_PreserveCollinear;};
+  void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
+protected:
+  void DisposeLocalMinimaList();
+  TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
+  virtual void Reset();
+  TEdge* ProcessBound(TEdge* E, bool IsClockwise);
+  void InsertScanbeam(const cInt Y);
+  bool PopScanbeam(cInt &Y);
+  bool LocalMinimaPending();
+  bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
+  OutRec* CreateOutRec();
+  void DisposeAllOutRecs();
+  void DisposeOutRec(PolyOutList::size_type index);
+  void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
+  void DeleteFromAEL(TEdge *e);
+  void UpdateEdgeIntoAEL(TEdge *&e);
+
+  typedef std::vector<LocalMinimum> MinimaList;
+  MinimaList::iterator m_CurrentLM;
+  MinimaList           m_MinimaList;
+
+  bool              m_UseFullRange;
+  EdgeList          m_edges;
+  bool              m_PreserveCollinear;
+  bool              m_HasOpenPaths;
+  PolyOutList       m_PolyOuts;
+  TEdge           *m_ActiveEdges;
+
+  typedef std::priority_queue<cInt> ScanbeamList;
+  ScanbeamList     m_Scanbeam;
+};
+//------------------------------------------------------------------------------
+
+class Clipper : public virtual ClipperBase
+{
+public:
+  Clipper(int initOptions = 0);
+  bool Execute(ClipType clipType,
+      Paths &solution,
+      PolyFillType fillType = pftEvenOdd);
+  bool Execute(ClipType clipType,
+      Paths &solution,
+      PolyFillType subjFillType,
+      PolyFillType clipFillType);
+  bool Execute(ClipType clipType,
+      PolyTree &polytree,
+      PolyFillType fillType = pftEvenOdd);
+  bool Execute(ClipType clipType,
+      PolyTree &polytree,
+      PolyFillType subjFillType,
+      PolyFillType clipFillType);
+  bool ReverseSolution() { return m_ReverseOutput; };
+  void ReverseSolution(bool value) {m_ReverseOutput = value;};
+  bool StrictlySimple() {return m_StrictSimple;};
+  void StrictlySimple(bool value) {m_StrictSimple = value;};
+  //set the callback function for z value filling on intersections (otherwise Z is 0)
+#ifdef use_xyz
+  void ZFillFunction(ZFillCallback zFillFunc);
+#endif
+protected:
+  virtual bool ExecuteInternal();
+private:
+  JoinList         m_Joins;
+  JoinList         m_GhostJoins;
+  IntersectList    m_IntersectList;
+  ClipType         m_ClipType;
+  typedef std::list<cInt> MaximaList;
+  MaximaList       m_Maxima;
+  TEdge           *m_SortedEdges;
+  bool             m_ExecuteLocked;
+  PolyFillType     m_ClipFillType;
+  PolyFillType     m_SubjFillType;
+  bool             m_ReverseOutput;
+  bool             m_UsingPolyTree; 
+  bool             m_StrictSimple;
+#ifdef use_xyz
+  ZFillCallback   m_ZFill; //custom callback 
+#endif
+  void SetWindingCount(TEdge& edge);
+  bool IsEvenOddFillType(const TEdge& edge) const;
+  bool IsEvenOddAltFillType(const TEdge& edge) const;
+  void InsertLocalMinimaIntoAEL(const cInt botY);
+  void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
+  void AddEdgeToSEL(TEdge *edge);
+  bool PopEdgeFromSEL(TEdge *&edge);
+  void CopyAELToSEL();
+  void DeleteFromSEL(TEdge *e);
+  void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
+  bool IsContributing(const TEdge& edge) const;
+  bool IsTopHorz(const cInt XPos);
+  void DoMaxima(TEdge *e);
+  void ProcessHorizontals();
+  void ProcessHorizontal(TEdge *horzEdge);
+  void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
+  OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
+  OutRec* GetOutRec(int idx);
+  void AppendPolygon(TEdge *e1, TEdge *e2);
+  void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
+  OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
+  OutPt* GetLastOutPt(TEdge *e);
+  bool ProcessIntersections(const cInt topY);
+  void BuildIntersectList(const cInt topY);
+  void ProcessIntersectList();
+  void ProcessEdgesAtTopOfScanbeam(const cInt topY);
+  void BuildResult(Paths& polys);
+  void BuildResult2(PolyTree& polytree);
+  void SetHoleState(TEdge *e, OutRec *outrec);
+  void DisposeIntersectNodes();
+  bool FixupIntersectionOrder();
+  void FixupOutPolygon(OutRec &outrec);
+  void FixupOutPolyline(OutRec &outrec);
+  bool IsHole(TEdge *e);
+  bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
+  void FixHoleLinkage(OutRec &outrec);
+  void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
+  void ClearJoins();
+  void ClearGhostJoins();
+  void AddGhostJoin(OutPt *op, const IntPoint offPt);
+  bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
+  void JoinCommonEdges();
+  void DoSimplePolygons();
+  void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
+  void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
+  void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
+#ifdef use_xyz
+  void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
+#endif
+};
+//------------------------------------------------------------------------------
+
+class ClipperOffset 
+{
+public:
+  ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
+  ~ClipperOffset();
+  void AddPath(const Path& path, JoinType joinType, EndType endType);
+  void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
+  void Execute(Paths& solution, double delta);
+  void Execute(PolyTree& solution, double delta);
+  void Clear();
+  double MiterLimit;
+  double ArcTolerance;
+private:
+  Paths m_destPolys;
+  Path m_srcPoly;
+  Path m_destPoly;
+  std::vector<DoublePoint> m_normals;
+  double m_delta, m_sinA, m_sin, m_cos;
+  double m_miterLim, m_StepsPerRad;
+  IntPoint m_lowest;
+  PolyNode m_polyNodes;
+
+  void FixOrientations();
+  void DoOffset(double delta);
+  void OffsetPoint(int j, int& k, JoinType jointype);
+  void DoSquare(int j, int k);
+  void DoMiter(int j, int k, double r);
+  void DoRound(int j, int k);
+};
+//------------------------------------------------------------------------------
+
+class clipperException : public std::exception
+{
+  public:
+    clipperException(const char* description): m_descr(description) {}
+    virtual ~clipperException() throw() {}
+    virtual const char* what() const throw() {return m_descr.c_str();}
+  private:
+    std::string m_descr;
+};
+//------------------------------------------------------------------------------
+
+} //ClipperLib namespace
+
+#endif //clipper_hpp
+
+
diff --git a/src/common/Colour.cc b/src/common/Colour.cc
index aab392f..67f093f 100644
--- a/src/common/Colour.cc
+++ b/src/common/Colour.cc
@@ -65,7 +65,7 @@ Colour::Colour(float red, float green, float blue, float alpha) :
 	rgb_(red, green, blue, alpha), automatic_(false)
 {
 	ostringstream name;
-	name << "RGB(" << red <<  "," << green << "," << blue << "," << alpha << ")" << "\n";
+	name << "rgba(" << int(red*255) <<  "," << int(green*255) << "," << int(blue*255) << "," << alpha << ")" << "\n";
 	name_ = name.str();
 }
 
diff --git a/src/common/ColourTableDefinition.h b/src/common/ColourTableDefinition.h
index 248d64b..6a3e911 100644
--- a/src/common/ColourTableDefinition.h
+++ b/src/common/ColourTableDefinition.h
@@ -37,7 +37,7 @@ class ColourTableDefinition {
 public:
 	ColourTableDefinition() {}
 	virtual ~ColourTableDefinition() {}
-	virtual void set(ColourTable&, int) {};
+	virtual void set(ColourTable&, int=0) {};
 	virtual ColourTableDefinition* clone() const { return new ColourTableDefinition(); }
 	
 	virtual void set(const XmlNode&) { }
diff --git a/src/common/ColourTableDefinitionCompute.cc b/src/common/ColourTableDefinitionCompute.cc
index 901dcad..2f9592b 100644
--- a/src/common/ColourTableDefinitionCompute.cc
+++ b/src/common/ColourTableDefinitionCompute.cc
@@ -39,6 +39,7 @@ ColourTableDefinitionCompute::ColourTableDefinitionCompute(const string& min, co
 {
    methods_["hsl"] = &ColourTableDefinitionCompute::hsl; 
    methods_["linear"] = &ColourTableDefinitionCompute::linear;
+   methods_["rgb"] = &ColourTableDefinitionCompute::linear;
    methods_["hcl"] = &ColourTableDefinitionCompute::hcl;
 }
 
@@ -107,8 +108,7 @@ void ColourTableDefinitionCompute::hsl(ColourTable& table, int nb)
       step_hue =  (hmax.hue_ - hmin.hue_)/(nb-2);
   }
 
-
-/* The handling of Special case for white introduced a regression   : getting rid of it for now ..
+/*
 if ( minColour_.white() ) {
     step_sat = 0;
     step_hue = 0;
@@ -321,8 +321,7 @@ void ColourTableDefinitionCompute::hcl(const Colour& colour, float& h, float& c,
   rgbToXyz(colour.red(), colour.green(), colour.blue(), x, y, z);
   xyzToHcl(x, y, z, h, c, l);
   h *= 360;
-  if ( colour.red() == 1 && colour.green() == 1 && colour.blue() == 1 )
-      h = -1;
+  
 }
 
 Colour ColourTableDefinitionCompute::rgb(float h, float c, float l, float alpha)
diff --git a/src/common/Coordinate.h b/src/common/Coordinate.h
index 5162440..48c99d2 100644
--- a/src/common/Coordinate.h
+++ b/src/common/Coordinate.h
@@ -228,7 +228,7 @@ public:
     double maxpc() { return max_; }
     
     AxisAutomaticSetting automatic() { return automatic_; }
-    virtual void setAutomatic(AxisAutomaticSetting automatic) { automatic_ = automatic; }
+    void setAutomatic(AxisAutomaticSetting automatic) { automatic_ = automatic; }
     virtual void  automatic(bool automatic) { automatic_ = automatic?m_both:m_off; set(); }
 
     void minmax(double min, double max) {
@@ -391,13 +391,19 @@ public:
     double max() { return max_; }
     double minpc() { return (*this)(min_); }
     double maxpc() { return (*this)(max_); }
-    virtual void set(const XmlNode& node) {
+    void set(const XmlNode& node) {
 	    if ( !magCompare(node.name(), "x_logarithmic") ) return; 
 		XmlNode regular = node;
 		regular.name("x_regular");
 		XLogarithmicCoordinateAttributes::set(regular);
         set();
     }
+   
+    void set(const map<string, string>& map) {
+        XLogarithmicCoordinateAttributes::set(map);
+        set();
+        
+    }
     void set() {
     		switch ( automatic_ ) {
     				case m_both:
@@ -496,6 +502,7 @@ public:
 		YLogarithmicCoordinateAttributes::set(regular);
         set();
     }
+    
 	virtual void set(const map<string, string>& map) {
 			YLogarithmicCoordinateAttributes::set(map);
 	        set();
@@ -727,7 +734,7 @@ public:
     bool accept(const string& xml) { return YDateCoordinateAttributes::accept(xml); }
     void set(const XmlNode& node) { YDateCoordinateAttributes::set(node); }
        void set(const map<string, string>& map) { YDateCoordinateAttributes::set(map);  }
-    virtual void setAutomatic(AxisAutomaticSetting automatic) { automatic_ = (automatic); }
+    void setAutomatic(AxisAutomaticSetting automatic) { automatic_ = (automatic); }
     void automatic(bool automatic) { automatic_ = (automatic?m_both:m_off); }
 
     virtual YCoordinate* clone() const {
@@ -827,7 +834,8 @@ public:
      bool accept(const string& xml) { return YHyperCoordinateAttributes::accept(xml); }
     void set(const XmlNode& node) { YHyperCoordinateAttributes::set(node); }
     void set(const map<string, string>& map) { YHyperCoordinateAttributes::set(map); }
-    virtual void setAutomatic(bool automatic) {automatic_ = automatic?m_both:m_off; }
+    void setAutomatic(AxisAutomaticSetting automatic) { YCoordinate::setAutomatic(automatic); }
+    void setAutomatic(bool automatic) {automatic_ = automatic?m_both:m_off; }
     void automatic(bool automatic) { automatic_ = automatic?m_both:m_off; }
     
     virtual YCoordinate* clone() const {
@@ -929,7 +937,8 @@ public:
      bool accept(const string& xml) { return XHyperCoordinateAttributes::accept(xml); }
     void set(const XmlNode& node) { XHyperCoordinateAttributes::set(node); }
     void set(const map<string, string>& map) { XHyperCoordinateAttributes::set(map); }
-    virtual void setAutomatic(bool automatic) { automatic_ = (automatic?m_both:m_off); }
+    void setAutomatic(AxisAutomaticSetting automatic) { XCoordinate::setAutomatic(automatic); }
+    void setAutomatic(bool automatic) { automatic_ = (automatic?m_both:m_off); }
     void automatic(bool automatic) {  automatic_ = automatic?m_both:m_off; }
     vector<double> mins() { vector<double> mins; mins.push_back(min_lon_); mins.push_back(min_lat_);  return mins; }
     vector<double> maxs() {  vector<double> maxs; maxs.push_back(max_lon_); maxs.push_back(max_lat_);  return maxs; }
diff --git a/src/common/Data.h b/src/common/Data.h
index 0d665dc..1193ba3 100644
--- a/src/common/Data.h
+++ b/src/common/Data.h
@@ -64,7 +64,7 @@ public:
 class Data: public MetviewIcon{
 
 public:
-	Data(): name_("no_name"), dimension_(1), valid_(true), binning_(0),   thinningFactor_(1) {}
+	Data():  dimension_(1), valid_(true), thinningFactor_(1), name_("no_name"), binning_(0)    {}
 	virtual ~Data() { if ( binning_ ) delete binning_; }
     //! Method to access the data as a matrix Used by pcont action routine
     virtual MatrixHandler& matrix() { throw MethodNotYetImplemented("Data::matrix"); }
diff --git a/src/common/GeoRectangularProjection.cc b/src/common/GeoRectangularProjection.cc
index 26e80ed..d5c7d92 100644
--- a/src/common/GeoRectangularProjection.cc
+++ b/src/common/GeoRectangularProjection.cc
@@ -589,13 +589,14 @@ void GeoRectangularProjection::populate(double lon, double lat, double value, ve
 	 		return;
 
 	 out.push_back(UserPoint(lon, lat, value));
-
+	double normlon = lon;
 	lon += 360.;
 	 while ( lon >  min_longitude_ && lon < max_longitude_) {
 		 out.push_back(UserPoint(lon, lat, value));
 	     lon += 360;
 	 }
 	 // To the West
+	 lon = normlon;
 	 lon -=  360.;
 	 while (lon >  min_longitude_ && lon < max_longitude_) {
 	 	out.push_back(UserPoint(lon, lat, value));
diff --git a/src/common/Layout.cc b/src/common/Layout.cc
index b86c314..4862aff 100644
--- a/src/common/Layout.cc
+++ b/src/common/Layout.cc
@@ -94,14 +94,14 @@ void Layout::print(ostream& out)  const
 }
 
 
-void Layout::absoluteWidth(double width) 
+double Layout::absoluteWidth(double width)
 {
-	width_ = 100*width / absoluteWidth();
+	return width_ = 100*width / absoluteWidth();
 }
 
-void Layout::absoluteHeight(double height) 
+double Layout::absoluteHeight(double height)
 {
-	height_ = 100*height / absoluteHeight();
+	return height_ = 100*height / absoluteHeight();
 }
 
 RootLayout::RootLayout(double width, double height) :
diff --git a/src/common/Layout.h b/src/common/Layout.h
index 872c07e..d68b346 100644
--- a/src/common/Layout.h
+++ b/src/common/Layout.h
@@ -122,8 +122,12 @@ public:
 	
 	void x(double x ) { x_ = x; }
 	void y(double y ) { y_ = y; }
-	void absoluteWidth(double);
-	void absoluteHeight(double);
+	
+    double absoluteWidth(double);
+	double absoluteHeight(double);
+   
+    
+    
 	void width(double width ) { width_ = width; }
 	void height(double height ) { height_ = height; }
 	
@@ -156,7 +160,12 @@ public:
 	void setCoordinates(double xmin, double xmax, double ymin, double ymax) {
 		xmin_ = xmin; xmax_ = xmax; ymin_ = ymin; ymax_ = ymax; 
 	}
-	
+
+	static void reset()
+	{
+		driverInfos_.clear();
+	}
+
 	void pushDriverInfo(double x, double y, double width, double height) const 
 	{
 		driverInfos_.push_back(DriverInfo(x, y, width, height));
@@ -328,7 +337,7 @@ public:
 	virtual ~RootLayout();
 	double absoluteWidth() const { return absoluteWidth_; }
 	double absoluteHeight() const { return absoluteHeight_; }
-	virtual bool childOfRoot() { return false; }
+	bool childOfRoot() const { return false; }
 	void redisplay(const BaseDriver& driver) const;
 
 	 virtual void resize(double width, double height) { absoluteWidth_ = width; absoluteHeight_ = height; }
diff --git a/src/common/MagicsCalls.cc b/src/common/MagicsCalls.cc
index e818d2a..baa6416 100644
--- a/src/common/MagicsCalls.cc
+++ b/src/common/MagicsCalls.cc
@@ -907,6 +907,7 @@ extern "C" {
 
 void popen_()
 {
+	
 	if (magics_ == 0) 
 		magics_ = new FortranMagics();
 	magics_->popen();
@@ -1022,12 +1023,13 @@ void psymb_()
 	magics_->psymb();
 }
 
-void pclose_()
+int  pclose_()
 {
-	magics_->pclose();
+	int code = magics_->pclose();
 
 	delete magics_;
 	magics_ = 0;
+	return code;
 }
 
 void pact_(const char*, const char*, const char*, int, int, int)
@@ -1070,20 +1072,44 @@ void pseti_(const char* name, const int* value, int namel)
 	}
 	catch (MagicsException& e)
 	{
-		MagLog::error() << e << "\n";
+		double fvalue = *value;
+		mag_setr(name, fvalue);
 	}
 }
 
 void pset1i_(const char* name, const int* data, const int* dim, int length)
 {
 	std::string n(name, length);
-	mag_set1i(n.c_str(), data, *dim);
+	try {	
+		mag_set1i(n.c_str(), data, *dim);
+	}
+	catch (MagicsException& e)
+	{
+		int s = *dim;
+		double fvalue[s];
+		for (int i =0; i < s; i++)
+			fvalue[i] = data[i];
+		mag_set1r(name, fvalue, *dim);
+	}
+	
 }
 
-void pset2i_(const char* name, const int* data, const int* dim, const int* dim2, int length)
+void pset2i_(const char* name, const int* data, const int* dim1, const int* dim2, int length)
 {
 	std::string n(name, length);
-	mag_set2i(n.c_str(), data, *dim, *dim2);	    
+	try {	
+		mag_set2i(n.c_str(), data, *dim1, *dim2);	
+	}
+	
+	catch (MagicsException& e)
+	{
+		int dim = *dim1 * *dim2;
+		double fvalue[dim];
+		for (int i =0; i < dim; i++)
+			fvalue[i] = data[i];
+		mag_set2r(name, fvalue, *dim1, *dim2);
+	}
+	
 }
 
 void pset3i_(const char* name, const int* data, const int* dim, const int* dim2, const int* dim3, int length)
@@ -1256,7 +1282,7 @@ void pinfo_(){mag_info();}
 
 ****************************************************************************/
 void mag_open()  {popen_();}
-void mag_close() {pclose_();}
+int mag_close() { return pclose_();}
 void mag_coast() {pcoast_();}
 void mag_grib()  {pgrib_();}
 void mag_mapgen()  {pmapgen_();}
@@ -1317,6 +1343,7 @@ void mag_setc(const char* name, const char* value)
 	string n(name);
 	string v(value);
 	psetc_(n.c_str(), value, n.size(), v.size());
+	//cout << "setc("<<name<<","<<value<<")"<<endl;
 }
 
 void mag_setr(const char* name, const double value)
@@ -1331,18 +1358,20 @@ void mag_setr(const char* name, const double value)
 	{
 		MagLog::error() << e << "\n";
 	}
+	//cout << "setr("<<name<<","<<value<<")"<<endl;
 }
 
 void mag_seti(const char* name, const int value)
 {
 	string n(name);
 	pseti_(name, &value, n.size());
+	//cout << "seti("<<name<<","<<value<<")"<<endl;
 }
 
 void mag_setp(const char* name, void* value)
 {
-	string n(name);
 #ifdef HAVE_CAIRO
+    string n(name);
     if ( magCompare(n, "output_cairo_drawing_context") ) {
        ParameterManager::set("output_cairo_drawing_context", (CairoPtr)value); 
     }
@@ -1465,6 +1494,7 @@ void mag_set1c(const char* name, const char** data, const int dim)
 	{
 		MagLog::error() << e << "\n";
 	}
+	//cout << "set1c("<<name<<","<<data[0]<<","<<dim<<")"<<endl;
 }
 
 void mag_enqr(const char* fname, double *value)
diff --git a/src/common/MagicsFormat.cc b/src/common/MagicsFormat.cc
index f25a1a5..c06e43b 100644
--- a/src/common/MagicsFormat.cc
+++ b/src/common/MagicsFormat.cc
@@ -62,6 +62,37 @@ bool MagicsFormat::valid(ostream& out) const
         return true;
     }
     
+	if ( format_.length() >=4 && format_[0] == '#' && format_[2] == ':' ) {
+		// Extension MF: Si debut type "#_:"
+		char type = format_[1];
+		string fmt(format_,3);
+		char bufr[256];
+		if ( type == 'C' ) {
+			// => Formatage C type printf
+			// Attention: aucun garde-fou si format erroné.
+			// Il doit etre défini pour recevoir un unique paramètre de type double.
+			sprintf(bufr, fmt.c_str(), value_);
+			out << bufr;
+			return true;
+		}
+		else if ( type == 'S' ) {
+			// => Formatage special prédefini
+			if ( magCompare(fmt, "WINTEM") ) {
+				// Format spécifique WINTEM AERO
+				// Arrondi entier, '+' si positif et pas de '-' si négatif.
+				if ( value_ > 0 ) {
+					sprintf(bufr, "+%.0f", value_);
+				}
+				else {
+					sprintf(bufr, "%.0f", -value_);
+				}
+				out << bufr;
+				return true;
+			}
+		}
+		return false;
+	}
+
 	string print =  "%g";
 	string flags;
 	string width;
diff --git a/src/common/Matrix.cc b/src/common/Matrix.cc
index d0bb1be..e089bb3 100644
--- a/src/common/Matrix.cc
+++ b/src/common/Matrix.cc
@@ -38,8 +38,10 @@ void Matrix::multiply(double factor)
     
 void Matrix::plus(double offset) 
 {
+	
     if (offset == 0 ) return;
     std::transform(begin(), end(), begin(), Plus(offset, missing_));
+    
 }
 
 pair<int, bool> InfoIndex::index(double pos) const
@@ -318,12 +320,9 @@ int Matrix::nearest_index(double row, double column,double &rowOut, double &colO
 	colOut = missing();
 
 	if ( col < left() || col > right() ) {
-
-		
 		return -1;
 	} 
 	if ( row < bottom() || row > top() ) {
-		
 		return -1;
 	} 
 	map<double, int >::const_iterator  row_index;
@@ -469,20 +468,23 @@ double Matrix::operator()(int row, int column) const
 GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Transformation& transformation):
 	  TransformMatrixHandler(matrix), transformation_(transformation), original_(0)
 {
-
 	map<double, int> lats;
 	map<double, int> lons;
 	
 	double lon, lat;
 	double minlon, minlat, maxlon, maxlat;
 	
-
 	transformation.boundingBox(minlon, minlat, maxlon, maxlat);
 
+	
+
 	int rows = matrix_.rows();
 	int columns = matrix_.columns();
 	double step = matrix_.XResolution();
+
 	bool global =  ( matrix_.regular_column(columns-1) - matrix_.regular_column(0) ) > ( 360. - 2 *matrix_.XResolution() );
+	global = true;
+
 	if (!global) {
 
 		lon = matrix_.column(0, 0) - step;
@@ -504,8 +506,6 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
 		while (  ml >= minlon && ml <= maxlon ) {  lons[ml] = -1; ml += 360; }
 	}
 
-
-
 	for (int i = 0; i < columns; i++)
 	{
 		lon = matrix_.regular_column(i);
@@ -514,7 +514,9 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
 
 		double ml = lon - 360;
 		while ( ml >= minlon && ml <= maxlon ) {  lons[ml] = i; ml -= 360; }
+		
 		ml = lon + 360;
+
 		while (  ml >= minlon && ml <= maxlon ) {  lons[ml] = i; ml += 360; }
 	}
 
@@ -522,6 +524,7 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
 	int i = 0;
 	for (map<double, int>::const_iterator entry = lons.begin(); entry != lons.end(); ++entry)
 	{
+		
 		columns_[i] = entry->second;
 		regular_longitudes_.push_back(entry->first);
 		columnsMap_[entry->first] = i;
@@ -532,13 +535,20 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
 
 
 	for (int i = 0; i < rows; i++) {
-
 		lat = matrix_.regular_row(i);
-		if ( minlat <= lat && lat <= maxlat) 
+		if ( minlat < lat && lat < maxlat) {
 			lats[lat] = i;
-		
+			//cout << "add lat -> " << lat << endl;
+		}
+		if ( same(minlat, lat) || same(lat,maxlat) ) { 
+			lats[lat] = i;
+			//cout << "PASS nEW TEST " << lat << " - " <<  minlat << " - " << maxlat << endl;
+			//cout << "add lat -> " << lat << endl;
+		}
+
 
 	}
+
 	i = 0;
 	for (map<double, int>::const_iterator entry = lats.begin(); entry != lats.end(); ++entry) {
 		rows_[i] = entry->second;
@@ -581,6 +591,7 @@ RotatedMatrixHandler::RotatedMatrixHandler(const AbstractMatrix& matrix,  double
 }
 
 
+
        
 double Proj4MatrixHandler::interpolate(double  row, double  column) const 
 {
diff --git a/src/common/Matrix.h b/src/common/Matrix.h
index 0526070..bf69fbc 100644
--- a/src/common/Matrix.h
+++ b/src/common/Matrix.h
@@ -493,7 +493,9 @@ public:
 		ProjectedMatrix(int rows, int columns);
 	
 		
-		void getReady(); // Prepare the matrix ... 
+        MatrixHandler* getReady(const Transformation& transformation) const
+            { return Matrix::getReady(transformation); }
+		void getReady(); // Prepare the matrix ...
 		  
 		vector<double>&  values() const { return values_; }
 		vector<double>&  rowsArray() const { return rowsArray_; }
diff --git a/src/common/MatrixHandler.h b/src/common/MatrixHandler.h
index 80c588b..61e8438 100644
--- a/src/common/MatrixHandler.h
+++ b/src/common/MatrixHandler.h
@@ -60,10 +60,10 @@ public :
     	double& column1, int& index1, double& column2, int& index2) const 
     		{ return matrix_.boundColumn(r, column1, index1, column2, index2); }		
     
-    double  left() const { return matrix_.left(); }
-         double bottom() const { return matrix_.bottom(); } 
-         double  right() const { return matrix_.right(); }
-         double  top() const { return matrix_.top(); }
+    virtual double  left() const { return matrix_.left(); }
+    virtual double bottom() const { return matrix_.bottom(); } 
+    virtual double  right() const { return matrix_.right(); }
+    virtual double  top() const { return matrix_.top(); }
          
          double x(double x, double y) const  { return matrix_.x(x, y); }
          double y(double x, double y) const { return matrix_.y(x, y); }
@@ -100,13 +100,17 @@ public :
                 vector< std::pair< std::pair<double, double>,  pair<int, int> > > coordinates;
                 if (ri != -1 ) {
                 	boundColumn(column, x1, c1, x2, c2);
-                	coordinates.push_back(make_pair(make_pair(row, x1), std::make_pair(ri, c1)));
-                	coordinates.push_back(make_pair(make_pair(row, x2), std::make_pair(ri, c2)));
+                	if (x1 != -1)
+                		coordinates.push_back(make_pair(make_pair(row, x1), std::make_pair(ri, c1)));
+                	if (x2 != -1)
+                		coordinates.push_back(make_pair(make_pair(row, x2), std::make_pair(ri, c2)));
                 }
                 else if (ci != -1 ) {
                 	boundRow(row, y1, r1, y2, r2);
-                	coordinates.push_back(make_pair(make_pair(y1, column), std::make_pair(r1, ci)));
-                	coordinates.push_back(make_pair(make_pair(y2, column), std::make_pair(r2, ci)));
+                	if (y1 != -1)
+                		coordinates.push_back(make_pair(make_pair(y1, column), std::make_pair(r1, ci)));
+                	if (y2 != -1)
+                		coordinates.push_back(make_pair(make_pair(y2, column), std::make_pair(r2, ci)));
 
                 }
                 else {
@@ -116,10 +120,18 @@ public :
                 // 4 points ...
                 // x1, y1 - x2, y1 -  x1, y2 - x2, y2
                 // find the nearest...
-                	coordinates.push_back(make_pair(make_pair(y1, x1), std::make_pair(r1, c1)));
-                	coordinates.push_back(make_pair(make_pair(y1, x2), std::make_pair(r1, c2)));
-                	coordinates.push_back(make_pair(make_pair(y2, x1), std::make_pair(r2, c1)));
-                	coordinates.push_back(make_pair(make_pair(y2, x2), std::make_pair(r2, c2)));
+                	if (y1 != -1) {
+                		if (x1 != -1)
+                			coordinates.push_back(make_pair(make_pair(y1, x1), std::make_pair(r1, c1)));
+                		if (x2 != -1)
+                			coordinates.push_back(make_pair(make_pair(y1, x2), std::make_pair(r1, c2)));
+                	}
+                	if (y2 != -1) {
+                		if (x1 != -1)
+                			coordinates.push_back(make_pair(make_pair(y2, x1), std::make_pair(r2, c1)));
+                		if (x2 != -1)
+                			coordinates.push_back(make_pair(make_pair(y2, x2), std::make_pair(r2, c2)));
+                	}
                 }
 
                 for (vector< pair< std::pair<double, double>, pair<int, int> > >::iterator coord = coordinates.begin(); coord != coordinates.end(); ++coord) {
@@ -149,14 +161,26 @@ public :
     	if ( columns() == 0  || rows() == 0)
     		return matrix_.missing();
 
-		if ( j < left() && !same(j, left()) )
-            return matrix_.missing();
-        if ( j > right() && !same(j, right()) )
-            return matrix_.missing();
-        if ( i < bottom() && !same(i, bottom()) )
-            return matrix_.missing();
-        if ( i > top() && !same(i, top()) )
-            return matrix_.missing();
+    	if (j < left()) {
+    		if (!same(j, left()))
+    			return matrix_.missing();
+    		j = left(); //not really necessary but now there will be no more obscur rounding problems!
+    	}
+    	if (j > right()) {
+    		if (!same(j, right()))
+    			return matrix_.missing();
+    		j = right(); //id left
+    	}
+    	if (i < bottom()) {
+    		if (!same(i, bottom()))
+    			return matrix_.missing();
+    		i = bottom(); //id left
+    	}
+    	if (i > top()) {
+    		if (!same(i, top()))
+    			return matrix_.missing();
+    		i = top(); //id left
+    	}
 
 
     	
@@ -167,12 +191,18 @@ public :
     		int i1, i2;
     		boundRow(i, v1, i1, v2, i2);
     		
-    		if (i1 == -1) return missing(); 
+    		if (i1 == -1 || i2 == -1) return missing();
     		internal_ = true;
     	    double a = (*this).interpolate(v1, j);
+            internal_ = false;
+
+            if (same(a, missing())) return missing();
+            if (i1 == i2 || v1 == v2) return a;     // already seen with Akima760 (da,db ---> zero divide !)
+
+            internal_ = true;
             double b = (*this).interpolate(v2, j);
             internal_ = false;
-            if ( same(a, missing()) || same(b, missing()) ) return missing();
+            if (same(b, missing())) return missing();
             
             double da = (v2-i)/(v2-v1);
             double db = (i-v1)/(v2-v1);
@@ -184,13 +214,17 @@ public :
         	double v1, v2;
     		int i1, i2;
     		boundColumn(j, v1, i1, v2, i2);
-    		if (i1 == -1) return missing(); 
+    		if (i1 == -1 || i2 == -1) return missing();
     		
         	
     		double a = (*this)(ii, i1);
+    		if (same(a, missing())) return missing();
+
+    		if (i1 == i2 || v1 == v2) return a; // Id rows
+
             double b = (*this)(ii, i2);
             
-            if ( same(a, missing()) || same(b, missing()) ) return missing();
+    		if (same(b, missing())) return missing();
             
             double da = (v2-j)/(v2-v1);
             double db = (j-v1)/(v2-v1);
@@ -495,11 +529,15 @@ public :
 
     
     
-    double interpolate(double  row, double  column) const { matrix_.interpolate(row, column); }
-    double nearest(double  row, double  column) const { matrix_.nearest(row, column); }
+    double interpolate(double  row, double  column) const { return matrix_.interpolate(row, column); }
+    double nearest(double  row, double  column) const { return matrix_.nearest(row, column); }
 
-    double column(int i, int j) const { matrix_.column(i, j); }
-    double row(int i, int j) const { matrix_.row(i, j); }
+    double column(int i, int j) { return matrix_.column(i, j); }
+    double row(int i, int j) { return matrix_.row(i, j); }
+    double  left() const { return matrix_.left(); }
+    double bottom() const { return matrix_.bottom(); } 
+    double  right() const { return matrix_.right(); }
+    double  top() const { return matrix_.top(); }
 
 protected :
 
@@ -658,6 +696,12 @@ public:
                 if ( same(i->first, r) )
                     return i->second;
             }
+         	else
+         	{ // Utilité ? A confirmer
+         		map<double, int>::const_reverse_iterator i = rowsMap_.rbegin();
+         		if ( same(i->first, r) )
+         			return i->second;
+         	}
          	return -1;
          }
 
@@ -668,6 +712,12 @@ public:
                 if ( same(i->first, c) )
                     return i->second;
             }
+         	else
+         	{ // Utilité ? A confirmer
+         		map<double, int>::const_reverse_iterator i = columnsMap_.rbegin();
+         		if ( same(i->first, c) )
+         			return i->second;
+         	}
          	return -1;
          }
     
@@ -711,6 +761,12 @@ public:
             if ( same(i->first, r) )
                 return i->second;
         }
+    	else
+    	{ // Utilité ? A confirmer
+    		map<double, int>::const_reverse_iterator i = rowsMap_.rbegin();
+    		if ( same(i->first, r) )
+    			return i->second;
+    	}
     	return -1;
     }
     
@@ -721,6 +777,12 @@ public:
             if ( same(i->first, c) )
                 return i->second;
         }
+    	else
+    	{ // Utilité ? A confirmer
+    		map<double, int>::const_reverse_iterator i = columnsMap_.rbegin();
+    		if ( same(i->first, c) )
+    			return i->second;
+    	}
         return -1;
     }
 
@@ -792,7 +854,17 @@ public:
 	virtual void boundRow(double r, double& row1, int& index1, double& row2, int& index2) const
 	{
 		index1 = lowerRow(r);
+		if (index1 < 0) {
+			index2 = -1;
+			return;
+		}
+
 		row1 = regular_latitudes_[index1];
+		if (index1 >= regular_latitudes_.size() - 1) {
+			index2 = -1;
+			return;
+		}
+
 		index2 = index1+1;
 		row2 = regular_latitudes_[index2];
 	} 
@@ -800,7 +872,17 @@ public:
 	virtual void boundColumn(double r, double& column1, int& index1, double& column2, int& index2) const
 	{
 		index1 = lowerColumn(r);
+		if (index1 < 0) {
+			index2 = -1;
+			return;
+		}
+
 		column1 = regular_longitudes_[index1];
+		if (index1 >= regular_longitudes_.size() - 1) {
+			index2 = -1;
+			return;
+		}
+
 		index2 = index1+1;
 		column2 = regular_longitudes_[index2];
 	} 
diff --git a/src/common/ParameterManager.h b/src/common/ParameterManager.h
index 6132795..a05fa9b 100644
--- a/src/common/ParameterManager.h
+++ b/src/common/ParameterManager.h
@@ -56,13 +56,9 @@ public:
 		BaseParameter* param = (*table_).parameter(name);
 		if (param)
 		{
-			try {
-			    param->set(value);
-			}
-			catch (MagicsException& e)
-			{
-			    MagLog::warning() << "MagException > " << e << "\n";
-			}
+			
+			 param->set(value);
+			
 		}
 		else
 			MagLog::warning() << "The parameter " << name << " was not found.\n";
diff --git a/src/common/PointsHandler.cc b/src/common/PointsHandler.cc
index db4b4f5..76428bb 100644
--- a/src/common/PointsHandler.cc
+++ b/src/common/PointsHandler.cc
@@ -147,6 +147,7 @@ void ThinningPointsHandler::advance()   {
     					return;
     				}
     				x_ = y_->second.begin();
+    				j = xfreq_;
     			}
     		}
     	}
diff --git a/src/common/Proj4Projection.cc b/src/common/Proj4Projection.cc
index b4132f3..be2dadd 100644
--- a/src/common/Proj4Projection.cc
+++ b/src/common/Proj4Projection.cc
@@ -278,14 +278,52 @@ void Proj4Projection::init()
 void Proj4Projection::full()
 {
 	if ( projection_->method_ == "simple" ) {
-		if ( min_longitude_ != -180 )
+
+		if ( max_longitude_ != 180. ) {
+			if ( max_latitude_ == 90 )	
+				max_latitude_ = projection_->maxlat_;
+			if ( min_latitude_ == -90 )	
+				min_latitude_ = projection_->minlat_;
 			corners();
-		if ( max_longitude_ != 180. )
+			return;
+		}
+		if ( max_longitude_ == 180. ) {
+			projection_->maxlon_ = 180.;
+			if ( max_latitude_ == 90 )	
+				max_latitude_ = projection_->maxlat_;
+			if ( min_latitude_ == -90 )	
+				min_latitude_ = projection_->minlat_;
 			corners();
-		if ( min_latitude_ != -90 )
+			return;
+		}
+		
+		if ( min_longitude_ != -180 ) {
+
+			// set projection default ! 
+			if ( max_latitude_ == 90 )	
+				max_latitude_ = projection_->maxlat_;
+			if ( min_latitude_ == -90 )	
+				min_latitude_ = projection_->minlat_;
 			corners();
-		if ( max_latitude_ != 90 )
+		}
+		
+		if ( min_latitude_ != -90 ) {
+			
+			if ( max_latitude_ == 90 )	
+				max_latitude_ = projection_->maxlat_;
+			
 			corners();
+			return;
+		}
+		if ( max_latitude_ != 90 ) {
+			if ( min_longitude_ == -180 )
+				min_longitude_ = projection_->minlon_;
+			if ( min_latitude_ == -90 )	
+				min_latitude_ = projection_->minlat_;			
+			corners();
+			return;
+		}
+	
 	}
 	
 }
@@ -339,7 +377,11 @@ PaperPoint Proj4Projection::operator()(const UserPoint& point)  const
     int error = pj_transform(from_, to_, 1, 1, &x, &y, NULL);
     if ( error ) {
 		MagLog::debug() << pj_strerrno(error) << " for " << point << endl;
-		return PaperPoint(-1000000, -10000000);
+//		NON Valeurs trop faibles en EPSG:3857 par exemple !  --> Transformation::in(pp) == True !
+//		-> Avec ces valeurs, si grille globale, les barbules des poles sont tracées dans l'atlantique sud
+//		en formant une couronne centrée vers( 9°W, 66°35S)
+//		return PaperPoint(-1000000, -10000000);   .// En plus il manque 1 zero !
+		return PaperPoint(-1e10, -1e10);    // Devrait suffire pour que Transformation::in(pp) == False qqsoient from_ et to_
 	}
 	
 	return PaperPoint(x, y, point.value_, point.missing(), point.border(), 0, point.name());
@@ -372,6 +414,19 @@ void Proj4Projection::setNewPCBox(double minx, double miny, double maxx, double
 
 void Proj4Projection::revert(const PaperPoint& xy, UserPoint& point)  const
 {
+	static bool first = true;
+	if ( first ) {
+		
+		const_cast<Proj4Projection*>(this)->init();
+		first = false;
+	}
+	if ( PCEnveloppe_->within(xy) == false ) {
+				  point = UserPoint(-1000, -1000);
+				  
+			 return;
+	}
+
+
 	double x = xy.x();
 	double y = xy.y();
 
@@ -410,6 +465,7 @@ void Proj4Projection::add(double lon, double lat)
 	int error =  pj_transform(from_, to_, 1, 1, &x, &y, NULL );
 	userEnveloppe_->push_back(PaperPoint(lon, lat));
 	PCEnveloppe_->push_back(PaperPoint(x, y));
+	
 	if ( x < min_pcx_ )  min_pcx_ = x;
 	if ( y < min_pcy_ )  min_pcy_ = y;
 	if ( x > max_pcx_ )  max_pcx_ = x;
diff --git a/src/common/Proj4Projection.h b/src/common/Proj4Projection.h
index 0b82e39..d7a7435 100644
--- a/src/common/Proj4Projection.h
+++ b/src/common/Proj4Projection.h
@@ -228,10 +228,10 @@ protected:
 	 double max_pcy_;
 	 mutable Epsg*   projection_;
 	 string definition_;
-	 double gridMinLon_;
-	 double gridMinLat_;
-	 double gridMaxLon_;
-	 double gridMaxLat_;
+	 mutable double gridMinLon_;
+	 mutable double gridMinLat_;
+	 mutable double gridMaxLon_;
+	 mutable double gridMaxLat_;
 
 
 private:
@@ -266,7 +266,7 @@ public:
 class Proj4EPSG900913 : public Proj4Projection
 {
 public:
-	Proj4EPSG900913() : Proj4Projection("EPSG:3857") {}
+    Proj4EPSG900913() : Proj4Projection("EPSG:3857") {}
 };
 class Proj4Geos : public Proj4Projection
 {
diff --git a/src/common/Symbol.h b/src/common/Symbol.h
index fa289c5..0f1ca47 100644
--- a/src/common/Symbol.h
+++ b/src/common/Symbol.h
@@ -133,7 +133,7 @@ private:
 class TextSymbol : public Symbol
 {
 public:
-	TextSymbol() : position_(M_BELOW) {}
+	TextSymbol() : position_(M_BELOW), blanking_(false) {}
 	~TextSymbol() {}
 
 	void push_back(const PaperPoint& point, const string& text) {
diff --git a/src/common/Transformation.cc b/src/common/Transformation.cc
index 1dfde5a..ef71638 100644
--- a/src/common/Transformation.cc
+++ b/src/common/Transformation.cc
@@ -729,19 +729,29 @@ void Transformation::thin(double step, PaperPoint& origin, vector<pair<double, d
 
 	std::set<double> xl, yl;
 
-
-
-	for ( double x = origin.x(), i = 1; x <= maxx; x = origin.x() + i*step, i++) {
+	// [RV] : Pour eviter des boucles infernales si origine très lointaine ( on la
+	// ramene à une valeur raisonnable )
+	// Cf modif GribInterpretor::reference()  ( En steropolaire sud (10e23, 10e23) avec gribs globaux !!)
+	double origx = origin.x();
+	if (origx < minx) origx += floor((minx - origx)/step) * step;
+	if (origx > maxx) origx -= floor((origx - maxx)/step) * step;
+
+	double origy = origin.y();
+	if (origy < miny) origy += floor((miny - origy)/step) * step;
+	if (origy > maxy) origy -= floor((origy - maxy)/step) * step;
+	// [RV]
+
+	for ( double x = origx, i = 1; x <= maxx; x = origx + i*step, i++) {
 		if ( x > minx )
 			xl.insert(x);
 	}
-	for ( double x = origin.x(), i = 1; x >= minx; x = origin.x() - i*step, i++)
+	for ( double x = origx, i = 1; x >= minx; x = origx - i*step, i++)
 		if ( x < maxx )
 			xl.insert(x);
-	for ( double y = origin.y(), i = 1; y <= maxy; y = origin.y() + i*step, i++)
+	for ( double y = origy, i = 1; y <= maxy; y = origy + i*step, i++)
 		if ( y > miny )
 			yl.insert(y);
-	for ( double y = origin.y(), i = 1; y >= miny; y = origin.y() - i*step, i++)
+	for ( double y = origy, i = 1; y >= miny; y = origy - i*step, i++)
 		if ( y < maxy ) {
 			yl.insert(y);
 
@@ -770,19 +780,29 @@ void Transformation::thin(double step, PaperPoint& origin, Matrix& matrix, doubl
 
 	std::set<double> xl, yl;
 
+	// [RV] : Pour eviter des boucles infernales si origine très lointaine ( on la
+	// ramene à une valeur raisonnable )
+	// Cf modif GribInterpretor::reference()  ( En steropolaire sud (10e23, 10e23) avec gribs globaux !!)
+	double origx = origin.x();
+	if (origx < minx) origx += floor((minx - origx)/step) * step;
+	if (origx > maxx) origx -= floor((origx - maxx)/step) * step;
 
+	double origy = origin.y();
+	if (origy < miny) origy += floor((miny - origy)/step) * step;
+	if (origy > maxy) origy -= floor((origy - maxy)/step) * step;
+	// [RV]
 
-	for ( double x = origin.x(), i = 1; x <= maxx; x = origin.x() + i*step, i++) {
+	for ( double x = origx, i = 1; x <= maxx; x = origx + i*step, i++) {
 		if ( x > minx )
 			xl.insert(x);
 	}
-	for ( double x = origin.x(), i = 1; x >= minx; x = origin.x() - i*step, i++)
+	for ( double x = origx, i = 1; x >= minx; x = origx - i*step, i++)
 		if ( x < maxx )
 			xl.insert(x);
-	for ( double y = origin.y(), i = 1; y <= maxy; y = origin.y() + i*step, i++)
+	for ( double y = origy, i = 1; y <= maxy; y = origy + i*step, i++)
 		if ( y > miny )
 			yl.insert(y);
-	for ( double y = origin.y(), i = 1; y >= miny; y = origin.y() - i*step, i++)
+	for ( double y = origy, i = 1; y >= miny; y = origy - i*step, i++)
 		if ( y < maxy ) {
 			yl.insert(y);
 
diff --git a/src/common/magics_api.h b/src/common/magics_api.h
index f14ffa4..1e2ac79 100644
--- a/src/common/magics_api.h
+++ b/src/common/magics_api.h
@@ -24,7 +24,7 @@ extern "C" {
 #endif
 
 void mag_open();
-void mag_close();
+int mag_close();
 void mag_coast();
 void mag_grib();
 void mag_mapgen();
diff --git a/src/decoders/CMakeLists.txt b/src/decoders/CMakeLists.txt
index b4b796f..af54e50 100644
--- a/src/decoders/CMakeLists.txt
+++ b/src/decoders/CMakeLists.txt
@@ -80,8 +80,8 @@ if (HAVE_NETCDF)
      list( APPEND decoders_srcs 
 #Netcdf--->
 decoders/NetcdfOrcaInterpretor.cc
-decoders/Netcdf.cc
-decoders/Netcdf.h
+decoders/NetcdfData.cc
+decoders/NetcdfData.h
 decoders/NetcdfConvention.cc
 decoders/NetcdfConvention.h
 decoders/NetcdfDecoder.cc
diff --git a/src/decoders/GribDecoder.cc b/src/decoders/GribDecoder.cc
index 4e8fc7a..d899627 100644
--- a/src/decoders/GribDecoder.cc
+++ b/src/decoders/GribDecoder.cc
@@ -300,8 +300,7 @@ void GribDecoder::read(Matrix **matrix, const Transformation&  transformation)
         *matrix = 0;
         return;
     }
-    long repres;
-    grib_get_long(handle_,"dataRepresentationType",&repres);
+    
     const string representation = getString("typeOfGrid");
 
     try {
@@ -1763,14 +1762,25 @@ void GribDecoder::decode(const Transformation& transformation)
     to_ =  DateTime(helper.get("grib"+id_, "end-date"));
 }
 
+//// RV MF ////
+void GribDecoder::decode1D()
+{
+    if (matrix_) return;
+    field_ = open(field_);
+    read(&matrix_);
+}
+//// RV MF ////
+
 void GribDecoder::decode()
 {
 
     if ( dimension_ == 1) {
-        if (matrix_) return;
-        field_ = open(field_);
-        read(&matrix_);
-        if (!matrix_) return;
+// RV MF
+//      if (matrix_) return;
+//      field_ = open(field_);
+//      read(&matrix_);
+//      if (!matrix_) return;
+        decode1D();
     }
     else {
         decode2D();
diff --git a/src/decoders/GribDecoder.h b/src/decoders/GribDecoder.h
index 3fff343..10612c6 100644
--- a/src/decoders/GribDecoder.h
+++ b/src/decoders/GribDecoder.h
@@ -86,6 +86,7 @@ public:
 	void set(const GribLoop&, int);
 	// implements Decoder interface
 	void decode();
+	void decode1D();  // RV MF
 	void decode2D();
 	void decode(const Transformation&);
 	void decode2D(const Transformation&);
@@ -159,7 +160,9 @@ public:
 	MatrixHandler& matrix()
 	{
 
-		decode();
+// RV MF
+		decode1D();
+//		decode();
 		matrixHandlers_.push_back(new MatrixHandler(*matrix_));
 		return *(matrixHandlers_.back());
 	}
diff --git a/src/decoders/GribRegularInterpretor.cc b/src/decoders/GribRegularInterpretor.cc
index 8f6d98e..23fef47 100644
--- a/src/decoders/GribRegularInterpretor.cc
+++ b/src/decoders/GribRegularInterpretor.cc
@@ -1092,8 +1092,6 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
     	(*matrix)->xIndex_.reserve((*matrix)->rowsAxis().size());
 	}
 
-
-
     // compute the number of points we'll be adding to the matrix so that we can
     // allocate them in one go, rather than allowing the STL to re-allocate
     // when we reach the capacity
@@ -1130,6 +1128,7 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
     vector<double>::iterator ll = (*matrix)->rowsAxis().begin();
     {
     Timer timer("map2", " pair");
+    bool first = true;
     for (vector<vector<double> >::iterator row = rows.begin(); row != rows.end(); ++row) {
 
     	vector<double> p;
@@ -1230,28 +1229,46 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
         double lon2 = *r;
 
         int x = 0;
+      
+
         while (x < nblon) {
+
             if ( lon < lon1 ) {
                 (*matrix)->push_back(p[0]);
                 x++;
                 lon = west + ( x*step);
                 continue;
             }
-            if ( lon > row->back() ) {
-                (*matrix)->push_back(p.back());
-                x++;
-                lon = west + ( x*step);
-                continue;
+            if ( lon >= row->back() ) { 
+                if ( global ) {
+                    p2 = 0;
+                    lon2 = 360.;
+                    lon1 = row->back();
+                    p1 = p.size()-1;
+                   
+
+                } 
+                else { 
+                    (*matrix)->push_back(p.back());
+                    x++;
+                    lon = west + ( x*step);
+                    continue;
+                }
             }
             if ( lon > lon2) {
+                
                 p1++;
                 p2++;
+                
                 lon1 = lon2;
+                
                 r++;
-                if ( r == row->end() )
+                if ( r == row->end() ) 
                     r--;
-                lon2 = (*r);
+                lon2 = (*r);   
+                
             }
+
             double d1 = (lon2 - lon) / (lon2 - lon1);
             double d2 = 1 - d1;
             double val;
@@ -1262,6 +1279,7 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
                    else
                 	   if ( p[p2] != missing )
                 		   val = (p[p1] * d1) + (p[p2] * d2);
+               
                   (*matrix)->push_back(val);
 
             }
@@ -1273,6 +1291,7 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
             x++;
             lon = west + ( x*step);
         }
+        
 
     }
     }
@@ -1591,10 +1610,10 @@ pair<double, double> GribRotatedInterpretor::rotate(double lat_y,
 
 void GribLambertAzimutalInterpretor::interpretAsMatrix(const GribDecoder& grib,
         Matrix** matrix, Matrix** matrix2) const {
+    /*
     long im = grib.getLong("numberOfPointsAlongXAxis");
     long jm = grib.getLong("numberOfPointsAlongYAxis");
 
-/*
     RotatedMatrix *rotated = new RotatedMatrix(jm, im);
     *matrix = rotated;
 
@@ -1637,7 +1656,7 @@ void GribLambertAzimutalInterpretor::interpretAsMatrix(const GribDecoder& grib,
     } catch (MagicsException& e) {
         MagLog::error() << e << "\n";
     }
-*/
+    */
 }
 
 void GribLambertAzimutalInterpretor::print(ostream& out) const {
diff --git a/src/decoders/InputMatrix.cc b/src/decoders/InputMatrix.cc
index 36bd1af..1ffa690 100644
--- a/src/decoders/InputMatrix.cc
+++ b/src/decoders/InputMatrix.cc
@@ -55,7 +55,7 @@ void InputMatrix::print(ostream& out)  const
 MatrixHandler& InputMatrix::matrix()
 {
 	Timer timer("InputMatrix", "Getting data");
-	if (simple_field_) 
+	if ( simple_field_ ) 
 		matrix_ = (*organization_).geoInterpret(&field_, *this);
 	this->matrixHandlers_.push_back(new MatrixHandler(*matrix_));
 	return *(this->matrixHandlers_.back()); 
@@ -84,7 +84,7 @@ void InputMatrix::getReady(const Transformation& transformation)
 	(*organization_).getReady(transformation);
 
 	if(transformation.coordinateType() == Transformation::GeoType ) {
-		if ( !field_.empty())
+		if ( !field_.empty()) 
 			matrix_ = (*organization_).geoInterpret(&field_, *this);
 		if ( !u_component_.empty())
 			u_ = (*organization_).geoInterpret(&u_component_, *this);
diff --git a/src/decoders/InputMatrixInterpretor.cc b/src/decoders/InputMatrixInterpretor.cc
index 839d95e..994a726 100644
--- a/src/decoders/InputMatrixInterpretor.cc
+++ b/src/decoders/InputMatrixInterpretor.cc
@@ -73,6 +73,9 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
 {
 	std::map<string, Mapper>::iterator mapper = mappers_.find(lowerCase(info.mapping_));
 
+
+
+	
 	if ( mapper == mappers_.end() )
 		MagLog::warning() << "unknow input matrix mapping " << info.mapping_ << endl;
 	else 
@@ -100,6 +103,7 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
 		lon = longitude_ +( i * longitude_step_);
 		in->columnsAxis().push_back(lon);
 		
+		
 	}
 
 	int nblat =  in->rows();
@@ -108,7 +112,9 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
 	for (int i = 0; i < nblat; i++) {	
 		lat = latitude_ + (i*latitude_step_);	
 		in->rowsAxis().push_back(lat);	
+		
 	}
+	
 	in->setMapsAxis();
 	in->missing(std::numeric_limits<double>::max());
     return in;
@@ -116,6 +122,7 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
 
 Matrix* InputMatrixRegularInterpretor::xyInterpret(Matrix* in, const InputMatrix& info)
 {
+	in->akimaEnabled();
 	in->missing(std::numeric_limits<double>::max());
 	if ( !in->rowsAxis().empty() )
 		// WE have already initialised the matrix ..
diff --git a/src/decoders/Netcdf.cc b/src/decoders/Netcdf.cc
deleted file mode 100644
index a1fcdba..0000000
--- a/src/decoders/Netcdf.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * (C) Copyright 1996-2016 ECMWF.
- * 
- * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
- * granted to it by virtue of its status as an intergovernmental organisation nor
- * does it submit to any jurisdiction.
- */
-
-//! \file Netcdf.cc
-/*!
- Sylvie Lamy-Thepaut - ECMWF Apr 02
- 
- Changes:
- 
-   Apr 06: update for GCC 4.0 (Stephan) 
-*/
-#include <algorithm>
-#include <Netcdf.h>
-#include <MagException.h>
-#include <MagLog.h>
- 
-
-using namespace magics;
-
-
-static bool isVariable(NcVar* var)
-{
-    if (var->num_dims() != 1) return true;
-    
-    string name0(var->name());
-    string name1(var->get_dim(0)->name());
-    if ( name0 == name1) return false;
-    return true; 
-}
-
-template <class From, class To>
-Convertor<From,To>::Convertor(NetVariable& var) : variable_(var)
-{
-	To scale(1);
-	To offset(0);
-	scale_factor_ = variable_.getAttribute("scale_factor", scale);
-	add_offset_ = variable_.getAttribute("add_offset", offset);
-	missing_ = variable_.getMissing();
-}
-
-
-
-template <class F, class T>   
-void TypedAccessor<F,T>::operator() (vector<T>& to, vector<long>& start, vector<long>& edges, NetVariable& var) const
-{
-	F* from = new F[to.size()];
-	var.id_->set_cur(&start[0]);
-	var.id_->get(from, &edges[0]);
-	// Convert the data....       
-	std::transform(from, from + to.size(), to.begin(), Convertor<F, T>(var));
-	delete[] from;
-}
-
-template <class F, class T> 
-void TypedAccessor<F,T>::get (vector<F>& from, vector<long>& start, vector<long>& edges, NetVariable& var)const
-{
-	var.id_->set_cur(&start[0]);
-	var.id_->get(from, &edges[0]);
-} 
-
-Netcdf::Netcdf(const string& path, const string& method) : file_(path.c_str())
-{
-	if (file_.is_valid() == false) {
-		throw NoSuchNetcdfFile(path);
-	}
-	for ( int v = 0; v < file_.num_vars(); v++)
-	{ 
-		NcVar* var = file_.get_var(v); 
-		variables_.insert(std::make_pair(var->name(), NetVariable(var->name(), var, file_, method)));
-
-		if (isVariable(var)) dataset_.insert(std::make_pair(var->name(), NetVariable(var->name(), var, file_, method)));
-	}
-	MagLog::debug() << "Initialisation of  Netcdf [" << path << "] OK! " << "\n";  
-	for ( int v = 0; v < file_.num_atts(); v++)
-		{
-			NcAtt* attr = file_.get_att(v);
-			attributes_.insert(std::make_pair(attr->name(), NetAttribute(attr->name(), attr)));
-		}
-	for ( int d = 0; d < file_.num_dims(); d++)
-		{
-			NcDim* var = file_.get_dim(d);
-			dimensions_.insert(std::make_pair(var->name(), NetDimension(var)));
-		}
-}
-
-
-Netcdf::~Netcdf() 
-{	
-}
-double Netcdf::getMissing(const string& var, const string& attr)
-{
-
-	missing_ = getAttribute(attr, getDefaultMissing(var));
-	missing_ = getVariableAttribute(var, attr, missing_);
-	return missing_;
-}
-
-void Netcdf::print(ostream& out)  const
-{
-	out << "print Netcdf: " << "\n";
-	out << "Variables: " << "\n";
-	for (map<string, NetVariable>::const_iterator var = variables_.begin(); var != variables_.end(); ++var)
-	{
-		out << (*var).second;
-	}
-	out << "Dataset: " << "\n";
-	for (map<string, NetVariable>::const_iterator var = dataset_.begin(); var != dataset_.end(); ++var)
-	{
-		out << (*var).second;
-	}
-}
-
-
-struct Index
-{
-	static map<NcType, Index*>* tools_;
-	Index(NcType type)
-	{
-		if ( tools_ == 0) tools_ = new  map<NcType, Index*>();
-		tools_->insert(std::make_pair(type, this));
-	}
-	virtual int operator()(const string& val,  NcValues* values, long nb )
-	{
-		ASSERT(false);
-	}
-	static int get(const NcType& type, const string& val,  NcValues* values, long nb)
-	{
-		map<NcType, Index*>::const_iterator tool = tools_->find(type);
-		if ( tool == tools_->end() ) {
-			ASSERT(false);
-			throw new MagicsException("No Index available");
-		}
-        
-		return (*(*tool).second)(val, values, nb);
-	}
-};
-
-struct FloatIndex: public Index
-{
-	FloatIndex() : Index(ncFloat) {}
-    
-	virtual int operator()(const string& val,  NcValues* values, long nb )
-	{
-		float value = atof(val.c_str());
-                if ( nb == 1 && values->as_float(0) == value) return 0;
-		for (int i = 0; i < nb - 1; i++) {
-			if (values->as_float(i) == value) return i;
-			if (values->as_float(i+1) == value) return i+1;
-			if (values->as_float(i) < value && value  < values->as_float(i+1) ) return i;  
-			if (values->as_float(i+1) < value && value  < values->as_float(i) ) return i+1;     
-		}
-		throw MagicsException("No such value : " + val);
-	}
-};
-
-struct DoubleIndex: public Index
-{
-	DoubleIndex() : Index(ncDouble) {}
-    
-	virtual int operator()(const string& val,  NcValues* values, long nb )
-	{
-		double value = tonumber(val);
-        if ( nb == 1 && values->as_double(0) == value) return 0;
-		for (int i = 0; i < nb - 1; i++) {
-			if (values->as_double(i) == value) return i;
-			if (values->as_double(i+1) == value) return i+1;
-			if (values->as_double(i) < value && value  < values->as_double(i+1) ) return i;  
-			if (values->as_double(i+1) < value && value  < values->as_double(i) ) return i+1;     
-		}
-		throw MagicsException("No such value : " + val);
-	}
-};
-
-
-struct IntIndex: public Index
-{
-	IntIndex() : Index(ncInt) {}
-    
-	virtual int operator()(const string& val,  NcValues* values, long nb )
-	{
-		int value = atoi(val.c_str());
-        	 if ( nb == 1 && values->as_int(0) == value) return 0;
-
-		for (int i = 0; i < nb - 1; i++)
-		{
-			if (values->as_int(i) == value) return i;
-			if (values->as_int(i+1) == value) return i+1;
-			if ( values->as_int(i) < value && value < values->as_int(i+1) ) return i;   
-			if ( values->as_int(i+1) < value && value < values->as_int(i) ) return i+1;     
-		}
-		throw MagicsException("No such value : " + val);
-	}
-};
-
-struct StringIndex: public Index
-{
-	StringIndex() : Index(ncChar) {}
-    
-	virtual int operator()(const string& val,  NcValues* values, long nb )
-	{
-
-		for (int i = 0; i < nb; i++)
-		{
-			string read(values->as_string(i));
-
-			if ( read == val) {
-
-				return i/64;
-			}
-		}
-		throw MagicsException("No such value : " + val);
-	}
-};
-
-map<NcType, Index*>*  Index::tools_ = 0;
-
-static FloatIndex float_index;
-static IntIndex int_index;
-static DoubleIndex double_index;
-static StringIndex string_index;
-
-int  NetDimension::index(const string& val)
-{
-	int index = atoi(val.c_str());
-	// if (index < )
-	return index;
-}
-
-int  NetDimension::value(const string& val)
-{
-	if ( variable_ ) {
-		int index = Index::get(variable_->type(), val, variable_->values(), variable_->num_vals());
-
-		return index;
-	}
-	// we assume the user is using a simple ..
-	int index = atoi(val.c_str());
-	MagLog::warning() << " Could not find variable return index instead " << index << endl;
-	//if (index < )
-	return index;
-}
-
-void NetDimension::first(const string& val)
-{
-
-	first_ = ( magCompare(method_, "value") ) ? value(val) : index(val);
-
-}
-
-
-void NetDimension::last(const string& val)
-{
-
-	int last =  (magCompare(method_, "value")) ? value(val) : index(val);
-	if ( last < first_ )
-	{
-		MagLog::warning() << "last position (" + val + ") < first position: exchange " << "\n";
-		int tmp = first_;
-		first_ = last;
-		last = tmp;
-	} 
-	dim_ = last - first_ + 1;   
-}
-
-
-NetVariable::NetVariable(const string& name, NcVar* id, const NcFile& file, const string& method): name_(name), id_(id)
-	{
-		for (int d = 0; d < id_->num_dims(); d++)
-		{
-			NcDim* dim = id_->get_dim(d);
-			NcVar* var = 0;
-			string dim_name = dim->name();
-		    for (int v = 0; v < file.num_vars(); v++) {
-		    	 string var_name = file.get_var(v)->name();
-		         if (var_name == dim_name) var = file.get_var(dim->name());
-		         
-		    }
-			dimensions_[dim->name()]= NetDimension(dim, var, d); 
-			dimensions_[dim->name()].method_ = method;
-		}
-		for (int a = 0; a < id_->num_atts(); a++)
-		{
-			NcAtt* att = id_->get_att(a);
-			attributes_[att->name()] = NetAttribute(att->name(), att); 
-		}
-	}
-
-double NetVariable::getDefaultMissing()
-{
-
-	if (id_->type() == ncDouble)
-		return NC_FILL_DOUBLE;
-	return NC_FILL_FLOAT;
-}
-
-
-
-namespace magics {
-	template<> map<NcType, Accessor<double>*>*  Accessor<double>::accessors_ = 0;
-	template<> map<NcType, Accessor<float>*>*  Accessor<float>::accessors_ = 0;
-} // end namespace
-
-
-static TypedAccessor<short, float>  short_float_accessor(ncShort);
-static TypedAccessor<int, float>  int_float_accessor(ncInt);
-static TypedAccessor<float, float>  float_float_accessor(ncFloat);
-static TypedAccessor<double, float> double_float_accessor(ncFloat);
-
-static TypedAccessor<ncbyte, double>  byte_double_accessor(ncByte);
-static TypedAccessor<short, double>  short_double_accessor(ncShort);
-static TypedAccessor<int, double>  int_double_accessor(ncInt);
-static TypedAccessor<float, double>  float_double_accessor(ncFloat);
-static TypedAccessor<double, double> double_double_accessor(ncDouble);
-
diff --git a/src/decoders/NetcdfData.cc b/src/decoders/NetcdfData.cc
new file mode 100644
index 0000000..1f07256
--- /dev/null
+++ b/src/decoders/NetcdfData.cc
@@ -0,0 +1,433 @@
+/*
+ * (C) Copyright 1996-2016 ECMWF.
+ * 
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+ * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+ */
+
+//! \file Netcdf.cc
+/*!
+ Sylvie Lamy-Thepaut - ECMWF Apr 02
+ 
+ Changes:
+ 
+   Apr 06: update for GCC 4.0 (Stephan) 
+*/
+#include <algorithm>
+#include <NetcdfData.h>
+#include <MagException.h>
+#include <MagLog.h>
+#include <MagConfig.h>
+ 
+
+using namespace magics;
+
+
+static bool isVariable(int netcdf, int var)
+{
+	int dims;
+    nc_inq_varndims(netcdf, var,  &dims);
+       
+    if (dims != 1) return true;
+
+   return false;
+}
+
+template <class From, class To>
+Convertor<From,To>::Convertor(NetVariable& var) : variable_(var)
+{
+	To scale(1);
+	To offset(0);
+	scale_factor_ = variable_.getAttribute("scale_factor", scale);
+	add_offset_ = variable_.getAttribute("add_offset", offset);
+	missing_ = variable_.getMissing();
+}
+
+
+
+template <class F, class T>   
+void TypedAccessor<F,T>::operator() (vector<T>& to, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const
+{
+	vector<F> from(to.size());
+	var.get(from, start, edges);
+	// Convert the data....       
+	std::transform(from.begin(), from.begin() + to.size(), to.begin(), Convertor<F, T>(var));
+	
+}
+
+template <class F, class T> 
+void TypedAccessor<F,T>::get (vector<F>& from, vector<size_t>& start, vector<size_t>& edges, NetVariable& var)const
+{
+	var.get(&from.front(), start, edges);
+} 
+
+Netcdf::Netcdf(const string& path, const string& method)
+{
+	int error = nc_open(path.c_str(), NC_NOWRITE, &file_);
+		
+	if (error) {
+		throw NoSuchNetcdfFile(path);
+	}
+
+	int num_var;
+	int var_ids[100];
+	nc_inq_varids(file_, &num_var, var_ids);
+
+	for ( int v = 0; v < num_var; v++)
+	{ 
+		// get the name 
+		char tmp[NC_MAX_NAME+1];
+		int id = var_ids[v];
+		nc_inq_varname 	(file_,  id, tmp);
+
+		string name(tmp);
+		
+		variables_.insert(std::make_pair(name, NetVariable(name, v, this, method)));
+		if (isVariable(file_, var_ids[v])) dataset_.insert(std::make_pair(name, NetVariable(name, var_ids[v], this, method)));
+	}
+
+
+	MagLog::debug() << "Initialisation of  Netcdf [" << path << "] OK! " << "\n";  
+
+	int num_atts;
+	nc_inq_varnatts(file_, NC_GLOBAL, &num_atts);
+	for ( int v = 0; v < num_atts; v++)
+	{
+
+			char tmp[NC_MAX_NAME+1];
+			nc_inq_attname(file_, NC_GLOBAL, v, tmp);
+			string name(tmp);
+			attributes_.insert(std::make_pair(name, NetAttribute(name, file_, NC_GLOBAL)));
+	}
+
+	int num_dims;
+	nc_inq_ndims(file_, &num_dims);
+	for ( int d = 0; d < num_dims; d++)
+	{
+			char tmp[NC_MAX_NAME+1];
+			nc_inq_dimname(file_, d, tmp);
+			string name(tmp);
+			dimensions_.insert(std::make_pair(name, NetDimension(this, name)));
+	}
+
+	
+
+
+}
+
+
+Netcdf::~Netcdf() 
+{	
+}
+double Netcdf::getMissing(const string& var, const string& attr)
+{
+
+	missing_ = getAttribute(attr, getDefaultMissing(var));
+	missing_ = getVariableAttribute(var, attr, missing_);
+	return missing_;
+}
+
+void Netcdf::print(ostream& out)  const
+{
+	out << "print Netcdf: " << "\n";
+	out << "Variables: " << "\n";
+	for (map<string, NetVariable>::const_iterator var = variables_.begin(); var != variables_.end(); ++var)
+	{
+		out << (*var).second;
+	}
+	out << "Dataset: " << "\n";
+	for (map<string, NetVariable>::const_iterator var = dataset_.begin(); var != dataset_.end(); ++var)
+	{
+		out << (*var).second;
+	}
+}
+
+
+NetDimension::NetDimension(Netcdf* netcdf, const string& name, int index, int variable): 
+			parent_(netcdf), name_(name), 
+            first_(0),  index_(index), variable_(variable)
+            {
+            	   netcdf_ = parent_->file();
+                   nc_inq_dimid(netcdf_, name_.c_str(), &id_);
+                   nc_inq_dimlen(netcdf_, id_, &size_);
+                   dim_ = size_;
+
+            }
+
+
+int  NetDimension::index(const string& val)
+{
+	int index = atoi(val.c_str());
+	return index;
+}
+
+int  NetDimension::value(const string& val)
+{
+	if ( variable_ != -1 ) {
+
+		//int index = Index::get(variable_->type(), val, variable_->values(), variable_->num_vals());
+		NetVariable var(name_, variable_, parent_, "index");
+		
+		return var.find(val);
+	}
+
+	// we assume the user is using index! ..
+	int index = atoi(val.c_str());
+	MagLog::warning() << " Could not find variable return index instead " << index << endl;
+	return index;
+}
+
+void NetDimension::first(const string& val)
+{
+
+	first_ = ( magCompare(method_, "value") ) ? value(val) : index(val);
+
+}
+
+
+void NetDimension::last(const string& val)
+{
+
+	int last =  (magCompare(method_, "value")) ? value(val) : index(val);
+	if ( last < first_ )
+	{
+		MagLog::warning() << "last position (" + val + ") < first position: exchange " << "\n";
+		int tmp = first_;
+		first_ = last;
+		last = tmp;
+	} 
+	dim_ = last - first_ + 1;   
+}
+
+
+NetVariable::NetVariable(const string& name, int id, Netcdf* parent, const string& method): name_(name), id_(id), parent_(parent)
+{
+	netcdf_ = parent_->file();
+	int num_dims;
+	nc_inq_varndims(netcdf_, id_, &num_dims);
+	int dims[num_dims];
+	nc_inq_vardimid(netcdf_, id_, dims);
+
+
+	for (int d = 0; d < num_dims; d++)
+	{
+		string tmp;
+		nc_inq_dimname(netcdf_, dims[d], &tmp[0]);
+		string name(tmp.c_str());
+		int var = -1;
+		// Try to find if a variable is defined with this name.
+		int num_var;
+		int var_ids[100];
+		nc_inq_varids(netcdf_, &num_var, var_ids);
+
+		for ( int v = 0; v < num_var; v++)
+		{ 
+			// get the name 
+			string tmp;
+			int id = var_ids[v];
+			nc_inq_varname 	(netcdf_,  id, &tmp[0]);
+			string current(tmp.c_str());
+			if ( current == name ) {
+				var = id;
+				break;
+			}
+		
+		}   
+		dimensions_.insert(std::make_pair(name, NetDimension(parent_, name, d, var)));
+		dimensions_[name].method_ = method;
+	}
+
+
+	
+	int num_atts;
+	nc_inq_varnatts(netcdf_, id_, &num_atts);
+	for ( int v = 0; v < num_atts; v++)
+	{
+
+			string tmp;
+			nc_inq_attname(netcdf_, id_, v, &tmp[0]);
+			string name(tmp.c_str());
+			attributes_.insert(std::make_pair(name, NetAttribute(name, netcdf_, id_)));
+	}
+		
+	missing_ = getDefaultMissing();
+}
+
+template <class T>
+int find(const T& value, vector<T>&  values)
+{
+    if ( values.size() == 1  && values[0] == value) 
+    	return 0;
+	for (int i = 0; i < values.size() - 1; i++) {
+		if (values[i] == value) return i;
+		if (values[i+1] == value) return i+1;
+		if (values[i] < value && value  < values[i+1] ) return i;  
+		if (values[i+1] < value && value  < values[i] ) return i+1;     
+	}
+	return -1;
+}
+
+#include "Tokenizer.h"
+#include "DateTime.h"
+string  NetVariable::interpretTime(const string& val) 
+{
+	string time = parent_->detect(name_, "time");
+	if ( time.empty() ) 
+		return val;
+
+	//try to convert the time ! 
+	static map<string, long> factors;
+	if ( factors.empty() ) {
+		factors["hours"] = 3600;
+		factors["days"] = 24*3600;
+	}
+	string units = getAttribute("units", string(""));
+	if ( units.empty() ) return val;
+	
+
+
+	// Now we parse the string !
+	vector<string> tokens;
+	Tokenizer tokenizer(" ");
+	tokenizer(units, tokens);
+	string basedate = tokens[2];
+	string unit = tokens[0];
+	
+
+	try {
+		
+		
+		DateTime user = DateTime(val);
+		DateTime reference = DateTime(basedate);
+		long diff = user - reference;
+		DateTime x = reference + diff;
+		
+		
+		map<string, long>::iterator f = factors.find(unit);
+		long factor = ( f != factors.end() ) ? f->second : 1;
+		diff = diff/factor;
+
+		
+		return tostring(diff);
+	}
+	catch (exception) {
+		
+		return val;
+	}
+	
+}
+
+int NetVariable::find(const string& value)
+{
+	// First , is the variable a time variable:
+	string val = interpretTime(value);
+	
+	
+
+	nc_type t = type();
+	if ( t == NC_DOUBLE ) {
+		vector<double> values;
+		values.resize(getSize());
+		get(values);
+		double dval = tonumber(val);
+		return ::find(dval, values);
+	}
+	if ( t == NC_INT ) {
+		vector<int> values;
+		values.resize(getSize());
+		get(values);
+
+
+		int dval = tonumber(val);
+		
+		
+		return ::find(dval, values);
+	}
+	if ( t == NC_FLOAT ) {
+		vector<float> values;
+		values.resize(getSize());
+		getValues(values);
+		float dval = tonumber(val);
+		return ::find(dval, values);
+	}
+	if ( t == NC_SHORT ) {
+		vector<short> values;
+		values.resize(getSize());
+		get(values);
+		short dval = tonumber(val);
+		return ::find(dval, values);
+
+	}
+
+
+	return -1;
+
+}
+
+
+double NetVariable::getDefaultMissing()
+{
+
+	if ( type() == NC_DOUBLE)
+		return NC_FILL_DOUBLE;
+	return NC_FILL_FLOAT;
+}
+
+
+
+
+string Netcdf::detect(const string& var, const string& type) const
+{
+	
+	NetVariable variable = getVariable(var);
+	vector<string> dimensions = variable.dimensions();
+
+	NetcdfGuess guesser;
+
+	map<string, map<string, vector<string> > >::iterator checks = guesser.guess_.find(type);
+	if ( checks == guesser.guess_.end() )
+		return "";
+
+	for ( map<string, vector<string> >::iterator check = checks->second.begin(); check != checks->second.end(); ++check) {
+		
+		vector<string> values =  check->second;
+		for (vector<string>::iterator dim = dimensions.begin(); dim != dimensions.end(); ++dim) {
+			string value = getVariable(*dim).getAttribute(check->first, string(""));
+				
+			for ( vector<string>::iterator v = values.begin(); v != values.end(); ++v) {
+				string val = value.substr(0, v->size());
+
+				if ( v->compare(val) == 0 ) {
+					
+					return  *dim;
+				}
+			}
+			
+		}
+	}
+	return "";
+
+	
+}
+    
+
+namespace magics {
+	template<> map<nc_type, Accessor<double>*>*  Accessor<double>::accessors_ = 0;
+	template<> map<nc_type, Accessor<float>*>*  Accessor<float>::accessors_ = 0;
+} // end namespace
+
+
+static TypedAccessor<short, float>  short_float_accessor(NC_SHORT);
+static TypedAccessor<int, float>  int_float_accessor(NC_INT);
+static TypedAccessor<float, float>  float_float_accessor(NC_FLOAT);
+static TypedAccessor<double, float> double_float_accessor(NC_FLOAT);
+
+//static TypedAccessor<nc_byte, double>  byte_double_accessor(NC_BYTE);
+static TypedAccessor<short, double>  short_double_accessor(NC_SHORT);
+static TypedAccessor<int, double>  int_double_accessor(NC_INT);
+static TypedAccessor<float, double>  float_double_accessor(NC_FLOAT);
+static TypedAccessor<double, double> double_double_accessor(NC_DOUBLE);
+
diff --git a/src/decoders/Netcdf.h b/src/decoders/NetcdfData.h
similarity index 58%
rename from src/decoders/Netcdf.h
rename to src/decoders/NetcdfData.h
index 0fc2f76..63edbfa 100644
--- a/src/decoders/Netcdf.h
+++ b/src/decoders/NetcdfData.h
@@ -23,7 +23,7 @@
 #define Netcdf_H
 
 #include "magics.h"
-#include "netcdfcpp.h"
+#include "netcdf.h"
 
 #include "MagException.h"
 #include "MagLog.h"
@@ -52,28 +52,27 @@ public:
 		MagicsException("Netcdf MagException: The file " + file + " does not exist or is not a valid netcdf file")
 		{	MagLog::error() << what_ << "\n"; }
 }; 
-
+class Netcdf;
 struct NetDimension 
 {
     string name_;
-    long   size_; 
-    long   first_;
-    long   dim_;
-    long   index_;
+    size_t   size_; 
+    size_t   first_;
+    size_t   dim_;
+    size_t  index_;
     string method_;
 
-    NcDim* id_;
-    NcVar* variable_;
+
+    int  id_;
+    int variable_;
+    
+    Netcdf* parent_;
+    int     netcdf_;
 
     NetDimension() {}
-    NetDimension(NcDim* id): name_(id->name()), size_(id->size()),
-            first_(0), dim_(size_), index_(0),
-            id_(id), variable_(0) {}
-    NetDimension(NcDim* id, NcVar* variable, long index) : 
-        name_(id->name()), size_(id->size()), 
-        first_(0), dim_(size_), index_(index), 
-        id_(id), variable_(variable)
-        {}
+    NetDimension(Netcdf* netcdf, const string& name, int index = 0, int variable = -1);
+
+    
         
     void first(const string&);
     void last(const string&);
@@ -93,23 +92,49 @@ struct NetDimension
 struct NetAttribute 
 {
 	string name_;
-	NcAtt* id_;
-	NetAttribute(const string name, NcAtt* id) : name_(name), id_(id) {} 
+	int id_;
+    int netcdf_;
+	NetAttribute(const string name, int netcdf, int id) : name_(name), netcdf_(netcdf), id_(id) {} 
 	NetAttribute() {}
-	void get(double& val)      { val =  id_->as_double(0); }
-	void get(float& val)       { val =  id_->as_float(0); }
-	void get(const char*& val) { val =  id_->as_string(0); }
+	void get(double& val)      { 
+        double tmp; 
+        nc_get_att_double(netcdf_, id_, name_.c_str(), &tmp); 
+        val = tmp;  
+    }
+	void get(float& val)  { 
+        float tmp; 
+        nc_get_att_float(netcdf_, id_, name_.c_str(), 
+            &tmp); 
+    }
+	void get(string& val) { 
+          size_t len;
+          nc_inq_attlen (netcdf_, id_, name_.c_str(),&len);
+          
+          char tmp[len];
+          nc_get_att_text(netcdf_, id_, name_.c_str(), tmp);
+          val = string(tmp, len);
+         
+      }
+    void get(char*& val) { 
+          size_t len;
+          nc_inq_attlen (netcdf_, id_, name_.c_str(),&len);
+          char* tmp  = new char[len];
+          //val = new char[len];
+          nc_get_att_text(netcdf_, id_, name_.c_str(), (char*)val);
+         
+    }
 
 };
 
 class NetVariable;
 
+
 template <class From, class To>
 struct Convertor
 {
 	Convertor(NetVariable& );
 	To operator()(From from)
-	{     
+	{   
         return  ( from != missing_) ? from * scale_factor_ + add_offset_ : missing_;
 	}  
 
@@ -124,52 +149,58 @@ template <class T>
 class Accessor
 {
 public:
-    Accessor(NcType type) {
-        if ( !accessors_) accessors_ = new map<NcType, Accessor<T>*>;
+    Accessor(nc_type type) {
+        if ( !accessors_) 
+            accessors_ = new map<nc_type, Accessor<T>*>;
         accessors_->insert(std::make_pair(type, this));
     }
     virtual ~Accessor() {    }
        
-    virtual void operator() (vector<T>&,  vector<long>& , vector<long>&, NetVariable&) const {}
+    virtual void operator() (vector<T>&,  vector<size_t>& , vector<size_t>&, NetVariable&) const {}
     
-    static map<NcType, Accessor<T>*>* accessors_;
+    static map<nc_type, Accessor<T>*>* accessors_;
     static void release() {
  		if ( accessors_ ) 
- 			for ( typename map<NcType, Accessor<T>*>::iterator a = accessors_->begin(); a != accessors_->end(); ++a) {
+ 			for ( typename map<nc_type, Accessor<T>*>::iterator a = accessors_->begin(); a != accessors_->end(); ++a) {
  				Accessor<T>* accessor = a->second;
  				 a->second = 0;
  				 delete accessor;
     		}
 	}
     
-
-    static void access(vector<T>& data, vector<long> start, vector<long> edges, NetVariable& var); 
-    static void access(vector<T>& data, NetDimension& dim){}
+    static void access(vector<T>& data, vector<size_t>& start, vector<size_t>& edges, NetVariable& var);  
+    
+   
 };
 
 template <class F, class T>
 class TypedAccessor : public Accessor<T>
 {
 public:
-	TypedAccessor(NcType type) : Accessor<T>(type) {}
+	TypedAccessor(nc_type type) : Accessor<T>(type) {}
 
-	void operator() (vector<T>& to, vector<long>& start, vector<long>& edges, NetVariable& var) const;
-	void get (vector<F>& from, vector<long>& start, vector<long>& edges, NetVariable& var) const;
+	void operator() (vector<T>& to, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const;
+    void get (vector<F>& from, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const;
+   
 };
 
 
+class Netcdf;
 
 struct NetVariable 
 {
 	string name_;
-	NcVar* id_;
+	int id_;
+    
+    Netcdf* parent_;
+    int netcdf_;
 	map<string, NetDimension> dimensions_;
 	map<string, NetAttribute> attributes_;
     double missing_;
     
-	NetVariable(const string& name, NcVar* id, const NcFile& file, const string& method);
+	NetVariable(const string& name, int id, Netcdf* parent, const string& method);
 
-	void getStartingPoint(vector<long>& dims)
+	void getStartingPoint(vector<size_t>& dims)
 	{
 		dims.resize(dimensions_.size());
 		for (map<string, NetDimension>::iterator dim = dimensions_.begin(); dim != dimensions_.end(); ++dim)
@@ -178,7 +209,7 @@ struct NetVariable
 		}
 	}
     
-	void getDimensions(vector<long>& dims)
+	void getDimensions(vector<size_t>& dims)
 	{
 		dims.resize(dimensions_.size());
 		for (map<string, NetDimension>::iterator dim = dimensions_.begin(); dim != dimensions_.end(); ++dim)
@@ -187,6 +218,13 @@ struct NetVariable
 		}
 	}
     
+    size_t getSize()
+    {
+        vector<size_t> dims;
+        getDimensions(dims);
+        return getSize(dims);
+
+    }
  
     void setFirstPoint(const string& name, const string& first)
     {
@@ -202,13 +240,62 @@ struct NetVariable
         (*d).second.last(last);
     }
     
-    long getSize(const vector<long>& dims)
+    size_t getSize(const vector<size_t>& dims)
     {
-       long size = 1;
-       for (unsigned int i = 0; i < dims.size(); i++)
+       size_t size = 1;
+       for (unsigned int i = 0; i < dims.size(); i++) {
            size = (dims[i] ) * size;
+           
+       }
+
        return size;    
     }
+    string  interpretTime(const string&);
+     
+    void get(vector<double>& data, vector<size_t>& start, vector<size_t>& edges )
+    {
+        nc_get_vara_double(netcdf_, id_, &start.front(), &edges.front(), &data.front());   
+    }
+
+    void get(vector<float>& data, vector<size_t>& start, vector<size_t>& edges )
+    {
+
+        nc_get_vara_float(netcdf_, id_, &start.front(), &edges.front(), &data.front()); 
+    }
+
+    void get(vector<int>& data, vector<size_t>& start, vector<size_t>& edges )
+    {
+
+        nc_get_vara_int(netcdf_, id_, &start.front(), &edges.front(), &data.front()); 
+    }
+    void get(vector<short>& data, vector<size_t>& start, vector<size_t>& edges )
+    {
+
+        nc_get_vara_short(netcdf_, id_, &start.front(), &edges.front(), &data.front()); 
+    }
+    void get(vector<double>& data )
+    {
+        nc_get_var_double(netcdf_, id_, &data.front());   
+    }
+
+    void get(vector<float>& data)
+    {
+
+        nc_get_var_float(netcdf_, id_,  &data.front()); 
+    }
+
+    void get(vector<int>& data )
+    {
+
+        nc_get_var_int(netcdf_, id_, &data.front()); 
+    }
+    void get(vector<short>& data )
+    {
+
+        nc_get_var_short(netcdf_, id_,  &data.front()); 
+    }
+
+
     void print(ostream& s) const
     {
         s << name_ << "[";
@@ -223,6 +310,14 @@ struct NetVariable
         
     }
 
+    nc_type type() {
+        nc_type type;
+        nc_inq_vartype(netcdf_, id_,  &type);
+        return type;
+    }
+   
+    int find(const string& value);
+
     double getMissing() { return missing_; }
     
     template <class T> 
@@ -235,6 +330,20 @@ struct NetVariable
         return val;
    
     } 
+    string  getAttribute(const string& name, const char* def) 
+    {
+        return getAttribute(name, string(def));
+        
+    } 
+    string getAttribute(const string& name, const string& def) 
+    {
+        
+        map<string, NetAttribute>::iterator attr = attributes_.find(name);
+        if ( attr == attributes_.end() ) return def;
+        string val;
+        (*attr).second.get(val);
+        return val;        
+    } 
     
     double getDefaultMissing();
     double getMissing(const string&);
@@ -248,15 +357,15 @@ struct NetVariable
         for (map<string, string>::const_iterator f = last.begin(); f != last.end(); ++f) {
             setLastPoint((*f).first, (*f).second);
         }
-        get(vals);
+        getValues(vals);
     }
     
     template <class T>
-    void get(vector<T>& vals)
+    void getValues(vector<T>& vals)
     {
-        vector<long> start;
+        vector<size_t> start;
         getStartingPoint(start);
-        vector<long> end;
+        vector<size_t> end;
         getDimensions(end);
         
         vals.resize(getSize(end));
@@ -264,6 +373,16 @@ struct NetVariable
     
         
     }
+
+    vector<string> dimensions() {
+        vector<string> dims;
+        for (map<string, NetDimension>::iterator dim = dimensions_.begin(); dim !=dimensions_.end(); ++dim)
+            dims.push_back(dim->first);
+        return dims;
+
+    }
+
+    
     
     friend ostream& operator<<(ostream& s,const NetVariable& p)
 		{ p.print(s); return s; }
@@ -289,7 +408,8 @@ public:
 
     double getMissing(const string&, const string&);
 
-
+    string detect(const string& var, const string& type) const;
+    
 
     template <class T>
     void get(const string& name, vector<T>& vals, 
@@ -302,7 +422,7 @@ public:
         (*var).second.missing_ = missing_;
         (*var).second.get(vals, first, last);
     }
-
+    int file() const { return file_; }
 
     template <class T>
     void get(const string& name, vector<T>& vals)
@@ -328,22 +448,44 @@ public:
     T getVariableAttribute(const string& name, const string& attr, T def)
     {
         map<string, NetVariable>::iterator var = variables_.find(name);
-        if ( var == variables_.end() ) throw NoSuchNetcdfVariable(name);
+        if ( var == variables_.end() ) 
+            throw NoSuchNetcdfVariable(name);
         return (*var).second.getAttribute(attr, def);
-    }      
+    }  
+
+   
+    string getVariableAttribute(const string& name, const string& attr, const string& def)
+    {
+        map<string, NetVariable>::iterator var = variables_.find(name);
+        if ( var == variables_.end() ) 
+            throw NoSuchNetcdfVariable(name);
+        return (*var).second.getAttribute(attr, def);
+    }     
     template <class T>
     T getAttribute(const string& name, T def)
     {
     	  T val;
     	  map<string, NetAttribute>::iterator attr = attributes_.find(name);
     	  if ( attr == attributes_.end() ) return def;
-    	        (*attr).second.get(val);
-    	        return val;
-
+    	  (*attr).second.get(val);
+    	  return val;
      }
-     NetVariable getVariable(const string& name)
+   
+    string getAttribute(const string& name, const string& def)
+    {
+        
+        map<string, NetAttribute>::iterator attr = attributes_.find(name);
+        if ( attr == attributes_.end() ) return def;
+        string val;
+        (*attr).second.get(val);
+        
+        return strdup(val.c_str());
+     }
+
+   
+     NetVariable getVariable(const string& name) const
      {
-		map<string, NetVariable>::iterator var = variables_.find(name);
+		map<string, NetVariable>::const_iterator var = variables_.find(name);
          	if ( var == variables_.end() ) throw NoSuchNetcdfVariable(name);
 	 	return (*var).second;
      }
@@ -365,54 +507,28 @@ protected:
     double missing_;
      
 private:
-	NcFile    file_;
+	int    file_;
 
 	friend ostream& operator<<(ostream& s,const Netcdf& p)
 		{ p.print(s); return s; }
 };
 
 
-template <class From, class To> 
-class DataAccessor
-{
-public:
-    DataAccessor(Netcdf& netcdf) : netcdf_(netcdf) {}
-    void operator()(const string& name, vector<To>& to)
-    {
-        vector<From> from;
-        netcdf_.get(name, from, start_, end_);
-        int i = 0;
-        for (typename vector<From>::const_iterator val = from.begin(); val != from.end(); ++val) {
-            To add = To(*val);
-         
-            to.push_back(To(*val));
-        }
-    }
-    
-   void setDimension(const string& name, long from, long dim) {
-        start_.insert(std::make_pair(name, from));
-        end_.insert(std::make_pair(name, dim));
-   }
-   
-   void setDimension(const string& name, long val) {
-        start_.insert(std::make_pair(name, val));
-        end_.insert(std::make_pair(name, 1));
-   }
-    
-   map<string, long> start_;
-   map<string, long> end_;
-   Netcdf& netcdf_;
-};
-
 template <class T> 
-void Accessor<T>::access(vector<T>& data, vector<long> start, vector<long> edges, NetVariable& var) 
+void Accessor<T>::access(vector<T>& data, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) 
 {
-	typename map<NcType, Accessor<T>*>::const_iterator accessor = accessors_->find(var.id_->type());
+   
+	typename map<nc_type, Accessor<T>*>::const_iterator accessor = accessors_->find(var.type());
 	if ( accessor == accessors_->end() ) throw new MagicsException("No accessor available");
 
 	(*(*accessor).second)(data, start, edges, var);
 }
 
+
+
+
+
+
 } // Namespace Magics
 
 
diff --git a/src/decoders/NetcdfDecoder.cc b/src/decoders/NetcdfDecoder.cc
index fc8962c..8e8aeba 100644
--- a/src/decoders/NetcdfDecoder.cc
+++ b/src/decoders/NetcdfDecoder.cc
@@ -112,18 +112,30 @@ void NetcdfDecoder::visit(MetaDataCollector& mdc)
 		}
 	}
 	
+	(*interpretor_).visit(mdc);
+
 	MetviewIcon::visit(mdc);  	
 }
 
 void NetcdfDecoder::visit(ValuesCollector& values)
 {
-	(*interpretor_).visit(values,points_);
+	try {
+		(*interpretor_).visit(values,points_);
+	}
+	catch (...) {
+		valid_ = false;
+	}
 }
 
 
 void NetcdfDecoder::visit(TextVisitor& text)
 {
-	(*interpretor_).visit(text);
+	try {
+		(*interpretor_).visit(text);
+	}
+	catch (...) {
+		valid_ = false;
+	}
 
 }
 
diff --git a/src/decoders/NetcdfDecoder.h b/src/decoders/NetcdfDecoder.h
index 2700240..eed1491 100644
--- a/src/decoders/NetcdfDecoder.h
+++ b/src/decoders/NetcdfDecoder.h
@@ -85,7 +85,10 @@ public:
         MagLog::dev() << "NetcdfDecoder::matrix! " << "\n";
         if ( !data_ )
         	valid_ = (*interpretor_).interpretAsMatrix(&data_);
+        if ( !valid_ )
+            throw MagicsException("Unable to use data");
         this->matrixHandlers_.push_back(new MatrixHandler(*data_));
+
         return *(this->matrixHandlers_.back());
     } 
     
diff --git a/src/decoders/NetcdfGeoMatrixInterpretor.cc b/src/decoders/NetcdfGeoMatrixInterpretor.cc
index 7b20582..ea5d691 100644
--- a/src/decoders/NetcdfGeoMatrixInterpretor.cc
+++ b/src/decoders/NetcdfGeoMatrixInterpretor.cc
@@ -21,7 +21,7 @@
 
 #include "NetcdfGeoMatrixInterpretor.h"
 #include "Factory.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include <limits>
 #include "Layer.h"
 
@@ -36,13 +36,14 @@ NetcdfGeoMatrixInterpretor::~NetcdfGeoMatrixInterpretor()
 
 
 
-bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** data)
+bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** matrix)
 {
-	if ( *data ) return false;
+	if ( *matrix ) return false;
 	
 	Netcdf netcdf(path_, dimension_method_);
 
-	string proj4 = netcdf.getAttribute("projection", "");
+
+	string proj4 = netcdf.getAttribute("projection", string(""));
 
 	if ( proj4.empty() ) {
 		matrix_ = new Matrix();
@@ -52,27 +53,22 @@ bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** data)
 		
 		matrix_ = new Proj4Matrix(proj4);
 	}
-	*data = matrix_;
+	*matrix = matrix_;
 
-	double missing_value = netcdf.getMissing(field_, missing_attribute_);
+	
 
 	// get the data ...
 	try
 	{
+		double missing_value = netcdf.getMissing(field_, missing_attribute_);
 		map<string, string> first, last;
 		setDimensions(dimension_, first, last);
 		vector<double> inlon, outlon;
 		vector<double> inlat, outlat;
-
 		
 		netcdf.get(longitude_, matrix_->columnsAxis(), first, last);
 		netcdf.get(latitude_, matrix_->rowsAxis(), first, last);
 	
-
-		
-
-
-
 		matrix_->missing(missing_value);
 
 		if  ( magCompare(primary_index_, "latitude") ) {			
@@ -86,25 +82,22 @@ bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** data)
 			     }
 		}
 		else {
+			Timer timer("CREATE matrix", "prepare");
 			vector<double> data;	
 			netcdf.get(field_, data, first, last);
-
 			matrix_->reserve(data.size());
+			int i = 0;
 			fill(matrix_->begin(), matrix_->end(), missing_value);
 			for (vector<double>::iterator d = data.begin(); d != data.end(); ++d ) 
 			{
-
-
 				if ( !std::isnan(*d) ) {
 					matrix_->push_back(*d);
-				}
-				else 
 					
-					matrix_->push_back(missing_value);
-				
+				}
+				i++;			
 			}
 		}
-
+		
 		matrix_->multiply(scaling_);
 		matrix_->plus(offset_);
 	    matrix_->setMapsAxis();
@@ -112,6 +105,8 @@ bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** data)
 	catch (MagicsException& e)
 	{
 		MagLog::error() << e << "\n";
+		delete matrix_;
+		matrix_ = NULL;
 		return false;
 	}
 	return true;
@@ -124,7 +119,7 @@ void NetcdfGeoMatrixInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfGeoMatrixInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfGeoMatrixInterpretorAttributes::print(out);
+	
 	out << "]";
 }
 
@@ -160,7 +155,7 @@ void NetcdfGeoMatrixInterpretor::visit(Transformation& transformation) {
 bool NetcdfGeoMatrixInterpretor::interpretAsPoints(PointsList& list)
 {
 	Netcdf netcdf(path_, dimension_method_);
-	string proj4 = netcdf.getAttribute("projection", "");
+	string proj4 = netcdf.getAttribute("projection", string(""));
 
 	if ( !proj4.empty() ) {
 		proj4_ = pj_init_plus(proj4.c_str());
@@ -181,8 +176,8 @@ bool NetcdfGeoMatrixInterpretor::interpretAsPoints(PointsList& list)
 		netcdf.get(latitude_, latitudes, first, last);
 		unsigned int val = 0;
 		
-		for (unsigned int  lat  =0 ; lat < latitudes.size(); lat+=latitude_sample_) {
-			for ( unsigned int lon = 0; lon < longitudes.size(); lon+=longitude_sample_) {
+		for (unsigned int  lat  =0 ; lat < latitudes.size(); lat++) {
+			for ( unsigned int lon = 0; lon < longitudes.size(); lon++) {
 				val = (lat* longitudes.size() + lon);
 				if ( val >= values.size() ) return true;
 				if ( values[val] < suppress_below_ ) continue;
@@ -303,3 +298,31 @@ void NetcdfGeoMatrixInterpretor::customisedPoints(const Transformation& transfor
 			MagLog::error() << e << "\n";
 		}
 }
+
+
+NetcdfInterpretor* NetcdfGeoMatrixInterpretor::guess(const NetcdfInterpretor& from)
+{
+	if ( from.field_.empty() &&  (from.x_component_.empty() || from.y_component_.empty() ) ) 
+		return 0;
+	
+	Netcdf netcdf(from.path_, from.dimension_method_);
+	
+	string variable = from.field_;
+	if ( variable.empty() ) 
+		variable = from.x_component_;
+	string latitude = netcdf.detect(variable, "latitude");
+	string longitude = netcdf.detect(variable, "longitude");
+
+	if ( latitude.size() && longitude.size() ) {
+		NetcdfGeoMatrixInterpretor* interpretor = new NetcdfGeoMatrixInterpretor();
+		
+		interpretor->NetcdfInterpretor::copy(from);
+		interpretor->latitude_ = latitude;
+		interpretor->longitude_ = longitude;
+		interpretor->time_variable_ = netcdf.detect(variable, "time");
+		interpretor->level_variable_ = netcdf.detect(variable, "level");
+		interpretor->number_variable_ = netcdf.detect(variable, "number");
+		return interpretor;
+	}
+	return 0;
+}
diff --git a/src/decoders/NetcdfGeoMatrixInterpretor.h b/src/decoders/NetcdfGeoMatrixInterpretor.h
index 6637605..5982e8a 100644
--- a/src/decoders/NetcdfGeoMatrixInterpretor.h
+++ b/src/decoders/NetcdfGeoMatrixInterpretor.h
@@ -24,7 +24,6 @@
 
 #include "magics.h"
 
-#include "NetcdfGeoMatrixInterpretorAttributes.h"
 #include "NetcdfInterpretor.h"
 #include "Matrix.h"
 #include "XmlNode.h"
@@ -32,27 +31,23 @@
 
 namespace magics {
 
-class NetcdfGeoMatrixInterpretor: public NetcdfGeoMatrixInterpretorAttributes, public NetcdfInterpretor {
+class NetcdfGeoMatrixInterpretor:  public NetcdfInterpretor {
 
 public:
 	NetcdfGeoMatrixInterpretor();
 	virtual ~NetcdfGeoMatrixInterpretor();
     
-    void set(const map<string, string>& params) { 
-        MagLog::debug() << "NetcdfGeoMatrixInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfGeoMatrixInterpretorAttributes::set(params);
-    }
-
+   
+    static NetcdfInterpretor* guess(const NetcdfInterpretor&);
     void visit(Transformation& transformation);
 
     void set(const XmlNode& node) { 
         MagLog::debug() << "NetcdfGeoMatrixInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(node); 
+        set(node); 
         XmlNode netcdf = node;
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf); 
-        NetcdfGeoMatrixInterpretorAttributes::set(node);
+        set(netcdf); 
+        
     }
 	virtual NetcdfInterpretor* clone() const {
     	NetcdfGeoMatrixInterpretor* object = new NetcdfGeoMatrixInterpretor();
@@ -60,8 +55,8 @@ public:
     	return object;
     }
     void clone(const NetcdfGeoMatrixInterpretor& other) {
-    	NetcdfInterpretorAttributes::copy(other); 
-    	NetcdfGeoMatrixInterpretorAttributes::copy(other); 
+    	copy(other); 
+    	
     }
     bool interpretAsMatrix(Matrix**);
     bool interpretAsPoints(PointsList&);
diff --git a/src/decoders/NetcdfGeopointsInterpretor.cc b/src/decoders/NetcdfGeopointsInterpretor.cc
index 77a802b..dc7518e 100644
--- a/src/decoders/NetcdfGeopointsInterpretor.cc
+++ b/src/decoders/NetcdfGeopointsInterpretor.cc
@@ -22,7 +22,7 @@
 #include "NetcdfGeopointsInterpretor.h"
 #include "TextVisitor.h"
 #include "Factory.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include <limits>
 #include "Layer.h"
 #include "SciMethods.h"
@@ -73,8 +73,8 @@ bool NetcdfGeopointsInterpretor::interpretAsPoints(PointsList& list, const Trans
 		
 		//If the lat-lon units is specified as "radians" convert lat-lon 
 		//to degrees. By default the units are sipposed to be "degrees"
-		const char *units = 0;
-		if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
+		string units;
+		if ( magCompare(netcdf.getVariableAttribute(latitude_,"units", units), string("radians")) )
 		{			
 			while ( lat!= latitudes.end()) {
 			  *lat=DEG(*lat);
@@ -130,7 +130,7 @@ bool NetcdfGeopointsInterpretor::interpretAsPoints(PointsList& list)
 		
 		//If the lat-lon units is specified as "radians" convert lat-lon 
 		//to degrees. By default the units are sipposed to be "degrees"
-		const char *units = 0;
+		string units;
 		if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
 		{
 			while ( lat!= latitudes.end()) {
@@ -457,8 +457,7 @@ void NetcdfXYpointsInterpretor::visit(MetaDataCollector& mdc)
 	map<string, NetAttribute>::iterator attrIt=attrs.find("_VIEW");
 	if( attrIt !=  attrs.end())
 	{  
-	  	const char* val;	  
-	  	attrIt->second.get(val);
+	  	const char* val =0; // = attrIt->second.get();
 	  	string str;
 	  	if(val) str=string(val);
 	  
diff --git a/src/decoders/NetcdfGeopointsInterpretor.h b/src/decoders/NetcdfGeopointsInterpretor.h
index 187f486..fc0d3c7 100644
--- a/src/decoders/NetcdfGeopointsInterpretor.h
+++ b/src/decoders/NetcdfGeopointsInterpretor.h
@@ -24,14 +24,13 @@
 
 #include "magics.h"
 
-#include "NetcdfGeopointsInterpretorAttributes.h"
-#include "NetcdfXYpointsInterpretorAttributes.h"
+
 #include "NetcdfInterpretor.h"
 #include "Matrix.h"
 #include "XmlNode.h"
 namespace magics {
 
-class NetcdfGeopointsInterpretor: public NetcdfInterpretor, public NetcdfGeopointsInterpretorAttributes {
+class NetcdfGeopointsInterpretor: public NetcdfInterpretor {
 
 public:
     NetcdfGeopointsInterpretor();
@@ -39,15 +38,15 @@ public:
 
     void set(const map<string, string>& params) {
         MagLog::debug() << "NetcdfGeopointsInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params);
-        NetcdfGeopointsInterpretorAttributes::set(params);
+        NetcdfInterpretor::set(params);
+        
     }
     void set(const XmlNode& node) {
         MagLog::debug() << "NetcdfGeopointsInterpretor::set(params)" << "\n";
         XmlNode netcdf = node;
-        NetcdfGeopointsInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(node);
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf);
+        NetcdfInterpretor::set(netcdf);
 
     }
     virtual NetcdfInterpretor* clone() const {
@@ -56,8 +55,8 @@ public:
         return object;
     }
     void clone(const NetcdfGeopointsInterpretor& other) {
-        NetcdfInterpretorAttributes::copy(other);
-        NetcdfGeopointsInterpretorAttributes::copy(other);
+        copy(other);
+        
     }
     bool interpretAsPoints(PointsList&);
     bool interpretAsPoints(PointsList&, const Transformation&);
@@ -82,7 +81,7 @@ private:
         { p.print(s); return s; }
 
 };
-class NetcdfXYpointsInterpretor: public NetcdfInterpretor, public NetcdfXYpointsInterpretorAttributes {
+class NetcdfXYpointsInterpretor: public NetcdfInterpretor {
 
 public:
     NetcdfXYpointsInterpretor();
@@ -90,15 +89,15 @@ public:
 
     void set(const map<string, string>& params) {
         MagLog::debug() << "NetcdfGeopointsInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params);
-        NetcdfXYpointsInterpretorAttributes::set(params);
+        NetcdfInterpretor::set(params);
+       
     }
     void set(const XmlNode& node) {
         MagLog::debug() << "NetcdfGeopointsInterpretor::set(params)" << "\n";
         XmlNode netcdf = node;
-        NetcdfXYpointsInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(node);
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf);
+        NetcdfInterpretor::set(netcdf);
 
     }
     virtual NetcdfInterpretor* clone() const {
@@ -107,8 +106,7 @@ public:
         return object;
     }
     void clone(const NetcdfXYpointsInterpretor& other) {
-        NetcdfInterpretorAttributes::copy(other);
-        NetcdfXYpointsInterpretorAttributes::copy(other);
+        copy(other);
     }
     bool interpretAsPoints(PointsList&, const std::set<string>&);
     bool interpretAsPoints(PointsList&);
diff --git a/src/decoders/NetcdfInterpretor.cc b/src/decoders/NetcdfInterpretor.cc
index b47f304..b5357f0 100644
--- a/src/decoders/NetcdfInterpretor.cc
+++ b/src/decoders/NetcdfInterpretor.cc
@@ -22,8 +22,13 @@
 
 
 #include "NetcdfInterpretor.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include "XmlReader.h"
+#include "NetcdfGeoMatrixInterpretor.h"
+#include "NetcdfVectorInterpretor.h"
+#include "NetcdfMatrixInterpretor.h"
+#include "Layer.h"
+
 #include <limits>
 
 using namespace magics;
@@ -32,6 +37,41 @@ NetcdfInterpretor::NetcdfInterpretor()
 {
 }
 
+NetcdfGuessInterpretor::NetcdfGuessInterpretor(): delegate_(0) 
+{
+
+}
+
+NetcdfGuessInterpretor::~NetcdfGuessInterpretor() {}
+
+NetcdfInterpretor* NetcdfGuessInterpretor::guess() const
+{
+	if (delegate_ )
+		return delegate_;
+	// guess!!
+	Netcdf netcdf(path_, dimension_method_);
+	string convention = netcdf.getAttribute("Conventions", string(""));
+	
+
+
+	delegate_ =  NetcdfGeoMatrixInterpretor::guess(*this);
+
+	if (delegate_)
+		return delegate_;  
+	
+	delegate_ =  NetcdfGeoVectorInterpretor::guess(*this);
+
+	if (delegate_)
+		return delegate_;  
+
+	MagLog::warning() << "Could not guess the type of netcdf: Use default -->matrix" << endl;
+	
+	delegate_ = new NetcdfMatrixInterpretor();
+	delegate_->NetcdfInterpretor::copy(*this);
+	return delegate_;
+
+}
+
 void NetcdfInterpretor::setDimensions(const stringarray& value, map<string, string>& first, map<string, string>& last)
 {
     first.clear();
@@ -61,7 +101,28 @@ void NetcdfInterpretor::setDimensions(const stringarray& value, map<string, stri
           
     }
 
+    // Special case for the time ! 
+
+    if ( time_variable_.size() && time_dimension_.size() ) {
+    	first[time_variable_] = time_dimension_;
+    	last[time_variable_] = time_dimension_;
+    }
+
+    // Special case for the number ! 
+    if ( number_variable_.size() && number_dimension_.size() ) {
+    	first[number_variable_] = number_dimension_;
+    	last[number_variable_] = number_dimension_;
+    	
+    }
+
+    // Special case for the level ! 
+    if ( level_variable_.size() && level_dimension_.size() ) {
+    	first[level_variable_] = level_dimension_;
+    	last[level_variable_] = level_dimension_;
+    }
+
 }
+
 NetcdfInterpretor::~NetcdfInterpretor() 
 {
 }
@@ -93,12 +154,12 @@ bool NetcdfInterpretor::reference_date(Netcdf& netcdf, const string& var, const
 	}
 
 	double missing_value = netcdf.getMissing(var, missing_attribute_);
-	string date = netcdf.getVariableAttribute(var, "reference_date", "");
+	string date = netcdf.getVariableAttribute(var, "reference_date", string(""));
 	if ( date.empty() ) return false;
 	originals.reserve(coords.size());
 	for (vector<double>::iterator c = coords.begin(); c != coords.end(); ++c)
 		 originals.push_back(*c);
-	string units = netcdf.getVariableAttribute(var, "units", "");
+	string units = netcdf.getVariableAttribute(var, "units", string(""));
 	basedate = date;
 	double diff = ( refdate.empty() ) ? 0 : DateTime(date) - DateTime(refdate) ;
 	map<string, double>::const_iterator factor = factors.find(units);
@@ -119,11 +180,13 @@ bool NetcdfInterpretor::cf_date(Netcdf& netcdf, const string& var, const string&
 
 	}
 	double missing_value = netcdf.getMissing(var, missing_attribute_);
-	string date = netcdf.getVariableAttribute(var, "long_name", "");
+	
+	string date = netcdf.getVariableAttribute(var, "long_name", string(""));
+	
 	if ( date.empty() ) return false;
 	if ( date != "time" && date != "date and time") return false;
 
-	string units = netcdf.getVariableAttribute(var, "units", "");
+	string units = netcdf.getVariableAttribute(var, "units", string(""));
 	if ( units.empty() ) return false;
 	originals.reserve(coords.size());
 	for (vector<double>::iterator c = coords.begin(); c != coords.end(); ++c)
@@ -159,8 +222,8 @@ string NetcdfInterpretor::getAttribute(const string& var, const string& attr, co
 {
 	Netcdf netcdf(path_, dimension_method_);
 	if ( var.empty() )
-		return netcdf.getAttribute(attr, def.c_str());
-	return netcdf.getVariableAttribute(var, attr, def.c_str());
+		return netcdf.getAttribute(attr, def);
+	return netcdf.getVariableAttribute(var, attr, def);
 }
 
 void NetcdfInterpretor::visit(TextVisitor& title)
@@ -174,7 +237,7 @@ void NetcdfInterpretor::visit(TextVisitor& title)
 		tag.decode(*t);
 	}
 	Netcdf netcdf(path_, dimension_method_);
-	title.addAutomaticTitle(netcdf.getAttribute("title", "NO TITLE"));
+	title.addAutomaticTitle(netcdf.getAttribute("title", string("NO TITLE")));
 }
 
 void NetcdfInterpretor::getAttributes(Netcdf& nc,const string& varName,string& keys,string& values)
@@ -185,10 +248,11 @@ void NetcdfInterpretor::getAttributes(Netcdf& nc,const string& varName,string& k
 		bool first=true;
 		for(map<string, NetAttribute>::iterator it=var.attributes_.begin(); it != var.attributes_.end(); it++)
 		{
-			const char* val;
-			string str;
+			string val;
 			it->second.get(val);
-			if(val) str=string(val);
+			
+			
+			
 		
 			if(!first)
 			{	
@@ -204,21 +268,39 @@ void NetcdfInterpretor::getAttributes(Netcdf& nc,const string& varName,string& k
 	catch ( ... ) {}
 }
 
+string NetcdfInterpretor::getTime(const string& format, const string& def) {
+        if ( time_dimension_.empty() )
+            return def;
+        else return time_dimension_;
+    } 
+string NetcdfInterpretor::getNumber(const string& format, const string& def) {
+    if ( number_dimension_.empty() )
+        return def;
+    else 
+        return number_dimension_;
+}
+string NetcdfInterpretor::getLevel(const string& format, const string& def) {
+    if ( level_dimension_.empty() )
+        return def;
+    else 
+        return level_dimension_;
+}
 
 void NetcdfTag::visit(const XmlNode& node)
 	{
 		if ( magCompare(node.name(), "netcdf_info") )
 		{
 			string var = node.getAttribute("variable");
-
 			string attr = node.getAttribute("attribute");
+			
 			string def = node.getAttribute("default");
-
-
+			string format = node.getAttribute("format");
 			string val = netcdf_.getAttribute(var, attr, def);
-
-
+			
 			title_.update("netcdf"+var, attr,  val);
+			title_.update("netcdf"+var, "time",  netcdf_.getTime(format, def));
+			title_.update("netcdf"+var, "level", netcdf_.getLevel(format, def));
+			title_.update("netcdf"+var, "number",  netcdf_.getLevel(format, def));	
 		}
 
 
@@ -245,3 +327,8 @@ void NetcdfTag::visit(const XmlNode& node)
 		}
      }
 
+void NetcdfGuessInterpretor::visit(MetaDataCollector& info) { 
+	for ( MetaDataCollector::iterator key = info.begin(); key != info.end(); ++key )
+		key->second = getAttribute(field_, key->first, "");
+	guess()->visit(info); 
+}
diff --git a/src/decoders/NetcdfInterpretor.h b/src/decoders/NetcdfInterpretor.h
index b448e5d..036d592 100644
--- a/src/decoders/NetcdfInterpretor.h
+++ b/src/decoders/NetcdfInterpretor.h
@@ -79,6 +79,9 @@ public:
 	bool reference_date(Netcdf& netcdf, const string&, const string&, string&, vector<double>&, vector<double>&);
 	//return true, if the the data is Metview-date compliant and the date axis has been set
 
+    string getTime(const string& format, const string& def);
+    string getNumber(const string& format, const string& def);
+    string getLevel(const string& format, const string& def);
 protected:
      //! Method to print string about this class on to a stream of type ostream (virtual).
 	 virtual void print(ostream&) const; 
@@ -90,6 +93,10 @@ protected:
      string refDateX_;
      string refDateY_;
 
+     string time_variable_;
+     string level_variable_;
+     string number_variable_;
+
 private:
     //! Copy constructor - No copy allowed
 	NetcdfInterpretor(const NetcdfInterpretor&);
@@ -101,6 +108,69 @@ private:
 	friend ostream& operator<<(ostream& s,const NetcdfInterpretor& p)
 		{ p.print(s); return s; }
 };
+
+class NetcdfGuessInterpretor: public NetcdfInterpretor {
+
+public:
+    NetcdfGuessInterpretor();
+    virtual ~NetcdfGuessInterpretor();
+    virtual void visit(Transformation&) {} //delegate_->visit(transformation); }
+    virtual void getReady(const Transformation&) {}
+    virtual bool interpretAsMatrix(Matrix** matrix)
+        { return guess()->interpretAsMatrix(matrix); }
+    virtual bool interpretAsVectors(Matrix** u, Matrix** v)
+        {  return guess()->interpretAsVectors(u, v);}
+    virtual bool interpretAsRaster(RasterData&)
+        {  ASSERT(false); return false; }
+    virtual bool interpretAsPoints(PointsList& out)
+        { ASSERT(false);  return false; }
+    virtual void customisedPoints(const std::set<string>& needs, CustomisedPointsList& out)  
+        { guess()->customisedPoints(needs, out); }
+    virtual void customisedPoints(const Transformation& transformation, const std::set<string>& needs, CustomisedPointsList& out, int thinning)
+        { guess()->customisedPoints(transformation, needs, out, thinning); }
+
+    virtual bool interpretAsPoints(PointsList& points, const Transformation&)
+        { return interpretAsPoints(points);}
+    virtual void set(const map<string, string>& params) { NetcdfInterpretorAttributes::set(params); }
+    virtual void set(const XmlNode& node) { NetcdfInterpretorAttributes::set(node); }
+     virtual bool accept(const string& node) { return NetcdfInterpretorAttributes::accept(node); }
+    virtual NetcdfInterpretor* clone() const {
+        NetcdfInterpretor* object = new NetcdfInterpretor();
+        object->copy(*this);
+        return object;
+    }
+    
+    virtual void statsData(map<string,vector<double> >&) {}
+    virtual void visit(MetaDataCollector& info);
+    virtual void visit(ValuesCollector&,PointsList&) {};
+    virtual void visit(TextVisitor& text) {
+        guess()->visit(text); 
+    }
+    
+    
+    
+protected:
+     //! Method to print string about this class on to a stream of type ostream (virtual).
+     virtual void print(ostream& s) const { 
+        
+    }
+     void setDimensions(const stringarray&, map<string, string>& first, map<string, string>& last);
+     void getAttributes(Netcdf&,const string&,string&,string&);
+     NetcdfInterpretor* guess() const;
+   
+    mutable NetcdfInterpretor* delegate_;
+
+private:
+    //! Copy constructor - No copy allowed
+    NetcdfGuessInterpretor(const NetcdfInterpretor&);
+    //! Overloaded << operator to copy - No copy allowed
+    NetcdfGuessInterpretor& operator=(const NetcdfInterpretor&);
+
+// -- Friends
+    //! Overloaded << operator to call print().
+    friend ostream& operator<<(ostream& s,const NetcdfGuessInterpretor& p)
+        { p.print(s); return s; }
+};
 template<>
 class MagTranslator<string, NetcdfInterpretor> { 
 public:
diff --git a/src/decoders/NetcdfMatrixInterpretor.cc b/src/decoders/NetcdfMatrixInterpretor.cc
index 2f32969..1f8aac0 100644
--- a/src/decoders/NetcdfMatrixInterpretor.cc
+++ b/src/decoders/NetcdfMatrixInterpretor.cc
@@ -23,7 +23,7 @@
 
 #include "NetcdfMatrixInterpretor.h"
 #include "Factory.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include "Coordinate.h"
 #include "Layer.h"
 #include "TextVisitor.h"
@@ -46,41 +46,51 @@ bool NetcdfMatrixInterpretor::interpretAsMatrix(Matrix** matrix)
 	MagLog::debug() << "NetcdfMatrixInterpretor::interpret()--->" << *this << "\n";
 	if ( *matrix ) return false;
 
-	
-	matrix_ = new Matrix();
-	
-	*matrix = matrix_;
-	if ( !matrix_->empty() ) return false;
-    
-	matrix_->missing(std::numeric_limits<double>::max());
+	try {
+		matrix_ = new Matrix();
+		
+		*matrix = matrix_;
+		if ( !matrix_->empty() ) return false;
+	    
+		matrix_->missing(std::numeric_limits<double>::max());
 
-	Netcdf netcdf(path_, dimension_method_);
-	double missing =  netcdf.getMissing(field_, missing_attribute_);
-	matrix_->missing(missing);
+		Netcdf netcdf(path_, dimension_method_);
+		double missing =  netcdf.getMissing(field_, missing_attribute_);
+		matrix_->missing(missing);
 
-	string title = netcdf.getAttribute("title", "NO TITLE");
+		string title = netcdf.getAttribute("title", string("NO TITLE"));
 
 
-    x();
-    y();
+	    x();
+	    y();
 	// get the data ...
-	try {
+	
 
 
 		map<string, string> first, last;
 		setDimensions(dimension_, first, last);
 		vector<double> rows = dateRows_.empty() ? rows_ : dateRows_;
 		vector<double> columns = dateColumns_.empty() ? columns_ : dateColumns_;
-
+		int index = 0;
 		for ( vector<double>::iterator r = rows.begin(); r != rows.end(); r++) {
 			vector<string> dims;
 			ostringstream x,y;
-			x.precision(20);
-			y.precision(20);
-			y << y_ << "/" << *r;
-			x << x_ << "/" << columns.front() << "/" << columns.back();
+			if ( magCompare(dimension_method_, "index" ) ) {
+				y << y_ << "/" << index << "/" << index;
+				x << x_ << "/" << 0 << "/" << columns.size()-1;
+			}
+			else {
+				x.precision(20);
+				y.precision(20);
+
+				y << y_ << "/" << *r << "/" << *r;
+				x << x_ << "/" << columns.front() << "/" << columns.back();
+			}
+			std::copy(dimension_.begin(), dimension_.end(), std::back_inserter(dims));
 			dims.push_back(y.str());
 			dims.push_back(x.str());
+			index++;
+
 			setDimensions(dims, first, last);
 			vector<double> data;
 			netcdf.get(field_, data, first, last);
@@ -114,6 +124,8 @@ bool NetcdfMatrixInterpretor::interpretAsMatrix(Matrix** matrix)
 	catch (MagicsException& e)
 	{
 		MagLog::error() << e << "\n";
+		delete matrix_;
+		matrix_ = NULL;
 		 return false;
 	}    
 	return true;
@@ -128,7 +140,7 @@ void NetcdfMatrixInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfMatrixInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfMatrixInterpretorAttributes::print(out);
+	
 	out << "]";
 }
 
@@ -163,7 +175,8 @@ bool NetcdfMatrixInterpretor::x()
     	}
         catch (...) {
         	MagLog::warning() << "No valid X dimension.." << endl;
-        		return false;
+        	throw MagicsException("Could not find any X axis");
+        		
         	}
     }
 
@@ -193,7 +206,8 @@ bool NetcdfMatrixInterpretor::x()
     	}
     }
     catch (...) {
-    	return false;
+    	throw MagicsException("Could not find any X axis");
+    	
     }
 
     return true;
@@ -229,7 +243,8 @@ bool NetcdfMatrixInterpretor::y()
     	}
     	catch (...) {
     		MagLog::warning() << "No valid Y dimension.." << endl;
-    		return false;
+    		throw MagicsException("Could not find any Y axis");
+    		
     	}
     } 
 
@@ -254,7 +269,8 @@ bool NetcdfMatrixInterpretor::y()
     	}
     }
     catch (...) {
-    	return false;
+    	throw MagicsException("Could not find any X axis");
+    	
     }
     return true;
 }
@@ -318,7 +334,9 @@ void NetcdfMatrixInterpretor::visit(Transformation& transformation)
 			}
 
 		}
-		catch ( ... ) {}
+		catch ( ... ) {
+			throw MagicsException("Could not find any X axis");
+		}
 		
 
 }
@@ -329,10 +347,10 @@ void NetcdfMatrixInterpretor::customisedPoints(const Transformation& transformat
 
 	Matrix* uc = 0;
 	Matrix* vc = 0;
-	field_ = u_component_;
+	field_ = x_component_;
 	if (!interpretAsMatrix(&uc) )
 		return;
-	field_ = v_component_;
+	field_ = y_component_;
 	if ( !interpretAsMatrix(&vc) )
 		return;
 
diff --git a/src/decoders/NetcdfMatrixInterpretor.h b/src/decoders/NetcdfMatrixInterpretor.h
index dae7d5e..10ed405 100644
--- a/src/decoders/NetcdfMatrixInterpretor.h
+++ b/src/decoders/NetcdfMatrixInterpretor.h
@@ -24,7 +24,7 @@
 
 #include "magics.h"
 
-#include "NetcdfMatrixInterpretorAttributes.h"
+
 #include "NetcdfInterpretor.h"
 #include "Matrix.h"
 #include "PaperPoint.h"
@@ -32,33 +32,31 @@
 
 namespace magics {
 
-class NetcdfMatrixInterpretor: public NetcdfMatrixInterpretorAttributes, public NetcdfInterpretor {
+class NetcdfMatrixInterpretor:  public NetcdfInterpretor {
 
 public:
 	NetcdfMatrixInterpretor();
 	virtual ~NetcdfMatrixInterpretor();
     
-    void set(const map<string, string>& params)
-    { 
-        MagLog::debug() << "NetcdfMatrixInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfMatrixInterpretorAttributes::set(params);
-    }
+   
     
     void set(const XmlNode& node)
     { 
         MagLog::debug() << "NetcdfMatrixInterpretor::set(params)" << "\n";
         XmlNode netcdf = node;
          netcdf.name("netcdf");
-         NetcdfInterpretorAttributes::set(netcdf); 
-        NetcdfMatrixInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(netcdf); 
+        NetcdfInterpretor::set(node);
     }
     
     bool accept(const string& node)
     { 
         if ( NetcdfInterpretorAttributes::accept(node) ) 
         	return true; 
-        return NetcdfMatrixInterpretorAttributes::accept(node);
+        if ( magCompare(node, "matrix")  )
+            return true;
+
+       
     }
 
     virtual NetcdfInterpretor* clone() const
@@ -71,8 +69,8 @@ public:
     void clone(const NetcdfMatrixInterpretor& )
 //    void clone(const NetcdfMatrixInterpretor& other)
     {
-    	NetcdfInterpretorAttributes::copy(*this); 
-    	NetcdfMatrixInterpretorAttributes::copy(*this); 
+    	NetcdfInterpretor::copy(*this); 
+    	
     }
     virtual bool interpretAsMatrix(Matrix**);
     virtual bool interpretAsPoints(PointsList& points, const Transformation&);
diff --git a/src/decoders/NetcdfOrcaInterpretor.cc b/src/decoders/NetcdfOrcaInterpretor.cc
index 38a4f18..f4ce910 100644
--- a/src/decoders/NetcdfOrcaInterpretor.cc
+++ b/src/decoders/NetcdfOrcaInterpretor.cc
@@ -21,7 +21,7 @@
 
 #include "NetcdfOrcaInterpretor.h"
 #include "Factory.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include <limits>
 
 using namespace magics;
@@ -43,7 +43,7 @@ bool NetcdfOrcaInterpretor::interpretAsMatrix(Matrix** data)
 
 	Netcdf netcdf(path_, dimension_method_);
 	NetVariable var = netcdf.getVariable(longitude_);
-	vector<long> dims;
+	vector<size_t> dims;
 	var.getDimensions(dims);
 
 
@@ -303,8 +303,8 @@ void NetcdfOrcaInterpretor::customisedPoints(const Transformation& transformatio
 
 			netcdf.get(longitude_, longitudes, first, last);
 			netcdf.get(latitude_,  latitudes, first, last);
-			netcdf.get(u_component_, x_component, first, last);
-			netcdf.get(v_component_, y_component, first, last);
+			netcdf.get(x_component_, x_component, first, last);
+			netcdf.get(y_component_, y_component, first, last);
 
 			for ( int ind = 0; ind < latitudes.size(); ind += thinning) {
 				CustomisedPoint* point = new CustomisedPoint();
@@ -329,7 +329,7 @@ void NetcdfOrcaInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfOrcaInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfOrcaInterpretorAttributes::print(out);
+	
 	out << "]";
 }
 
diff --git a/src/decoders/NetcdfOrcaInterpretor.h b/src/decoders/NetcdfOrcaInterpretor.h
index 6c9e74b..cd29169 100644
--- a/src/decoders/NetcdfOrcaInterpretor.h
+++ b/src/decoders/NetcdfOrcaInterpretor.h
@@ -24,7 +24,7 @@
 
 #include "magics.h"
 
-#include "NetcdfOrcaInterpretorAttributes.h"
+
 #include "NetcdfInterpretor.h"
 #include "Matrix.h"
 #include "MagException.h"
@@ -32,19 +32,13 @@
 
 namespace magics {
 
-class NetcdfOrcaInterpretor: 
-        public NetcdfOrcaInterpretorAttributes,
-		public NetcdfInterpretor {
+class NetcdfOrcaInterpretor: public NetcdfInterpretor {
 
 public:
 	NetcdfOrcaInterpretor();
 	virtual ~NetcdfOrcaInterpretor();
     
-    void set(const map<string, string>& params) { 
-        MagLog::debug() << "NetcdfOrcaInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfOrcaInterpretorAttributes::set(params);
-    }
+    
 
     bool interpretAsPoints(PointsList&);
     bool interpretAsMatrix(Matrix**);
diff --git a/src/decoders/NetcdfVectorInterpretor.cc b/src/decoders/NetcdfVectorInterpretor.cc
index bfa8735..d205462 100644
--- a/src/decoders/NetcdfVectorInterpretor.cc
+++ b/src/decoders/NetcdfVectorInterpretor.cc
@@ -23,7 +23,7 @@
 
 #include "NetcdfVectorInterpretor.h"
 #include "Factory.h"
-#include "Netcdf.h"
+#include "NetcdfData.h"
 #include "Coordinate.h"
 #include "Coordinate.h"
 
@@ -54,7 +54,6 @@ void NetcdfVectorInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfVectorInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfVectorInterpretorAttributes::print(out);
 	out << "]";
 }
 
@@ -123,7 +122,7 @@ void NetcdfGeoVectorInterpretor::customisedPoints(const Transformation& transfor
 			
 			//If the lat-lon units is specified as "radians" convert lat-lon 
 			//to degrees. By default the units are sipposed to be "degrees"
-			const char *units = 0;
+			string units;
 			if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
 			{			
 				while ( lat!= latitudes.end()) {
@@ -166,10 +165,33 @@ void NetcdfGeoVectorInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfGeoVectorInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfGeoVectorInterpretorAttributes::print(out);
 	out << "]";
 }
 
+NetcdfInterpretor* NetcdfGeoVectorInterpretor::guess(const NetcdfInterpretor& from)
+{
+	if ( from.x_component_.empty() ||  from.y_component_.empty()) 
+		return 0;
+	
+	Netcdf netcdf(from.path_, from.dimension_method_);
+	
+	string latitude_x = netcdf.detect(from.x_component_, "latitude");
+	string longitude_x = netcdf.detect(from.y_component_, "longitude");
+	
+	string latitude_y = netcdf.detect(from.x_component_, "latitude");
+	string longitude_y = netcdf.detect(from.y_component_, "longitude");
+
+	if ( latitude_x.size() && longitude_x.size() && latitude_y ==  latitude_x && longitude_y == longitude_x ) {
+		NetcdfGeoVectorInterpretor* interpretor = new NetcdfGeoVectorInterpretor();
+		
+		interpretor->NetcdfInterpretor::copy(from);
+		interpretor->latitude_ = latitude_x;
+		interpretor->longitude_ = longitude_x;
+		return interpretor;
+	}
+	return 0;
+}
+
 NetcdfGeoPolarMatrixInterpretor::NetcdfGeoPolarMatrixInterpretor() 
 {
 }
@@ -203,7 +225,7 @@ void NetcdfGeoPolarMatrixInterpretor::customisedPoints(const Transformation&, co
 			
 			//If the lat-lon units is specified as "radians" convert lat-lon 
 			//to degrees. By default the units are sipposed to be "degrees"
-			const char *units = 0;
+			string units;
 			if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
 			{			
 				while ( lat!= latitudes.end()) {
@@ -251,6 +273,6 @@ void NetcdfGeoPolarMatrixInterpretor::print(ostream& out)  const
 {
 	out << "NetcdfGeoPolarMatrixInterpretor[";
 	NetcdfInterpretor::print(out);
-	NetcdfGeoPolarMatrixInterpretorAttributes::print(out);
+	
 	out << "]";
 }
diff --git a/src/decoders/NetcdfVectorInterpretor.h b/src/decoders/NetcdfVectorInterpretor.h
index dfce0b3..6a1024f 100644
--- a/src/decoders/NetcdfVectorInterpretor.h
+++ b/src/decoders/NetcdfVectorInterpretor.h
@@ -24,9 +24,7 @@
 
 #include "magics.h"
 
-#include "NetcdfVectorInterpretorAttributes.h"
-#include "NetcdfGeoVectorInterpretorAttributes.h"
-#include "NetcdfGeoPolarMatrixInterpretorAttributes.h"
+
 #include "NetcdfInterpretor.h"
 #include "PaperPoint.h"
 #include "UserPoint.h"
@@ -35,34 +33,28 @@
 namespace magics {
 
 
-class NetcdfVectorInterpretor: public NetcdfVectorInterpretorAttributes, public NetcdfInterpretor {
+class NetcdfVectorInterpretor:  public NetcdfInterpretor {
 
 public:
 	NetcdfVectorInterpretor();
 	virtual ~NetcdfVectorInterpretor();
     
-    void set(const map<string, string>& params)
-    { 
-        MagLog::debug() << "NetcdfVectorInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfVectorInterpretorAttributes::set(params);
-    }
     
     void set(const XmlNode& node)
     { 
         MagLog::debug() << "NetcdfVectorInterpretor::set(params)" << "\n";
         XmlNode netcdf(node);
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf); 
+        NetcdfInterpretor::set(netcdf); 
         
-        NetcdfVectorInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(node);
     }
     
     bool accept(const string& node)
     { 
         if ( NetcdfInterpretorAttributes::accept(node) ) 
         	return true; 
-        return NetcdfVectorInterpretorAttributes::accept(node);
+        return magCompare(node, "vector");
     }
 
     virtual NetcdfInterpretor* clone() const
@@ -75,8 +67,8 @@ public:
     void clone(const NetcdfVectorInterpretor& )
 //    void clone(const NetcdfVectorInterpretor& other)
     {
-    	NetcdfInterpretorAttributes::copy(*this); 
-    	NetcdfVectorInterpretorAttributes::copy(*this); 
+    	NetcdfInterpretor::copy(*this); 
+    	
     }
     virtual void customisedPoints(const std::set<string>&, CustomisedPointsList&);
     virtual void customisedPoints(const Transformation&, const std::set<string>&, CustomisedPointsList&, int);
@@ -86,35 +78,30 @@ protected:
 	 virtual void print(ostream&) const; 
 };
 
-class NetcdfGeoVectorInterpretor: public NetcdfGeoVectorInterpretorAttributes, public NetcdfInterpretor {
+class NetcdfGeoVectorInterpretor: public NetcdfInterpretor {
 
 public:
 	NetcdfGeoVectorInterpretor();
 	virtual ~NetcdfGeoVectorInterpretor();
     
-    void set(const map<string, string>& params)
-    { 
-        MagLog::debug() << "NetcdfGeoVectorInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfGeoVectorInterpretorAttributes::set(params);
-    }
+    
     
     void set(const XmlNode& node)
     { 
         MagLog::debug() << "NetcdfGeoVectorInterpretor::set(params)" << "\n";
         XmlNode netcdf(node);
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf); 
-        NetcdfGeoVectorInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(netcdf); 
+        NetcdfInterpretor::set(node);
     }
     
     bool accept(const string& node)
     { 
         if ( NetcdfInterpretorAttributes::accept(node) ) 
         	return true; 
-        return NetcdfGeoVectorInterpretorAttributes::accept(node);
+        return magCompare(node,  "geovector");
     }
-
+    static NetcdfInterpretor* guess(const NetcdfInterpretor& from);
     virtual NetcdfInterpretor* clone() const
     {
     	NetcdfGeoVectorInterpretor* object = new NetcdfGeoVectorInterpretor();
@@ -125,8 +112,8 @@ public:
     void clone(const NetcdfGeoVectorInterpretor& )
 //    void clone(const NetcdfGeoVectorInterpretor& other)
     {
-    	NetcdfInterpretorAttributes::copy(*this); 
-    	NetcdfGeoVectorInterpretorAttributes::copy(*this); 
+    	NetcdfInterpretor::copy(*this); 
+    	
     }
     virtual void customisedPoints(const Transformation&, const std::set<string>&, CustomisedPointsList&, int);
    
@@ -140,33 +127,27 @@ protected:
 
 
 
-class NetcdfGeoPolarMatrixInterpretor: public NetcdfGeoPolarMatrixInterpretorAttributes, public NetcdfInterpretor {
+class NetcdfGeoPolarMatrixInterpretor: public NetcdfInterpretor {
 
 public:
 	NetcdfGeoPolarMatrixInterpretor();
 	virtual ~NetcdfGeoPolarMatrixInterpretor();
     
-    void set(const map<string, string>& params)
-    { 
-        MagLog::debug() << "NetcdfGeoPolarMatrixInterpretor::set(params)" << "\n";
-        NetcdfInterpretorAttributes::set(params); 
-        NetcdfGeoPolarMatrixInterpretorAttributes::set(params);
-    }
     
     void set(const XmlNode& node)
     { 
         MagLog::debug() << "NetcdfGeoPolarMatrixInterpretor::set(params)" << "\n";
         XmlNode netcdf(node);
         netcdf.name("netcdf");
-        NetcdfInterpretorAttributes::set(netcdf); 
-        NetcdfGeoPolarMatrixInterpretorAttributes::set(node);
+        NetcdfInterpretor::set(netcdf); 
+        NetcdfInterpretor::set(node);
     }
     
     bool accept(const string& node)
     { 
-        if ( NetcdfInterpretorAttributes::accept(node) ) 
+        if ( NetcdfInterpretor::accept(node) ) 
         	return true; 
-        return NetcdfGeoPolarMatrixInterpretorAttributes::accept(node);
+        return magCompare(node, "geopolarvector");
     }
 
     virtual NetcdfInterpretor* clone() const
@@ -179,8 +160,8 @@ public:
     void clone(const NetcdfGeoPolarMatrixInterpretor& )
 //    void clone(const NetcdfGeoPolarMatrixInterpretor& other)
     {
-    	NetcdfInterpretorAttributes::copy(*this); 
-    	NetcdfGeoPolarMatrixInterpretorAttributes::copy(*this); 
+    	NetcdfInterpretor::copy(*this); 
+    
     }
     virtual void customisedPoints(const Transformation&, const std::set<string>&, CustomisedPointsList&);
    
diff --git a/src/decoders/ShapeDecoder.cc b/src/decoders/ShapeDecoder.cc
index 1fd83bd..94d5444 100644
--- a/src/decoders/ShapeDecoder.cc
+++ b/src/decoders/ShapeDecoder.cc
@@ -1,22 +1,22 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
 
 /*! \file ShapeDecoder.cc
     \brief Implementation of the Template class ShapeDecoder.
-    
+
     Magics Team - ECMWF 2005
-    
+
     Started: Mon 12-Dec-2005
-    
+
     Changes:
-    
+
 */
 
 
@@ -30,7 +30,7 @@ ShapeDecoder::ShapeDecoder() :holes_(false)
 {
 }
 
-ShapeDecoder::~ShapeDecoder() 
+ShapeDecoder::~ShapeDecoder()
 {
 	MagLog::debug() << "clean ShapeDecoder->" << size() << endl;
 	for ( iterator line = begin(); line != end(); ++line) {
@@ -61,9 +61,9 @@ void ShapeDecoder::decode(const Transformation& transformation)
 }
 
 /*! \brief Method to read location and names of state capitals
-  
+
   \todo When we can handle Unicode we should change "nameascii" back to "name"
-  
+
 */
 void ShapeDecoder::customisedPoints(const std::set<string>&, CustomisedPointsList& out)
 {
@@ -77,22 +77,22 @@ void ShapeDecoder::customisedPoints(const std::set<string>&, CustomisedPointsLis
 		double  adfMinBound[4], adfMaxBound[4];
 		string shp = path_ + ".shp";
 		string dbf = path_ + ".dbf";
-		hSHP = SHPOpen( shp.c_str(), "rb" ); 
+		hSHP = SHPOpen( shp.c_str(), "rb" );
 		hDBF = DBFOpen( dbf.c_str(), "rb" );
 		if ( !hSHP || !hDBF ) {
-	   		    MagLog::error() << "Can not open Shapefile " << path_ << endl;
+	   		    MagLog::error() << "Can not open points Shapefile " << shp << endl;
 	   		    return;
 	   	}
 
 		SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
 
 		map<string, int> attributes;
-		
+
 		for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) {
 		            DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
 		            attributes.insert(make_pair(lowerCase(szTitle), i));
 		}
-		
+
 		map<string, int>::iterator index  = attributes.find("nameascii");
 		map<string, int>::iterator indexc = attributes.find("featurecla");
 
@@ -129,14 +129,14 @@ void ShapeDecoder::customisedPoints(const std::set<string>&, CustomisedPointsLis
 			}
 			SHPDestroyObject( psShape );
 		    }
-		    SHPClose( hSHP ); 
-            DBFClose ( hDBF ); 
+		    SHPClose( hSHP );
+            DBFClose ( hDBF );
 	}
 	catch (...)
 	{
 		MagLog::error() << "Can not open Shapefile " << path_ << endl;
 	}
-	MagLog::dev() << "Shape file--->" << this->size() << endl; 
+	MagLog::dev() << "Shape file--->" << this->size() << endl;
 }
 
 /*
@@ -159,7 +159,7 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
 
 		string shp = path_ + ".shp";
 		string dbf = path_ + ".dbf";
-		const SHPHandle hSHP = SHPOpen( shp.c_str(), "rb" ); 
+		const SHPHandle hSHP = SHPOpen( shp.c_str(), "rb" );
 		const DBFHandle hDBF = DBFOpen( dbf.c_str(), "rb" );
 
 		if ( !hSHP || !hDBF ) {
@@ -169,7 +169,7 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
 
 		SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
 		map<string, int> attributes;
-		
+
 		for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
 		{
 		            DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
@@ -189,7 +189,7 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
 							}
 
 			psShape = SHPReadObject( hSHP, i );
-		
+
 			bool add = true;
 			if ( index != attributes.end() )
 			{
@@ -221,7 +221,6 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
 
 				if ( !in && !right && !left ) continue;
 
-
 				PointsList *inlist, *leftlist, *rightlist;
 				if (in) {
 					push_back(new PointsList());
@@ -270,13 +269,13 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
 		SHPDestroyObject(psShape);
 
 		SHPClose( hSHP );
-        DBFClose ( hDBF ); 
+        DBFClose ( hDBF );
 	}
 	catch (...)
 	{
 		MagLog::error() << "Can not open Shapefile " << path_ << endl;
 	}
-	MagLog::dev() << "Shape file--->" << this->size() << endl; 
+	MagLog::dev() << "Shape file--->" << this->size() << endl;
 }
 
 
@@ -297,7 +296,7 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
 			string dbf = path_ + ".dbf";
 			hSHP = SHPOpen( shp.c_str(), "rb" );
 			if ( !hSHP  ) {
-			    	MagLog::error() << "Can not open Shapefile " << path_ << endl;
+			    	MagLog::error() << "Can not open Shapefile " << shp << endl;
 			    	return;
 			}
 			data.clear();
@@ -344,8 +343,8 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
 
 				Polyline* poly = 0;
                 Polyline* polyleft = 0;
-                Polyline* polyright = 0; 
-               
+                Polyline* polyright = 0;
+
                 if ( in) {
                     poly  = new Polyline();
                     data.push_back(poly);
@@ -358,7 +357,7 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
                     polyright  = new Polyline();
                     data.push_back(polyright);
                 }
-                
+
 				left = false;
 				right= false;
 				int index = 0;
@@ -383,7 +382,7 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
 							if ( poly )    {
 								if (  same(x, -180.) || same(x, 180.) )  {
 									if ( y > 0 ) {
-										index = j;		
+										index = j;
 									}
 								}
 								poly->push_back(PaperPoint(x, y));
@@ -399,8 +398,6 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
 				}
 				if ( index ) {
 					poly->rotate(index);
-					// Clean the south pole ...
-
 				}
 			}
 			SHPDestroyObject(psShape);
@@ -411,5 +408,3 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
 			MagLog::error() << "Can not open Shapefile " << path_ << endl;
 		}
 }
-
-
diff --git a/src/drivers/BaseDriver.cc b/src/drivers/BaseDriver.cc
index 30f7633..38f7b95 100644
--- a/src/drivers/BaseDriver.cc
+++ b/src/drivers/BaseDriver.cc
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -142,7 +142,7 @@ void BaseDriver::printOutputName(const std::string & str) const
 {
 	if(filelist_)
 	{
-		if(filelist_reset_) remove(filelist_name_.c_str()); 
+		if(filelist_reset_) remove(filelist_name_.c_str());
 		const SystemInfo info;
 		fstream fs;
 		if(numFiles_ == 0)
@@ -222,28 +222,32 @@ string BaseDriver::getFileName(const string &extension, const unsigned int no) c
 	string filename = name_;
 	if(filename.empty())
 	{
-	  filename = fullname_;
-	  if(!filename.empty()) full = true;
+		filename = fullname_;
+		if(!filename.empty()) full = true;
 	}
 	if(filename.empty())
 	{
-	  filename = legacyname_;
-	  if(!filename.empty()) legacy = true;
+		filename = legacyname_;
+		if(!filename.empty()) legacy = true;
 	}
 	if(filename.empty())
 	{
-	  filename = extension;
+		filename = extension;
 	}
 
-	// name stays the same as given
-	if( no==0 && (full || (legacy && extension=="ps")) ) return filename;
-	if( no==0 && (extension=="ps" || extension=="pdf" || extension=="kmz") )  { filename += ext;return filename;}
-
 	// if nothing is set
-	if(filename=="") filename = "magics";
+	if(filename.empty()) filename = "magics";
+
+	// name stays the same as given
+	if( no==0 )
+	{
+		if(full || (legacy && extension=="ps")) return filename;
+		if(extension=="ps" || extension=="pdf" || extension=="kmz") { filename += ext;return filename;}
+	}
 
 	if(full)
 	{
+		ext="";
 		string::size_type pos = filename.find_last_of(".");
 		if(pos != string::npos)
 		{
@@ -269,7 +273,6 @@ string BaseDriver::getFileName(const string &extension, const unsigned int no) c
 	{
 		filename += ext;
 	}
-
 	return filename;
 }
 
@@ -279,7 +282,7 @@ string BaseDriver::getFileName(const string &extension, const unsigned int no) c
   This methods processes the Layout objects. It needs to be checked if a Layout is a new page or not.
   \sa Layout
 */
-MAGICS_NO_EXPORT void BaseDriver::redisplay(const Layout& layout) const 
+MAGICS_NO_EXPORT void BaseDriver::redisplay(const Layout& layout) const
 {
 	project(layout);
 	staLayouts_.push(&layout);
@@ -326,7 +329,7 @@ void BaseDriver::redisplay(const PolylineSet& line) const
 
 /*!
   \brief Decision how to stroke/fill simple polygon
-  
+
   Overwritten in SVGDriver::redisplay(const Polyline& line) const
 */
 void BaseDriver::redisplay(const Polyline& line) const
@@ -365,12 +368,12 @@ void BaseDriver::redisplay(const Symbol& symbol) const
 	renderSymbols(symbol);
 }
 
-void BaseDriver::redisplay(const TextSymbol& symbol) const 
+void BaseDriver::redisplay(const TextSymbol& symbol) const
 {
 	renderTextSymbols(symbol);
 }
 
-void BaseDriver::redisplay(const ComplexSymbol& symbol) const 
+void BaseDriver::redisplay(const ComplexSymbol& symbol) const
 {
 	renderComplexSymbols(symbol);
 }
@@ -430,7 +433,7 @@ double BaseDriver::LSF(MFloat *x,MFloat *y, int i0) const
 	{
 	 angle = atan2( (sxy/sxx) ,1.);
 	}
-	else 
+	else
 	{
 		angle=10.;
 		MagLog::debug() << "BaseDriver: Devision through zero prevented in calculation of Label angle!" << endl;
@@ -470,7 +473,7 @@ void BaseDriver::printLine(const Polyline &line) const
 //	  if(line.getAntiAliasing()) polylineAntialiasing_=true;
 	  renderPolyline(n, x, y);
 //	  polylineAntialiasing_=false;
-    
+
 	  Polyline::Holes::const_iterator h  = line.beginHoles();
 	  Polyline::Holes::const_iterator he = line.endHoles();
 
@@ -532,7 +535,7 @@ void BaseDriver::printLine(const Polyline &line) const
 
 	    const double distance_squared = ((THIS_X - PREV_X) * (THIS_X - PREV_X)) + ((THIS_Y - PREV_Y) * (THIS_Y - PREV_Y));
 
-	    if ( (arrowHead) || (distance_squared > min_square_distance_between_labels) ) 
+	    if ( (arrowHead) || (distance_squared > min_square_distance_between_labels) )
 	    {
 	       if(arrowHead)
 	       {
@@ -563,8 +566,8 @@ void BaseDriver::printLine(const Polyline &line) const
     	TextSymbol textSymbol;
 		textSymbol.position(TextSymbol::M_BELOW);
 		ostringstream nice;
-    	nice << angle;      
-	    textSymbol.push_back(pp, nice.str()); 				
+    	nice << angle;
+	    textSymbol.push_back(pp, nice.str());
 		renderTextSymbols(textSymbol);
        }
 */
@@ -574,7 +577,7 @@ void BaseDriver::printLine(const Polyline &line) const
               MFloat pro_x = x[i+2];
               MFloat pro_y = y[i+2];
               Text text;
-		      PaperPoint pp(pro_x,pro_y);		
+		      PaperPoint pp(pro_x,pro_y);
 		      text.push_back(pp);
 		      Label label= line.getLabel();
 		      MagFont font = label.font();
@@ -583,7 +586,7 @@ void BaseDriver::printLine(const Polyline &line) const
 		      text.setBlanking(label.getBlanking());
 		      text.setJustification(label.getJustification());
 		      text.setVerticalAlign(MHALF);
-		      text.setAngle(-setAngleY(angle));	
+		      text.setAngle(-setAngleY(angle));
 		      text.setFont(font);
 		      renderText(text);
 		   }
@@ -700,10 +703,10 @@ bool BaseDriver::renderPixmap(MFloat, MFloat, MFloat, MFloat, int, int, unsigned
 
 /*!
   Overwritten in KMLDriver
-  
+
   \sa Layer
 */
-MAGICS_NO_EXPORT void BaseDriver::redisplay(const Layer& layer) const 
+MAGICS_NO_EXPORT void BaseDriver::redisplay(const Layer& layer) const
 {
   MagLog::dev() << "BaseDriver::redisplay( layer) > " << layer.name()<< endl;
 }
@@ -734,14 +737,14 @@ void BaseDriver::redisplay(const StepLayer& layer) const
 }
 /*!
  \brief Method to read and execute binary file
- 
+
  This method is implemented for performance in Metview 4 and WREP
- 
+
 */
 void BaseDriver::setDimensionsFromBinary(string mbg_tmpl,MFloat &ratio,int &width) const
 {
   ifstream in(mbg_tmpl.c_str());
-  if(in.is_open()) 
+  if(in.is_open())
   {
 	char mag [6];
 	in.read((char *)(&mag), 6);
@@ -785,16 +788,16 @@ void BaseDriver::setDimensionsFromBinary(string mbg_tmpl,MFloat &ratio,int &widt
 
 /*!
  \brief Method to read and execute binary file
- 
+
  This method is implemented for performance in Metview 4 and WREP
- 
+
 */
-void BaseDriver::redisplay(const BinaryObject& binary) const 
+void BaseDriver::redisplay(const BinaryObject& binary) const
 {
   Timer timer("binary", " read");
   const string mbg_tmpl = binary.getPath();
   ifstream in(mbg_tmpl.c_str());
-  if(in.is_open()) 
+  if(in.is_open())
   {
     const float alpha = binary.getTransparency();
     applyGaussianBlur_ = binary.getGaussianBlur();
@@ -829,13 +832,13 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 
   int lengthHeader;
   in.read((char *)(&lengthHeader), sizeof(int));
-  
-  
+
+
   MFloat lx;
   MFloat ly;
   in.read((char *)(&lx), sizeof(MFloat));
   in.read((char *)(&ly), sizeof(MFloat));
-  
+
 //  if(lx!=0 || ly != 0) MagLog::warning()<<"Reading Binary: dimension mismatch!!!"<< std::endl;
   Layout la;
    la.x(binary.getMgb_x());
@@ -859,7 +862,7 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 		MFloat s;
 		int len, noNT;
 		int size;
-		{ 
+		{
 			in.read((char *)(&size), sizeof(int));
 			MFloat r,g,b;
 			in.read((char *)(&r), sizeof(MFloat));
@@ -950,7 +953,7 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 			  PaperPoint p(ax,ay);
 			  ArrowPoint ap(x, y, p);
 			  arrow.push_back(ap);
-			} 
+			}
 			renderWindArrow(arrow);
 		}
 		break;
@@ -991,7 +994,7 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 			tex[len]='\0';
 			string str(tex);
 			flag.setOriginMarker(str);
-	
+
 			for(int pts=0;pts<n;pts++)
 			{
 			  double x,y,ax,ay;
@@ -1004,7 +1007,7 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 			  PaperPoint p(ax,ay);
 			  ArrowPoint ap(x, y, p);
 			  flag.push_back(ap);
-			} 
+			}
 			renderWindFlag(flag);
 		}
 		break;
@@ -1123,7 +1126,7 @@ void BaseDriver::redisplay(const BinaryObject& binary) const
 			 }
 			}
 			line.setFillColour(Colour("green"));
-			FillShadingProperties* shading = new FillShadingProperties();    
+			FillShadingProperties* shading = new FillShadingProperties();
 			line.setShading(shading);
 			MFloat r,g,b,a;
 			in.read((char *)(&r), sizeof(MFloat));
diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt
index 08e6930..ebbecb7 100644
--- a/src/drivers/CMakeLists.txt
+++ b/src/drivers/CMakeLists.txt
@@ -10,13 +10,6 @@ list( APPEND _drivers_srcs
 # minizip
   minizip/ioapi.c minizip/zip.c
   minizip/ioapi.h minizip/zip.h minizip/crypt.h
-# libimagequant
-  libimagequant/blur.h libimagequant/libimagequant.c libimagequant/mediancut.c
-  libimagequant/mempool.c libimagequant/nearest.c libimagequant/pam.c
-  libimagequant/viter.c libimagequant/blur.c libimagequant/libimagequant.h
-  libimagequant/mediancut.h	libimagequant/mempool.h	libimagequant/nearest.h	libimagequant/pam.h libimagequant/viter.h
-  libimagequant/rwpng.c libimagequant/rwpng.h
-  libimagequant/pngquant.c libimagequant/pngquant.h
 )
 
 if( qt )
@@ -38,14 +31,14 @@ if( qt )
           MgQ/MgQPolylineSetItem.cc MgQ/MgQScene.cc MgQ/MgQSceneItem.cc
           MgQ/MgQSceneCacheItem.cc MgQ/MgQStepMetaData.cc
           MgQ/MgQPattern.cc MgQ/MgQHistoItem.cc
-   )   
+   )
    set (qt_files_HEADERS MgQ/MgQPlotScene.h)
    if( MAGICS_QT5 )
      QT5_WRAP_CPP(qt_files_HEADERS_MOC ${qt_files_HEADERS})
    else()
      QT4_WRAP_CPP(qt_files_HEADERS_MOC ${qt_files_HEADERS})
    endif()
-   list( APPEND qt_srcs   ${qt_files_HEADERS_MOC}) 
+   list( APPEND qt_srcs   ${qt_files_HEADERS_MOC})
 endif()
 
 if( HAVE_CAIRO )
@@ -53,19 +46,19 @@ if( HAVE_CAIRO )
 endif()
 
 if ( metview )
-   list (APPEND metview_include 
+   list (APPEND metview_include
 	drivers/DriverManager.h
-	drivers/BaseDriver.h 
+	drivers/BaseDriver.h
 	${CMAKE_CURRENT_BINARY_DIR}/../params/BaseDriverAttributes.h
 	)
    set( metview_include ${metview_include} PARENT_SCOPE )
 endif()
 
 if ( qt )
-   list (APPEND metview_include 
+   list (APPEND metview_include
 	drivers/MgQ/MgQPlotScene.h
 	drivers/MgQ/MgQScene.h
-	drivers/QtDriver.h 
+	drivers/QtDriver.h
 	drivers/MgQ/MgQLayoutItem.h
 	drivers/MgQ/MgQ.h
 	drivers/MgQ/MgQSceneItem.h
diff --git a/src/drivers/CairoDriver.cc b/src/drivers/CairoDriver.cc
index d376a23..059ac2c 100644
--- a/src/drivers/CairoDriver.cc
+++ b/src/drivers/CairoDriver.cc
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -72,16 +72,13 @@ Display *dpy;
 
 #define FONT_SCALE 25*.7  //! \todo clean-up!!!
 
-extern "C"{
-#include "libimagequant/pngquant.h"
-}
 
 using namespace magics;
 
 /*!
   \brief Constructor
 */
-CairoDriver::CairoDriver() : filename_(""), offsetX_(0), offsetY_(0), backend_("PDF")
+CairoDriver::CairoDriver() : offsetX_(0), offsetY_(0), backend_("PDF")
 {
         cr_ = 0;
 }
@@ -158,8 +155,8 @@ void CairoDriver::setupNewSurface() const
 	else if(magCompare(backend_,"pdf"))
 	{
 #if CAIRO_HAS_PDF_SURFACE
-	    filename_ = getFileName("pdf");
-	    surface_ = cairo_pdf_surface_create(filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+	    fileName_ = getFileName("pdf");
+	    surface_ = cairo_pdf_surface_create(fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 #else
 	    MagLog::error() << "CairoDriver: PDF output NOT supported! Enable PDF support in your Cairo installation." << std::endl;
 #endif
@@ -167,10 +164,10 @@ void CairoDriver::setupNewSurface() const
 	else if(magCompare(backend_,"ps"))
 	{
 #if CAIRO_HAS_PS_SURFACE
-        filename_ = getFileName("ps"); 
+        fileName_ = getFileName("ps");
         const int dimensionXglobal = static_cast<int>(getXDeviceLength()*72/2.54);
         const int dimensionYglobal = static_cast<int>(getYDeviceLength()*72/2.54);
-        surface_ = cairo_ps_surface_create(filename_.c_str(), dimensionXglobal,dimensionYglobal);
+        surface_ = cairo_ps_surface_create(fileName_.c_str(), dimensionXglobal,dimensionYglobal);
 #else
 	    MagLog::error() << "CairoDriver: PS output NOT supported! Enable PS support in your Cairo installation." << std::endl;
 #endif
@@ -178,22 +175,22 @@ void CairoDriver::setupNewSurface() const
 	else if(magCompare(backend_,"eps"))
 	{
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2)
-	    filename_ = getFileName("eps");
-	    surface_ = cairo_ps_surface_create(filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+	    fileName_ = getFileName("eps");
+	    surface_ = cairo_ps_surface_create(fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 	    cairo_ps_surface_set_eps (surface_,true);
 #else
 	    MagLog::error() << "CairoDriver: EPS output NOT supported! You need at least version Cairo 1.5.2.\n"
 	                 << "PostScript is generated instead." << std::endl;
-	    filename_ = getFileName("ps");
-	    surface_ = cairo_ps_surface_create(filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+	    fileName_ = getFileName("ps");
+	    surface_ = cairo_ps_surface_create(fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 #endif
 	}
 	else if(magCompare(backend_,"svg"))
 	{
 #if CAIRO_HAS_SVG_SURFACE
-	    filename_ = getFileName("svg",currentPage_+1);
+	    fileName_ = getFileName("svg",currentPage_+1);
 
-	    surface_ = cairo_svg_surface_create (filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+	    surface_ = cairo_svg_surface_create (fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 //	    cairo_svg_surface_restrict_to_version (surface_, CAIRO_SVG_VERSION_1_2);
 #else
 	    MagLog::error() << "CairoDriver: SVG output NOT supported! Enable SVG support in your Cairo installation." << std::endl;
@@ -267,8 +264,8 @@ void CairoDriver::setupNewSurface() const
 void CairoDriver::close()
 {
 	currentPage_ = 0;
-	if(magCompare(backend_,"pdf") && !filename_.empty()) printOutputName("CAIRO pdf "+filename_);
-	if(magCompare(backend_,"ps") && !filename_.empty()) printOutputName("CAIRO ps "+filename_);
+	if(magCompare(backend_,"pdf") && !fileName_.empty()) printOutputName("CAIRO pdf "+fileName_);
+	if(magCompare(backend_,"ps") && !fileName_.empty()) printOutputName("CAIRO ps "+fileName_);
 
 	if (!context_) {
 		cairo_surface_destroy (surface_);
@@ -310,8 +307,8 @@ MAGICS_NO_EXPORT void CairoDriver::startPage() const
 			cairo_destroy (cr_);
 			cairo_surface_destroy (surface_);
 
-			filename_ = getFileName("svg",currentPage_+1);
-			surface_ = cairo_svg_surface_create(filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+			fileName_ = getFileName("svg",currentPage_+1);
+			surface_ = cairo_svg_surface_create(fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 			cr_ = cairo_create (surface_);
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 4, 0)
 			cairo_svg_surface_restrict_to_version (surface_, CAIRO_SVG_VERSION_1_1);
@@ -324,8 +321,8 @@ MAGICS_NO_EXPORT void CairoDriver::startPage() const
 			cairo_destroy (cr_);
 			cairo_surface_destroy (surface_);
 
-			filename_ = getFileName("eps",currentPage_+1);
-			surface_ = cairo_ps_surface_create(filename_.c_str(), dimensionXglobal_, dimensionYglobal_);
+			fileName_ = getFileName("eps",currentPage_+1);
+			surface_ = cairo_ps_surface_create(fileName_.c_str(), dimensionXglobal_, dimensionYglobal_);
 			cairo_ps_surface_set_eps (surface_,true);
 			cr_ = cairo_create (surface_);
 #endif
@@ -355,34 +352,34 @@ MAGICS_NO_EXPORT void CairoDriver::endPage() const
 
 	if(magCompare(backend_,"eps"))
 	{
-		if(!filename_.empty()) printOutputName("CAIRO eps "+filename_);
+		if(!fileName_.empty()) printOutputName("CAIRO eps "+fileName_);
 	}
 	else if(magCompare(backend_,"svg"))
 	{
-		if(!filename_.empty()) printOutputName("CAIRO svg "+filename_);
+		if(!fileName_.empty()) printOutputName("CAIRO svg "+fileName_);
 	}
 	else if (magCompare(backend_,"png") )
 	{
 		Timer timer("cairo", "write png");
-		filename_ = getFileName("png" ,currentPage_);
+		fileName_ = getFileName("png" ,currentPage_);
 		if(magCompare(palette_,"on"))
 		{
 		   if(!write_8bit_png())
 		   {
 		     MagLog::warning() << "CairoDriver::renderPNG > palletted PNG failed! Generate 24 bit one ..." << endl;
-		     cairo_surface_write_to_png(surface_, filename_.c_str());
+		     cairo_surface_write_to_png(surface_, fileName_.c_str());
 		   }
 		}
 		else
 		{
-		   cairo_surface_write_to_png(surface_, filename_.c_str());
+		   cairo_surface_write_to_png(surface_, fileName_.c_str());
 		}
-		if(!filename_.empty()) printOutputName("CAIRO png "+filename_);
+		if(!fileName_.empty()) printOutputName("CAIRO png "+fileName_);
 	}
 	else if (magCompare(backend_,"geotiff") )
 	{
 #ifdef HAVE_GEOTIFF
-		filename_ = getFileName("tif" ,currentPage_);
+		fileName_ = getFileName("tif" ,currentPage_);
 		write_tiff();
 #else
 		MagLog::error() << "CairoDriver: GEOTIFF not enabled!"<< std::endl;
@@ -400,7 +397,7 @@ void CairoDriver::newLayer(Layer&) const
 
 void CairoDriver::closeLayer(Layer&) const
 {
-    if(applyGaussianBlur_ > 0) 
+    if(applyGaussianBlur_ > 0)
     {
         blur_image_surface(surface_,50);
     }
@@ -432,16 +429,16 @@ MAGICS_NO_EXPORT void CairoDriver::write_tiff() const
     int          height = cairo_image_surface_get_height(surface_);
     const int    stride = cairo_image_surface_get_stride(surface_);
 
-    TIFF *tif = TIFFOpen(filename_.c_str(), "w");
+    TIFF *tif = TIFFOpen(fileName_.c_str(), "w");
     if (!tif) {
-        MagLog::warning() << "CairoDriver: Unable to open TIFF file "<<filename_<< std::endl;
+        MagLog::warning() << "CairoDriver: Unable to open TIFF file "<<fileName_<< std::endl;
         return;
     }
-    
+
     GTIF *gtif = GTIFNew(tif);
     if (!gtif)
     {
-        MagLog::warning() << "CairoDriver: Unable to open GeoTIFF file "<<filename_<< std::endl;
+        MagLog::warning() << "CairoDriver: Unable to open GeoTIFF file "<<fileName_<< std::endl;
         return;
     }
 
@@ -510,15 +507,16 @@ MAGICS_NO_EXPORT void CairoDriver::write_tiff() const
 
 MAGICS_NO_EXPORT bool CairoDriver::write_8bit_png() const
 {
+/*
     cairo_surface_flush (surface_);
     unsigned char *data = cairo_image_surface_get_data(surface_);
     const int     width = cairo_image_surface_get_width(surface_);
     const int    height = cairo_image_surface_get_height(surface_);
-  
+
     struct pngquant_options options_ = { };
     options_.liq = liq_attr_create();
     struct pngquant_options *options = &options_;
-    //    pngquant_file(filename_.c_str(), filename.c_str(), &options);
+    //    pngquant_file(fileName_.c_str(), filename.c_str(), &options);
 
     pngquant_error  retval             = SUCCESS;
     liq_image*      input_image        = NULL;
@@ -534,12 +532,12 @@ MAGICS_NO_EXPORT bool CairoDriver::write_8bit_png() const
 	data2[h*4*width+w+3] = data[h*4*width+w+3];  // a
       }
     }
- 
+
     input_image = liq_image_create_rgba(options->liq, data2, width, height, 0);
     if (!input_image) {
         //return OUT_OF_MEMORY_ERROR;
     }
-    
+
     int quality_percent = 90; // quality on 0-100 scale, updated upon successful remap
     png8_image output_image = {};
 
@@ -571,24 +569,25 @@ MAGICS_NO_EXPORT bool CairoDriver::write_8bit_png() const
     if (SUCCESS == retval) {
         output_image.fast_compression  = false; //  (fast_compression ? Z_BEST_SPEED : Z_BEST_COMPRESSION);
 
-        retval = write_image(&output_image, NULL, filename_.c_str(), options);
+        retval = write_image(&output_image, NULL, fileName_.c_str(), options);
     }
 
     liq_image_destroy(input_image);
     rwpng_free_image8(&output_image);
 
     if (SUCCESS == retval) return true;
+*/
     return false;
 }
 
-/*  
+/*
 MAGICS_NO_EXPORT void CairoDriver::write_8bit_png() const
 {
-    const string filename = filename_ +"_8bit";    
+    const string filename = fileName_ +"_8bit";
     FILE * fp = fopen (filename.c_str(), "wb");
     if (! fp) {
         MagLog::error() << "CairoDriver: Unable to open 8 bit PNG file "<<filename<< std::endl;
-        return;        
+        return;
     }
 
     cairo_surface_flush (surface_);
@@ -604,7 +603,7 @@ MAGICS_NO_EXPORT void CairoDriver::write_8bit_png() const
     	MagLog::error() << "CairoDriver: Unable to create WRITE struct for 8 bit PNG file "<<filename<< std::endl;
         return;
     }
- 
+
     png_infop info_ptr  = png_create_info_struct (png_ptr);
     if(!png_ptr)
     {
@@ -612,7 +611,7 @@ MAGICS_NO_EXPORT void CairoDriver::write_8bit_png() const
         return;
     }
 //    setjmp (png_jmpbuf (png_ptr));
-    
+
     // Set image attributes
     png_set_IHDR (png_ptr,
                   info_ptr,
@@ -623,21 +622,21 @@ MAGICS_NO_EXPORT void CairoDriver::write_8bit_png() const
                   PNG_INTERLACE_NONE,
                   PNG_COMPRESSION_TYPE_DEFAULT,
                   PNG_FILTER_TYPE_DEFAULT);
-    
+
     // Initialize rows of PNG.
     png_bytep *row_pointers = (png_bytep*) malloc(3 * width * sizeof(png_byte));
 
     for (size_t y = 0; y < height; ++y) {
         row_pointers[y] = data + width * 4 * y;
     }
-    
+
     // Write the image data to file
     png_init_io   (png_ptr, fp);
     png_set_rows  (png_ptr, info_ptr, row_pointers);
     png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);
 
- //   free (row_pointers); 
- //   png_destroy_write_struct (&png_ptr, &info_ptr);  
+ //   free (row_pointers);
+ //   png_destroy_write_struct (&png_ptr, &info_ptr);
     fclose (fp);
    return;
 }
@@ -917,7 +916,7 @@ MAGICS_NO_EXPORT void CairoDriver::renderSimplePolygon(const Polyline& line) con
 		vector<double> x;
 		vector<double> y;
 		line.hole(h,x,y);
-		if ( x.empty() ) 
+		if ( x.empty() )
 			continue;
 		cairo_move_to (cr_, projectX(x[0]),setY(projectY(y[0])));
 		vector<double>::const_iterator yt = y.begin();
@@ -1046,7 +1045,7 @@ MAGICS_NO_EXPORT void CairoDriver::renderSimplePolygon() const
 			cairo_move_to(cr2, density+.5*.5, 0);
 			cairo_line_to(cr2, density+.5*.5, density+.5);
 		}
-		if(indexHatch_==4 || indexHatch_==6) 
+		if(indexHatch_==4 || indexHatch_==6)
 		{
 			cairo_move_to(cr2,       0, 0);
 			cairo_line_to(cr2, density+.5, density+.5);
@@ -1102,7 +1101,7 @@ MAGICS_NO_EXPORT void CairoDriver::renderSimplePolygon() const
 
   Cairo expects a string as a char array, where each character is expressed as
   16 bit Unicode. Expat however delivers Multi-Byte encoding!
-  
+
   \sa http://www.pygtk.org/docs/pygtk/pango-markup-language.html
 
   \sa Text
@@ -1122,7 +1121,7 @@ MAGICS_NO_EXPORT void CairoDriver::renderText(const Text& text) const
 	vector<NiceText>::const_iterator niceText = text.textBegin();
 	vector<NiceText>::const_iterator niceTextEnd = text.textEnd();
 
-	MFloat textXoffset = 0.;
+	//MFloat textXoffset = 0.;
 	ostringstream alltext;
 
 	for(;niceText<niceTextEnd;niceText++)
@@ -1321,7 +1320,7 @@ MAGICS_NO_EXPORT bool CairoDriver::renderPixmap(MFloat x0,MFloat y0,MFloat x1,MF
 	cairo_save(cr_);
 	cairo_antialias_t t = cairo_get_antialias(cr_);
 	cairo_set_antialias(cr_, CAIRO_ANTIALIAS_NONE);
-	
+
 	for(int i=h-1;i>=0;i--)
 	{
 		for(int j=0;j<w; x0+=dx,j++)
@@ -1467,7 +1466,7 @@ MAGICS_NO_EXPORT bool CairoDriver::renderCellArray(const Image& image) const
 		const float cr = lt[c].red();
 		const float cg = lt[c].green();
 		const float cb = lt[c].blue();
-		
+
 		if(cr*cg*cb <0)
 		{
 			chImage[jj]=0; jj++;
@@ -1548,7 +1547,7 @@ MAGICS_NO_EXPORT void CairoDriver::renderSymbols(const Symbol& symbol) const
 	}
 	else
 	{
-	    string logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_;	
+	    string logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_;
 		if     (symbolName == "logo_cams") logofile += "CAMS_combined.png";
 		else if(symbolName == "logo_c3s")  logofile += "C3S_combined.png";
 		else   logofile += "ecmwf_logo_2014.png";
diff --git a/src/drivers/CairoDriver.h b/src/drivers/CairoDriver.h
index 8a616d9..0ae804d 100644
--- a/src/drivers/CairoDriver.h
+++ b/src/drivers/CairoDriver.h
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -116,8 +116,6 @@ private:
 	void print(ostream&) const;
 	MAGICS_NO_EXPORT void debugOutput(const string &s) const;
 
-	mutable string	filename_;
-
 	mutable cairo_t*	cr_;
 	mutable cairo_t*	tmp_cr_;
 	mutable cairo_surface_t* surface_;
diff --git a/src/drivers/GDDriver.cc b/src/drivers/GDDriver.cc
index 727af93..e114725 100644
--- a/src/drivers/GDDriver.cc
+++ b/src/drivers/GDDriver.cc
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -45,7 +45,7 @@ using namespace magics;
 /*!
   \brief Constructor
 */
-GDDriver::GDDriver() : filename_("magics_output.gif"),currentFont_(""),
+GDDriver::GDDriver() :currentFont_(""),
                       currentFontSize_(0),currentPageCount_(0),
                       lastPage_(-1),scaleFactor_(1),
                       animated_(false),jpg_(false),gif_(false),png_(false),
@@ -57,7 +57,7 @@ GDDriver::GDDriver() : filename_("magics_output.gif"),currentFont_(""),
 /*!
   \brief Destructor
 */
-GDDriver::~GDDriver() 
+GDDriver::~GDDriver()
 {
   relieveFonts();
 }
@@ -74,7 +74,7 @@ void GDDriver::open()
 {
 	currentPage_ = -1;
 	//needed for multithread apps!
-#ifndef MAGICS_GIF	
+#ifndef MAGICS_GIF
 	if(gdFontCacheSetup()!=0)  MagLog::error() << "GDDriver::readFonts() --> Cannot initialize font cache!\n";
 #endif
 //	setCMscale(30.);// cm -> pixel
@@ -140,7 +140,7 @@ void GDDriver::close()
 
  In this method the binary output file is opened.
  This includes the formation of the file name.
- 
+
  \sa endPage
 */
 MAGICS_NO_EXPORT void GDDriver::startPage() const
@@ -156,7 +156,7 @@ MAGICS_NO_EXPORT void GDDriver::startPage() const
 	currentPageCount_++;
 	currentPage_++;
 	newPage_ = true;
-	
+
 	int cPage = currentPage_;
 
 	if(!animated_)
@@ -168,7 +168,7 @@ MAGICS_NO_EXPORT void GDDriver::startPage() const
 	// No TrueColor otherwise transparent background does not work
 	currentImage_ = gdImageCreateTrueColor(dimensionXglobal_,dimensionYglobal_);
 	if(png_)
-	{	
+	{
 		gdImageAlphaBlending(currentImage_, 0);
 		gdImageSaveAlpha(currentImage_, 1); // save transparency
 	}
@@ -201,8 +201,8 @@ MAGICS_NO_EXPORT void GDDriver::startPage() const
 
 /*!
   \brief ending a page
- 
-  This method has to take care that for formats with multiple output 
+
+  This method has to take care that for formats with multiple output
   files are closed.
 
  A page in GD means normally a output file.
@@ -211,7 +211,7 @@ MAGICS_NO_EXPORT void GDDriver::startPage() const
 
  In this method the binary output file is opened.
  This includes the formation of the file name.
- 
+
  \sa startPage() close()
 */
 MAGICS_NO_EXPORT void GDDriver::endPage() const
@@ -227,7 +227,7 @@ MAGICS_NO_EXPORT void GDDriver::endPage() const
 #endif
 #endif
 	{
-		string fileName; 
+		string fileName;
 		// write image to file in PNG or JPEG - close and destoy
 		if( gif_ )
 		{
@@ -349,7 +349,7 @@ MAGICS_NO_EXPORT void GDDriver::setNewColour(const Colour &colour) const
 
 	currentColour_ = colour;
 
-	const int r = static_cast<int>(colour.red()*255.); 
+	const int r = static_cast<int>(colour.red()*255.);
 	const int g = static_cast<int>(colour.green()*255.);
 	const int b = static_cast<int>(colour.blue()*255.);
 	const int a = 127-static_cast<int>(colour.alpha()*127.);
@@ -373,7 +373,7 @@ MAGICS_NO_EXPORT int GDDriver::setLineParameters(const LineStyle linestyle, cons
 {
 //	int width = 1;
 //	if      (w > 3.) width=static_cast<int>(w*.25);
-//	else 
+//	else
 	int width=w*.25;
 	if(width<1) width=1;
 
@@ -568,10 +568,10 @@ MAGICS_NO_EXPORT void GDDriver::renderSimplePolygon(const Polyline& line) const
   This method renders given text strings.
 
  GD offers two ways of plotting text: using own line fonts or using TTF fonts.
- 
+
  By default line fonts are used if MAGICS_TTF is not set (see configure & config.h).
- 
- \note Be careful: TTF text ploting seems to fail in multithread context (AIX Jan2006) 
+
+ \note Be careful: TTF text ploting seems to fail in multithread context (AIX Jan2006)
   \sa Text
   \param text object containing the strings and their description
 */
@@ -686,7 +686,7 @@ MAGICS_NO_EXPORT void GDDriver::renderText(const Text& text) const
 			ttf += FontMap_["sansserif_normal"].ttf_filename; // if not found get default
 			MagLog::warning() << "GDDriver: Font "<< lowFont << " is not registered! Default font is used."<< endl;
 		}
-	
+
 		// test if font files exists
 		if(currentFont_!=ttf)
 		{
@@ -711,7 +711,7 @@ MAGICS_NO_EXPORT void GDDriver::renderText(const Text& text) const
 		// get bbx to size text
 		int bbx[8];
 		char *err = gdImageStringFT(NULL,&bbx[0],0,(char *)ttf.c_str(),fontSize,0.,10,10,(char*)(*niceText).text().c_str());
-	
+
 		if (err)
 		{
 			MagLog::error() << "GDDriver: gdImageStringFT (prettyText) -> "<< err <<" in "<<ttf<< endl;
@@ -826,7 +826,7 @@ MAGICS_NO_EXPORT void GDDriver::circle(const MFloat x, const MFloat y, const MFl
 MAGICS_NO_EXPORT bool GDDriver::renderPixmap(MFloat x0,MFloat y0,MFloat x1,MFloat y1,
                                             int w,int h,unsigned char* pixmap,int, bool alpha) const
 {
-	unsigned char *p = pixmap;	
+	unsigned char *p = pixmap;
 	const float dx =  (x1 - x0)/w;
 	const float dy =  (y1 - y0)/h;
 
@@ -865,7 +865,7 @@ MAGICS_NO_EXPORT bool GDDriver::renderPixmap(MFloat x0,MFloat y0,MFloat x1,MFloa
 /*!
   \brief render cell arrays
 
-  This method renders cell arrays, also called images in Magics language. These are 
+  This method renders cell arrays, also called images in Magics language. These are
   mainly used for satellite data.
 
   \sa renderPixmap()
@@ -874,7 +874,7 @@ MAGICS_NO_EXPORT bool GDDriver::renderPixmap(MFloat x0,MFloat y0,MFloat x1,MFloa
 */
 MAGICS_NO_EXPORT bool GDDriver::renderCellArray(const Image& image) const
 {
-	ColourTable &lt = image.getColourTable(); 
+	ColourTable &lt = image.getColourTable();
 	const int width  = image.getNumberOfColumns();
 	const int height = image.getNumberOfRows();
 	const float x0 = projectX(image.getOrigin().x());
@@ -888,9 +888,9 @@ MAGICS_NO_EXPORT bool GDDriver::renderCellArray(const Image& image) const
 	{
 		for(int j=0;j<width; j++)
 		{
-		  const int in = width*i+j;	 
+		  const int in = width*i+j;
 		  const short c = image[in];
- 
+
  		  if(!(lt[c]=="undefined"))
 		  {
 			const int r = static_cast<int>(lt[c].red()*255.);
@@ -951,10 +951,10 @@ MAGICS_NO_EXPORT void GDDriver::renderMagLogo(MFloat x, MFloat y) const
 MAGICS_NO_EXPORT void GDDriver::renderSymbols(const Symbol& symbol) const
 {
 	debugOutput("Start GDDriver Symbols");
-	
+
 	if(symbol.getSymbol()=="logo_ecmwf")
 		renderMagLogo(projectX(symbol[0].x()),projectY(symbol[0].y()));
-	else 
+	else
 		BaseDriver::renderSymbols(symbol);
 }
 
diff --git a/src/drivers/GDDriver.h b/src/drivers/GDDriver.h
index 7bd5541..1f04388 100644
--- a/src/drivers/GDDriver.h
+++ b/src/drivers/GDDriver.h
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -103,13 +103,12 @@ private:
 
 	mutable ofstream	xmlFile_;
 	mutable FILE*		outFile_;
-	mutable string	filename_;
 	mutable string	currentFont_;
 	mutable int		currentFontSize_;
 	mutable int		currentColourIndex_;
 	mutable int		currentLineStyleIndex_;
 	mutable int		currentPageCount_;
-	mutable int		lastPage_;    //!< for layers 
+	mutable int		lastPage_;    //!< for layers
 	mutable MFloat		scaleFactor_; //!< needed because GD uses different sizes as CM
 	mutable Layout*		currentLayout_;
 
diff --git a/src/drivers/GeoJsonDriver.cc b/src/drivers/GeoJsonDriver.cc
index 2550d65..61f2a08 100644
--- a/src/drivers/GeoJsonDriver.cc
+++ b/src/drivers/GeoJsonDriver.cc
@@ -435,14 +435,14 @@ MAGICS_NO_EXPORT int GeoJsonDriver::setLineParameters(const LineStyle , const MF
 */
 MAGICS_NO_EXPORT void GeoJsonDriver::renderPolyline(const int n, MFloat *x, MFloat *y) const
 {
-	pFile_ << "{\n \"coordinates\": [\n  [\n";
+	pFile_ << "{\n \"type\": \"Feature\", \"properties\": {\n    \"value\": \"2000\"\n  }, \"geometry\": { \n\t\"coordinates\": [\n  [\n";
 	for(int is=0;is<n;is++)
 	{
 		pFile_ <<"   ["<< x[is]<<","<<y[is]<<"]";
 		if(is<n-1) pFile_ <<",\n";
 		else       pFile_ <<"\n";
 	}
-	pFile_ << "  ] ],\n  \"properties\": {\n    \"type\": \"cold fronts\"\n  },\n  \"type\": \"MultiLineString\"\n}"<<endl;
+	pFile_ << "  ] ],\n  \"properties\": {\n    \"type\": \"isoline\"\n  },\n  \"type\": \"MultiLineString\"\n} },"<<endl;
 }
 
 
@@ -482,8 +482,11 @@ void GeoJsonDriver::renderSimplePolygon(const Polyline& line) const
 		x[i] = pp.x();
 		y[i] = pp.y();
 	}
+	
+	pFile_ << "{\n \"type\": \"Feature\", \"properties\": {\n   ";
+	pFile_ << " \"colour\": \"" << line.getFillColour().name() << "\"";
 
-	pFile_ << "{\n \"coordinates\": [\n  [\n";
+	pFile_ << "\n }, \"geometry\" : {\n \"coordinates\": [\n  [\n";
 	for(int is=0;is<n;is++)
 	{
 		pFile_ <<"   ["<< x[is]<<","<<y[is]<<"]";
@@ -491,7 +494,7 @@ void GeoJsonDriver::renderSimplePolygon(const Polyline& line) const
 		else       pFile_ <<"\n";
 
 	}
-	pFile_ << "  ],\n  \"properties\": {\n    \"type\": \"cold fronts\"\n  },\n  \"type\": \"MultiLineString\"\n}"<<endl;
+	pFile_ << "  ] ],\n   \"type\": \"Polygon\"\n} },"<<endl;
 
 	delete [] x;
 	delete [] y;
diff --git a/src/drivers/KMLDriver.cc b/src/drivers/KMLDriver.cc
index 0a58cad..1949e28 100644
--- a/src/drivers/KMLDriver.cc
+++ b/src/drivers/KMLDriver.cc
@@ -633,7 +633,7 @@ MAGICS_NO_EXPORT void KMLDriver::renderSimplePolygon(const int n, MFloat* xx, MF
 	pFile_ << "<Placemark>\n";
 	pFile_ << "<visibility>1</visibility>\n<open>0</open>\n";
 
-	const int a = (int)(transparency_ * 2.55);
+	//const int a = (int)(transparency_ * 2.55);
 
 	pFile_	<< "<Style>\n<PolyStyle>\n";
 	writeColour(currentColour_);
@@ -735,8 +735,8 @@ void KMLDriver::renderSimplePolygon(const Polyline& line) const
 	   line.hole(h,x,y);
 	   if ( x.empty() ) 
 	     continue;
-	   vector<double>::const_iterator yt = y.begin();
-	   vector<double>::const_iterator xt = x.begin();
+	   //vector<double>::const_iterator yt = y.begin();
+	   //vector<double>::const_iterator xt = x.begin();
 	   for(int it=0;it<x.size();it++)
 	    {
 	       pFile_ <<"\t"<< x[it] <<","<< y[it] <<","<<height_*1000<<"\n";
diff --git a/src/drivers/MgQ/MgQLayerItem.cc b/src/drivers/MgQ/MgQLayerItem.cc
index 7b9d8f8..df35c7b 100644
--- a/src/drivers/MgQ/MgQLayerItem.cc
+++ b/src/drivers/MgQ/MgQLayerItem.cc
@@ -82,6 +82,9 @@ MgQLayerItem::MgQLayerItem(Layer &layer,MgQLayoutItem *layout,int stepNum) :
 	{
 		histoItems_ << 0;
 	}
+
+	// Show layer according to its visibility
+   setData(MgQ::ItemIsVisibleKey,layer_.visibility());
 }
 
 MgQLayerItem::~MgQLayerItem()
diff --git a/src/drivers/MgQ/MgQPlotScene.cc b/src/drivers/MgQ/MgQPlotScene.cc
index 26cb1f2..37a617b 100644
--- a/src/drivers/MgQ/MgQPlotScene.cc
+++ b/src/drivers/MgQ/MgQPlotScene.cc
@@ -124,6 +124,7 @@ void MgQPlotScene::clearBeforeNewRequest()
 
 void MgQPlotScene::saveStateBeforeNewRequest()
 {
+#if 0
   	foreach(QList<MgQLayerState*> sc,previousSceneState_)
 	{
 		foreach(MgQLayerState* st, sc)
@@ -147,10 +148,12 @@ void MgQPlotScene::saveStateBeforeNewRequest()
 		previousSceneState_ << vec;
 		
 	}
+#endif
 }
 //Temporary solution until layers handled properly in Metview 4
 void MgQPlotScene::restoreLayerState()
-{	
+{
+#if 0
   	/*qDebug() << "restoreLayerState";
   	foreach(QList<MgQLayerState*> sc,previousSceneState_)
 	{
@@ -215,6 +218,7 @@ void MgQPlotScene::restoreLayerState()
 		 
 				
 	}		  				
+#endif
 }	
  
 void MgQPlotScene::addSceneItem(MgQSceneItem *item)
diff --git a/src/drivers/MgQ/MgQSceneItem.cc b/src/drivers/MgQ/MgQSceneItem.cc
index e80f388..f82205a 100644
--- a/src/drivers/MgQ/MgQSceneItem.cc
+++ b/src/drivers/MgQ/MgQSceneItem.cc
@@ -364,10 +364,13 @@ void MgQSceneItem::updateLayers()
  
 void MgQSceneItem::addLayerItem(MgQLayerItem* item) 
 {
-	layerItems_.push_back(item);
-	//item->setStackLevel(layerItems_.count()-1);
-	ASSERT(item->layer().zindex() >= 0);
-	item->setStackLevel(item->layer().zindex());
+   layerItems_.push_back(item);
+
+//------------------------------------------------------------
+// FAMI20160913: JUST TO MAKE IT WORK FOR THE MOMENT.
+// Uncomment command below:
+//   ASSERT(item->layer().zindex() >= 0);
+   item->setStackLevel(item->layer().zindex());
 }
 
 
diff --git a/src/drivers/PostScriptDriver.cc b/src/drivers/PostScriptDriver.cc
index 18ca005..48841d0 100644
--- a/src/drivers/PostScriptDriver.cc
+++ b/src/drivers/PostScriptDriver.cc
@@ -1,9 +1,9 @@
 /*
  * (C) Copyright 1996-2016 ECMWF.
- * 
+ *
  * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
- * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
  * granted to it by virtue of its status as an intergovernmental organisation nor
  * does it submit to any jurisdiction.
  */
@@ -300,7 +300,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::unproject() const
 	dimensionX_ = dimensionStack_.top();dimensionStack_.pop();
 	coordRatioX_  = scalesX_.top();scalesX_.pop();
 	coordRatioY_  = scalesY_.top();scalesY_.pop();
-	
+
 	fstream *ps = getStream();
 	*ps << "gr\n";
 	setLineParameters(M_SOLID, 1);
@@ -385,7 +385,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::writeColour() const
   \brief sets a new line width
 
   This line width stays the default width until the painting in the
-  current box is finished. 
+  current box is finished.
 
   \sa setLineParameters()
 */
@@ -602,7 +602,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::renderPolyline2(const int n, MFloat* x,
   \param line polyline to be filled
 */
 void PostScriptDriver::renderSimplePolygon(const Polyline& line) const
-{ 
+{
 	unsigned int n = line.size();
 	setNewColour(line.getFillColour());
 	line.getShading()->draw(*this);
@@ -779,7 +779,7 @@ void PostScriptDriver::renderSimplePolygon(const Polyline& line) const
 		   if(pcounter%10==0) *ps << "\n";
 		   pcounter++;
 		}
-		else */ 
+		else */
 if( !(zero(diffX) && zero(diffY)) )
 		{
 		   *ps <<  diffX << " " << diffY << " ";
@@ -833,7 +833,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::renderSimplePolygon(const int n, MFloat*
 	}
 
 	std::fstream *ps = getStream();
-	
+
 
 	if (currentShading_==M_SH_DOT)
 	{
@@ -987,13 +987,13 @@ MAGICS_NO_EXPORT void PostScriptDriver::renderText(const Text& text) const
 	vector<NiceText>::const_iterator niceText = text.textBegin();
 	vector<NiceText>::const_iterator niceTextEnd = text.textEnd();
 
-	int u=0;
+	int counterSubStrings=0;
 	ostringstream all_text;
 	for(;niceText<niceTextEnd;)
 	{
 		all_text << (*niceText).text();
 		niceText++;
-		u++;
+		counterSubStrings++;
 	}
 
 	niceText = text.textBegin();
@@ -1068,41 +1068,33 @@ MAGICS_NO_EXPORT void PostScriptDriver::renderText(const Text& text) const
 	  unsigned int noTexts = text.size();
 	  for(unsigned int nT=0;nT<noTexts;nT++)  // for all string CO-ORDINATES
 	  {
-		if(niceText == text.textBegin())
-		{
+		 if(niceText == text.textBegin()) // if first text string
+		 {
 			const MFloat x0 = projectX(text[nT].x());
 			const MFloat y0 = projectY(text[nT].y()) + offset;
+			const MFloat angle = 360.-(text.getAngle()*57.29577951);
 
-			if(u>1)
+			*ps <<"gs "<< x0 << " " << y0 << " t ";
+			if(angle != 0.) *ps <<angle<< " ro ";
+
+			if(counterSubStrings>1)
 			{
-				const MFloat an = 360.-(text.getAngle()*57.29577951);
-				if(an==0 || an==360)
-				    *ps <<"gs "<< x0 << " " << y0 << " t ("<< all_text.str() << ") stringwidth pop HA mul VA Height mul moveto "
-				        << "("<<tmp.str()<< ") "<<showCommand<<"\n";
-				else
-				    *ps <<"gs "<< x0 << " " << y0 << " t "<<an<< " ro ("<< all_text.str() << ") stringwidth pop HA mul VA Height mul moveto "
-				        << "("<<tmp.str()<< ") "<<showCommand<<"\n";
+				*ps <<"("<< all_text.str() << ") stringwidth pop HA mul VA Height mul moveto " << "("<<tmp.str()<< ") "<<showCommand<<"\n";
 			}
 			else
 			{
-
-
-				const MFloat an = 360.-(text.getAngle()*57.29577951);
-				if(an==0 || an==360)
-					*ps <<"gs "<< x0 << " " << y0 << " t ("<<tmp.str()<< ") 0 0 "<<textCommand<<"\n";
-				else
-					*ps <<"gs "<< x0 << " " << y0 << " t "<<an<< " ro ("<<tmp.str()<< ") 0 0 "<<textCommand<<"\n";
+				*ps <<"("<<tmp.str()<< ") 0 0 "<<textCommand<<"\n";
 			}
-		}
-		else
-		{
-		*ps << " 0 "<<offset<<" rmoveto\n";
+		 }
+		 else  // all other substrings
+		 {
+			*ps << " 0 "<<offset<<" rmoveto\n";
 			*ps << "("<<tmp.str()<< ") "<<showCommand<<"\n";
-		}
-		count++;
-		if (niceText+1 == text.textEnd()) *ps <<"gr\n";
-	   }
-	   niceText++;
+		 }
+		 count++;
+		 if (niceText+1 == text.textEnd()) *ps <<"gr\n";
+	  }
+	  niceText++;
 	} // endfor all nicetexts
 	ps->precision(ss);
 	currentColour_ = Colour("none");
@@ -1305,7 +1297,7 @@ MAGICS_NO_EXPORT bool PostScriptDriver::renderCellArray(const Image& image) cons
    if(width > 0 && height > 0)
    {
 	const int col_model = getDeviceColourModel();
-	
+
 	const MFloat x0 = projectX(image.getOrigin().x());
 	const MFloat y0 = projectY(image.getOrigin().y()-image.getHeight());
 	const MFloat x1 = projectX(image.getOrigin().x()+image.getWidth());
@@ -1440,7 +1432,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::renderSymbols(const Symbol& symbol) cons
 	else
 	{
       pFile_<< " "<<projectX(symbol[0].x())<<" "<< projectY(symbol[0].y())-convertCM(symbol.getHeight()*.3)<< " t 0.4 0.4 s"<<endl;
-      pFile_<< "gs\n" 
+      pFile_<< "gs\n"
             << "183.473 76.074 m 183.473 63.121 l 146.492 63.121 l 146.492 48.105 l 180.438 48.105 l 180.438 36.094 l 146.492 36.094 l 146.492 18.977 l 184.262 18.977\n"
             << "l 184.262 6.023 l 131.086 6.023 l 131.086 76.074 l P 183.473 76.074 m fill\n"
             << "234.574 57.387 m 233.656 58.859 232.492 60.172 231.141 61.262 c 228.277 63.559 224.711 64.805 221.039 64.793 c 217.973 64.891 214.934 64.199 212.211\n"
@@ -1558,7 +1550,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::closeFile() const
 		}
 	}
 	if(!isPS() && !isEPS() ) remove(fps.c_str());
-	else 
+	else
 	{
 		if(isPS()) printOutputName("PS ps "+fps);
 		else printOutputName("PS eps "+fps);
@@ -1633,7 +1625,7 @@ MAGICS_NO_EXPORT void PostScriptDriver::writePSFileHeader() const
 	else *ps << "/S {gr} def\n"; // define "showpage" empty for EPS files
 
 	//copyMacro(ps,"PostScriptMacro1.ps");
-	*ps << "/m {moveto} def /st {stroke} def /rl {rlineto} def /ro {rotate} def /cp {closepath} def /d { {rmoveto rlineto} repeat stroke} bind def /gr {grestore} def /gs {gsave} def /n { newpath } def\n" 
+	*ps << "/m {moveto} def /st {stroke} def /rl {rlineto} def /ro {rotate} def /cp {closepath} def /d { {rmoveto rlineto} repeat stroke} bind def /gr {grestore} def /gs {gsave} def /n { newpath } def\n"
 	    << "/sa {save} def /lw {setlinewidth } def /ar {arc fill} def /arn {arcn fill} def /l { lineto } bind def /c { curveto } bind def\n"
 	    << "/sd {setdash} def /C { setrgbcolor } def /Y { setcmykcolor } def  /B { moveto rlineto stroke } bind def /BB { moveto lineto stroke } bind def /t { translate } def /s {scale} def /K { /UY exch def /UX exch def /LY exch def \n"
 	    << "/LX exch def gsave newpath LX LY moveto UX LY lineto UX UY lineto LX UY lineto closepath newpath } def /lp { moveto rlineto } bind def /p { moveto {rlineto} repeat stroke} bind def /po { moveto {rlineto} repeat } bind def\n"
diff --git a/src/drivers/QtDriver.cc b/src/drivers/QtDriver.cc
index 10de87a..bb96846 100644
--- a/src/drivers/QtDriver.cc
+++ b/src/drivers/QtDriver.cc
@@ -1567,25 +1567,44 @@ MAGICS_NO_EXPORT void QtDriver::renderImage(const ImportObject& obj) const
 	else if(magCompare(f,"svg")) return; //format = SVG;
 	else return;
 	
-	MFloat width=0;
-	MFloat height=0;
-
-	if(obj.getWidth()==-1 && ( magCompare(f,"gif") || magCompare(f,"png") || magCompare(f,"jpeg")|| magCompare(f,"jpg") ) )
-	{
-		return;
-	}
-	else
-	{
-		width  = obj.getWidth();
-		height = obj.getHeight();
-	}
+    MFloat width  = obj.getWidth(); //cm
+    MFloat height = obj.getHeight(); //cm
 
+    if(width == 0. || height == 0.)
+        return;
+    
 	QImage img(obj.getPath().c_str());
 	if(img.isNull())
 	{
 		return;
 	}
 
+	if(width < 0)
+    {    
+        width=img.width(); //pixels
+        //We need the width in cm
+        MFloat cm0=projectX(obj.getOrigin().x());
+        MFloat cm1=projectX(obj.getOrigin().x()+1.);
+        MFloat cm=fabs(cm1-cm0);
+        if(cm > 0.)
+            width/=cm;
+        else
+            return;
+    }    
+        
+    if(height < 0)
+    {
+        height=img.height(); //pixels
+        //We need the height in cm
+        MFloat cm0=projectY(obj.getOrigin().y());
+        MFloat cm1=projectY(obj.getOrigin().y()+1.);
+        MFloat cm=fabs(cm1-cm0);
+        if(cm > 0.)
+            height/=cm;
+        else
+            return;
+    }   
+    
 	MgQPixmapItem *item=new MgQPixmapItem(QPixmap::fromImage(img.mirrored(false,true)));
 	
 	MFloat x0=projectX(obj.getOrigin().x());
diff --git a/src/drivers/SVGDriver.cc b/src/drivers/SVGDriver.cc
index 00b164b..317196a 100644
--- a/src/drivers/SVGDriver.cc
+++ b/src/drivers/SVGDriver.cc
@@ -319,7 +319,7 @@ MAGICS_NO_EXPORT void SVGDriver::project(const magics::Layout& layout) const
 	dimensionStack_.push(dimensionX_);
 	dimensionStack_.push(dimensionY_);
 	const MFloat oldHeight = dimensionY_;
-	const MFloat oldWidth  = dimensionX_;
+	// const MFloat oldWidth  = dimensionX_;
 	scalesX_.push(coordRatioX_);
 	scalesY_.push(coordRatioY_);
 
@@ -983,7 +983,7 @@ MAGICS_NO_EXPORT void SVGDriver::renderText(const Text& text) const
   else if( horizontalAlign==MRIGHT ) justification = "end";
 
   VerticalAlign verticalAlign = text.getVerticalAlign();
-  double vertical = 0.;
+  //double vertical = 0.;
 
   unsigned int noTexts = text.size();
   vector<NiceText>::const_iterator niceTextEnd = text.textEnd();
@@ -1092,7 +1092,7 @@ MAGICS_NO_EXPORT void SVGDriver::circle(const MFloat x, const MFloat y, const MF
 		}
 		else
 		{
-		 const short  i   = (s<4) ? 1 : 0;
+		 //const short  i   = (s<4) ? 1 : 0;
 		 //const double rad = s*0.7853981634;
 
 		 if(s==2)      pFile_ << "<path d=\"M"<<cx<<" "<<cy-r<<" v"<<r<<" h"<<r<<" a"<<r<<","<<r<<" 0 0 0 "<< -r<<","<<-r<<"\" ";
diff --git a/src/drivers/libimagequant/CHANGELOG b/src/drivers/libimagequant/CHANGELOG
deleted file mode 100644
index 4714caa..0000000
--- a/src/drivers/libimagequant/CHANGELOG
+++ /dev/null
@@ -1,130 +0,0 @@
-version 2.5
------------
- - replaced color search algorithm with vantage point tree, which is much faster and more reliable
- - deprecated IE6 workaround
-
-version 2.4
------------
- - fixed remapping of bright colors when dithering
- - added libimagequant API to add fixed preset colors to the palette
-
-version 2.3
------------
- - added ./configure script for better support of Intel C compiler and dependencies [thanks to pdknsk]
- - tweaked quality metric to better estimate quality of images with large solid backgrounds [thanks to Rolf Timmermans]
- - atomic file saves and fixed --skip-if-larger
- - avoid applying quality setting to images that use palette already
- - preserving standard PNG chunks (requires libpng 1.6)
- - deprecated libpng 1.2 support
-
-version 2.2
------------
- - preserving of unknown PNG chunks (enables optimized Android 9-patch images)
- - improved color profile support: cHRM & gAMA as alternative to ICC profiles, OpenMP acceleration
- - improved support for Intel C Compiler, speedup in 32-bit GCC, and some workarounds for Visual Studio's incomplete C support
-
-version 2.1
------------
- - option to save files only if they're compressed better than the original
- - option to generate posterized output (for use with 16-bit textures)
- - support for ICC profiles via Little CMS library
-
-version 2.0
------------
- - refactored codebase into pngquant and standalone libimagequant
- - reduced memory usage by further 30% (and more for very large images)
- - less precise remapping improving speed by 25% in higher speed settings
- - --output option for writing converted file under the given path
- - light dithering with --floyd=0.5
- - fixed regression in dithering of alpha channel
-
-version 1.8
------------
- - min/max quality option (number of colors is automatically adjusted for desired quality level)
- - switched option parsing to getopt_long (syntax such as -s1 and --ext=ext is supported)
- - significantly improved performance thanks to custom partial sorting
- - optional Cocoa (Mac OS X) image reader for color profile support
- - reduced memory usage by 20%
- - remapping improved for very low number of colors
-
-version 1.7
------------
- - new, accurate RGBA color similarity algorithm
- - change of optional SSE3 code to SSE2 that is always enabled on x86-64
- - optional OpenMP-based parallelisation of remapping
- - changed long options to use double hyphen (-force to --force) [thanks to Jari Aalto]
-
-version 1.6
------------
- - novel dithering algorithm that doesn't add noise unless necessary
- - perceptual weighting of colors taking into account edges and noise
- - much faster remapping
- - improved portability, makefiles and man page
-
-version 1.5
------------
- - palettes postprocessed with Voronoi iteration
- - better RGBA color similarity algorithm and Floyd-Steinberg remapping
- - SSE optimisations
-
-version 1.4
------------
- - median cut is applied many times in a feedback loop
- - speed/quality trade-off option
- - faster remap of transparent areas
-
-version 1.3
------------
- - significant changes to the algorithm: use of variance
-   to find largest dimensioin and to split most varying boxes
- - use of premultiplied alpha for color blending
- - conversion of output to gamma 2.2
-
-version 1.2
------------
- - color computation done in floating point
- - gamma correction applied
- - dropped support for very old systems & compilers
-
-version 1.1
------------
- - alpha-sensitive color reduction and dithering
- - support -- and - arguments in command line
- - number of colors optional (defaults to 256)
- - increased maximum number of colors in histogram
-
-version 1.0
------------
- - cleaned up Makefile.unx (better gcc optimizations, "clean" target)
- - recompiled binaries with zlib 1.1.4
-
-version 0.95
-------------
- - fixed Win32 filter bug (binary mode for stdin/stdout)
- - fixed cosmetic "choosing colors" verbosity buglet
- - fixed palette-size bug when number of colors in image < number requested
- - fixed sample-depth bug (png_set_packing() not retroactively smart)
-
-version 0.91
-------------
- - fixed some verbose/non-verbose oopers
- - fixed Win32 (MSVC) portability issues (getpid(), random(), srandom())
- - added Makefile.w32 for MSVC (tested with 5.0)
-
-version 0.90
-------------
- - added support for multiple files on command line
- - changed stdin support to write PNG stream to stdout (not "stdin-fs8.png")
-
-version 0.75
-------------
- - added support for any type of input file [Glenn Randers-Pehrson]
- - fixed palette-(re)scaling bug
- - added -verbose and -quiet options (default now is -quiet)
- - added palette-remapping to minimize size of tRNS chunk
- - made Floyd-Steinberg dithering default
- - changed output naming scheme to -fs8.png and -or8.png (FS or ordered dither)
-
-version 0.70
-------------
- - first public release
diff --git a/src/drivers/libimagequant/COPYRIGHT b/src/drivers/libimagequant/COPYRIGHT
deleted file mode 100644
index 20ac3db..0000000
--- a/src/drivers/libimagequant/COPYRIGHT
+++ /dev/null
@@ -1,36 +0,0 @@
-© 1997-2002 by Greg Roelofs; based on an idea by Stefan Schneider.
-© 2009-2015 by Kornel Lesiński.
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-© 1989, 1991 by Jef Poskanzer.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted, provided
-that the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.  This software is provided "as is" without express or
-implied warranty.
diff --git a/src/drivers/libimagequant/MANUAL.md b/src/drivers/libimagequant/MANUAL.md
deleted file mode 100644
index 56c6ddb..0000000
--- a/src/drivers/libimagequant/MANUAL.md
+++ /dev/null
@@ -1,511 +0,0 @@
-# libimagequant—Image Quantization Library
-
-Small, portable C library for high-quality conversion of RGBA images to 8-bit indexed-color (palette) images.
-It's powering [pngquant2](http://pngquant.org).
-
-## License
-
-[BSD](https://raw.github.com/pornel/pngquant/master/lib/COPYRIGHT).
-It can be linked with both free and closed-source software.
-
-## Download
-
-The [library](http://pngquant.org/lib) is currently a part of the [pngquant2 project](https://github.com/pornel/pngquant/tree/master/lib).
-
-Files needed for the library are only in the `lib/` directory inside the repository (and you can ignore the rest).
-
-## Compiling and Linking
-
-The library can be linked with ANSI C, C++ and [Rust](https://crates.io/crates/imagequant/) programs. It has no external dependencies.
-
-To build on Unix-like systems run:
-
-    make -C lib
-
-it will create `lib/libimagequant.a` which you can link with your program.
-
-    gcc yourprogram.c /path/to/lib/libimagequant.a
-
-On BSD, use `gmake` (GNU make) rather than the native `make`.
-
-Alternatively you can compile the library with your program simply by including all `.c` files (and define `NDEBUG` to get a fast version):
-
-    gcc -std=c99 -O3 -DNDEBUG lib/*.c yourprogram.c
-
-In [Rust](https://github.com/pornel/libimagequant-rust),
-if using Cargo, add `imagequant` to dependencies.
-
-### Compiling on Windows/Visual Studio
-
-The library can be compiled with any C compiler that has at least basic support for C99 (GCC, clang, ICC, C++ Builder, even Tiny C Compiler), but Visual Studio 2012 and older are not up to date with the 1999 C standard. There are 2 options for using `libimagequant` on Windows:
-
- * Use Visual Studio **2013** (MSVC 18) and an [MSVC-compatible branch of the library](https://github.com/pornel/pngquant/tree/msvc/lib)
- * Or use GCC from [MinGW](http://www.mingw.org). Use GCC to build `libimagequant.a` (using the instructions above for Unix) and add it along with `libgcc.a` (shipped with the MinGW compiler) to your VC project.
-
-## Overview
-
-The basic flow is:
-
-1. Create attributes object and configure the library.
-2. Create image object from RGBA bitmap or data source.
-3. Perform quantization (generate palette).
-4. Store remapped image and final palette.
-5. Free memory.
-
-Please note that libimagequant only handles raw uncompressed bitmaps in memory and is completely independent of any file format.
-
-<p>
-
-    #include "lib/libimagequant.h"
-
-    liq_attr *attr = liq_attr_create();
-    liq_image *image = liq_image_create_rgba(attr, bitmap_rgba, width, height, 0);
-    liq_result *res = liq_quantize_image(attr, image);
-
-    liq_write_remapped_image(res, image, bitmap_8bpp, bitmap_size);
-    const liq_palette *pal = liq_get_palette(res);
-
-    // save image and palette here
-
-    liq_attr_destroy(attr);
-    liq_image_destroy(image);
-    liq_result_destroy(res);
-
-Functions returning `liq_error` return `LIQ_OK` (`0`) on success and non-zero on error.
-
-It's safe to pass `NULL` to any function accepting `liq_attr`, `liq_image`, `liq_result` (in that case the error code `LIQ_INVALID_POINTER` will be returned). These objects can be reused multiple times.
-
-There are 3 ways to create image object for quantization:
-
-  * `liq_image_create_rgba()` for simple, contiguous RGBA bitmaps (width×height×4 bytes large array).
-  * `liq_image_create_rgba_rows()` for non-contiguous RGBA bitmaps (that have padding between rows or reverse order, e.g. BMP).
-  * `liq_image_create_custom()` for RGB, ABGR, YUV and all other formats that can be converted on-the-fly to RGBA (you have to supply the conversion function).
-
-Note that "image" here means raw uncompressed pixels. If you have a compressed image file, such as PNG, you must use another library (e.g. libpng or lodepng) to decode it first.
-
-## Functions
-
-----
-
-    liq_attr* liq_attr_create(void);
-
-Returns object that will hold initial settings (attributes) for the library. The object should be freed using `liq_attr_destroy()` after it's no longer needed.
-
-Returns `NULL` in the unlikely case that the library cannot run on the current machine (e.g. the library has been compiled for SSE-capable x86 CPU and run on VIA C3 CPU).
-
-----
-
-    liq_error liq_set_max_colors(liq_attr* attr, int colors);
-
-Specifies maximum number of colors to use. The default is 256. Instead of setting a fixed limit it's better to use `liq_set_quality()`.
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if number of colors is outside the range 2-256.
-
-----
-
-    int liq_get_max_colors(liq_attr* attr);
-
-Returns the value set by `liq_set_max_colors()`.
-
-----
-
-    liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum);
-
-Quality is in range `0` (worst) to `100` (best) and values are analoguous to JPEG quality (i.e. `80` is usually good enough).
-
-Quantization will attempt to use the lowest number of colors needed to achieve `maximum` quality. `maximum` value of `100` is the default and means conversion as good as possible.
-
-If it's not possible to convert the image with at least `minimum` quality (i.e. 256 colors is not enough to meet the minimum quality), then `liq_quantize_image()` will fail. The default minumum is `0` (proceeds regardless of quality).
-
-Quality measures how well the generated palette fits image given to `liq_quantize_image()`. If a different image is remapped with `liq_write_remapped_image()` then actual quality may be different.
-
-Regardless of the quality settings the number of colors won't exceed the maximum (see `liq_set_max_colors()`).
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if target is lower than minimum or any of them is outside the 0-100 range.
-Returns `LIQ_INVALID_POINTER` if `attr` appears to be invalid.
-
-    liq_attr *attr = liq_attr_create();
-    liq_set_quality(attr, 50, 80); // use quality 80 if possible. Give up if quality drops below 50.
-
-----
-
-    int liq_get_min_quality(liq_attr* attr);
-
-Returns the lower bound set by `liq_set_quality()`.
-
-----
-
-    int liq_get_max_quality(liq_attr* attr);
-
-Returns the upper bound set by `liq_set_quality()`.
-
-----
-
-    liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma);
-
-Creates image object that represents a bitmap later used for quantization and remapping. The bitmap must be contiguous run of RGBA pixels (alpha is the last component, 0 = transparent, 255 = opaque).
-
-The bitmap must not be modified or freed until this object is freed with `liq_image_destroy()`. See also `liq_image_set_memory_ownership()`.
-
-`width` and `height` are dimensions in pixels. An image 10x10 pixel large will need 400-byte bitmap.
-
-`gamma` can be `0` for images with the typical 1/2.2 [gamma](http://en.wikipedia.org/wiki/Gamma_correction).
-Otherwise `gamma` must be > 0 and < 1, e.g. `0.45455` (1/2.2) or `0.55555` (1/1.8). Generated palette will use the same gamma unless `liq_set_output_gamma()` is used. If `liq_set_output_gamma` is not used, then it only affects whether brighter or darker areas of the image will get more palette colors allocated.
-
-Returns `NULL` on failure, e.g. if `bitmap` is `NULL` or `width`/`height` is <= 0.
-
-----
-
-    liq_image *liq_image_create_rgba_rows(liq_attr *attr, void* rows[], int width, int height, double gamma);
-
-Same as `liq_image_create_rgba()`, but takes array of pointers to rows in the bitmap. This allows defining bitmaps with reversed rows (like in BMP), "stride" different than width or using only fragment of a larger bitmap, etc.
-
-`rows` array must have at least `height` elements and each row must be at least `width` RGBA pixels wide.
-
-    unsigned char *bitmap = …;
-    void *rows = malloc(height * sizeof(void*));
-    int bytes_per_row = width * 4 + padding; // stride
-    for(int i=0; i < height; i++) {
-        rows[i] = bitmap + i * bytes_per_row;
-    }
-    liq_image *img = liq_image_create_rgba_rows(attr, rows, width, height, 0);
-    // …
-    liq_image_destroy(img);
-    free(rows);
-
-The row pointers and bitmap must not be modified or freed until this object is freed with `liq_image_destroy()` (you can change that with `liq_image_set_memory_ownership()`).
-
-See also `liq_image_create_rgba()` and `liq_image_create_custom()`.
-
-----
-
-    liq_result *liq_quantize_image(liq_attr *attr, liq_image *input_image);
-
-Performs quantization (palette generation) based on settings in `attr` and pixels of the image.
-
-Returns `NULL` if quantization fails, e.g. due to limit set in `liq_set_quality()`.
-
-See `liq_write_remapped_image()`.
-
-----
-
-    liq_error liq_set_dithering_level(liq_result *res, float dither_level);
-
-Enables/disables dithering in `liq_write_remapped_image()`. Dithering level must be between `0` and `1` (inclusive). Dithering level `0` enables fast non-dithered remapping. Otherwise a variation of Floyd-Steinberg error diffusion is used.
-
-Precision of the dithering algorithm depends on the speed setting, see `liq_set_speed()`.
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if the dithering level is outside the 0-1 range.
-
-----
-
-    liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size);
-
-Remaps the image to palette and writes its pixels to the given buffer, 1 pixel per byte.
-
-The buffer must be large enough to fit the entire image, i.e. width×height bytes large. For safety, pass the size of the buffer as `buffer_size`.
-
-For best performance call `liq_get_palette()` *after* this function, as palette is improved during remapping.
-
-Returns `LIQ_BUFFER_TOO_SMALL` if given size of the buffer is not enough to fit the entire image.
-
-    int buffer_size = width*height;
-    char *buffer = malloc(buffer_size);
-    if (LIQ_OK == liq_write_remapped_image(result, input_image, buffer, buffer_size)) {
-        liq_palette *pal = liq_get_palette(result);
-        // save image
-    }
-
-See `liq_get_palette()`.
-
-The buffer is assumed to be contiguous, with rows ordered from top to bottom, and no gaps between rows. If you need to write rows with padding or upside-down order, then use `liq_write_remapped_image_rows()`.
-
-Please note that it only writes raw uncompressed pixels to memory. It does not perform any PNG compression. If you'd like to create a PNG file then you need to pass the raw pixel data to another library, e.g. libpng or lodepng. See `rwpng.c` in `pngquant` project for an example how to do that.
-
-----
-
-    const liq_palette *liq_get_palette(liq_result *result);
-
-Returns pointer to palette optimized for image that has been quantized or remapped (final refinements are applied to the palette during remapping).
-
-It's valid to call this method before remapping, if you don't plan to remap any images or want to use same palette for multiple images.
-
-`liq_palette->count` contains number of colors (up to 256), `liq_palette->entries[n]` contains RGBA value for nth palette color.
-
-The palette is **temporary and read-only**. You must copy the palette elsewhere *before* calling `liq_result_destroy()`.
-
-Returns `NULL` on error.
-
-----
-
-    void liq_attr_destroy(liq_attr *);
-    void liq_image_destroy(liq_image *);
-    void liq_result_destroy(liq_result *);
-
-Releases memory owned by the given object. Object must not be used any more after it has been freed.
-
-Freeing `liq_result` also frees any `liq_palette` obtained from it.
-
-## Advanced Functions
-
-----
-
-    liq_error liq_set_speed(liq_attr* attr, int speed);
-
-Higher speed levels disable expensive algorithms and reduce quantization precision. The default speed is `3`. Speed `1` gives marginally better quality at significant CPU cost. Speed `10` has usually 5% lower quality, but is 8 times faster than the default.
-
-High speeds combined with `liq_set_quality()` will use more colors than necessary and will be less likely to meet minimum required quality.
-
-<table><caption>Features dependent on speed</caption>
-<tr><th>Noise-sensitive dithering</th><td>speed 1 to 5</td></tr>
-<tr><th>Forced posterization</th><td>8-10 or if image has more than million colors</td></tr>
-<tr><th>Quantization error known</th><td>1-7 or if minimum quality is set</td></tr>
-<tr><th>Additional quantization techniques</th><td>1-6</td></tr>
-</table>
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if the speed is outside the 1-10 range.
-
-----
-
-    int liq_get_speed(liq_attr* attr);
-
-Returns the value set by `liq_set_speed()`.
-
-----
-
-    liq_error liq_set_min_opacity(liq_attr* attr, int min);
-
-Alpha values higher than this will be rounded to opaque. This is a workaround for Internet Explorer 6, but because this browser is not used any more, this option is deprecated and will be removed. The default is `255` (no change).
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if the value is outside the 0-255 range.
-
-----
-
-    int liq_get_min_opacity(liq_attr* attr);
-
-Returns the value set by `liq_set_min_opacity()`.
-
-----
-
-    liq_set_min_posterization(liq_attr* attr, int bits);
-
-Ignores given number of least significant bits in all channels, posterizing image to `2^bits` levels. `0` gives full quality. Use `2` for VGA or 16-bit RGB565 displays, `4` if image is going to be output on a RGB444/RGBA4444 display (e.g. low-quality textures on Android).
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if the value is outside the 0-4 range.
-
-----
-
-    int liq_get_min_posterization(liq_attr* attr);
-
-Returns the value set by `liq_set_min_posterization()`.
-
-----
-
-    liq_set_last_index_transparent(liq_attr* attr, int is_last);
-
-`0` (default) makes alpha colors sorted before opaque colors. Non-`0` mixes colors together except completely transparent color, which is moved to the end of the palette. This is a workaround for programs that blindly assume the last palette entry is transparent.
-
-----
-
-    liq_image *liq_image_create_custom(liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void *user_info, int width, int height, double gamma);
-
-<p>
-
-    void image_get_rgba_row_callback(liq_color row_out[], int row_index, int width, void *user_info) {
-        for(int column_index=0; column_index < width; column_index++) {
-            row_out[column_index] = /* generate pixel at (row_index, column_index) */;
-        }
-    }
-
-Creates image object that will use callback to read image data. This allows on-the-fly conversion of images that are not in the RGBA color space.
-
-`user_info` value will be passed to the callback. It may be useful for storing pointer to program's internal representation of the image.
-
-The callback must read/generate `row_index`-th row and write its RGBA pixels to the `row_out` array. Row `width` is given for convenience and will always equal to image width.
-
-The callback will be called multiple times for each row. Quantization and remapping require at least two full passes over image data, so caching of callback's work makes no sense — in such case it's better to convert entire image and use `liq_image_create_rgba()` instead.
-
-To use RGB image:
-
-    void rgb_to_rgba_callback(liq_color row_out[], int row_index, int width, void *user_info) {
-        unsigned char *rgb_row = ((unsigned char *)user_info) + 3*width*row_index;
-
-        for(int i=0; i < width; i++) {
-            row_out[i].r = rgb_row[i*3];
-            row_out[i].g = rgb_row[i*3+1];
-            row_out[i].b = rgb_row[i*3+2];
-            row_out[i].a = 255;
-        }
-    }
-    liq_image *img = liq_image_create_custom(attr, rgb_to_rgba_callback, rgb_bitmap, width, height, 0);
-
-The library doesn't support RGB bitmaps "natively", because supporting only single format allows compiler to inline more code, 4-byte pixel alignment is faster, and SSE instructions operate on 4 values at once, so alpha support is almost free.
-
-----
-
-    liq_error liq_image_set_memory_ownership(liq_image *image, int ownership_flags);
-
-Passes ownership of bitmap and/or rows memory to the `liq_image` object, so you don't have to free it yourself. Memory owned by the object will be freed at its discretion with `free` function specified in `liq_attr_create_with_allocator()` (by default it's stdlib's `free()`).
-
-* `LIQ_OWN_PIXELS` makes bitmap owned by the object. The bitmap will be freed automatically at any point when it's no longer needed. If you set this flag you must **not** free the bitmap yourself. If the image has been created with `liq_image_create_rgba_rows()` then the bitmap address is assumed to be the lowest address of any row.
-
-* `LIQ_OWN_ROWS` makes array of row pointers (but not bitmap pointed by these rows) owned by the object. Rows will be freed when object is deallocated. If you set this flag you must **not** free the rows array yourself. This flag is valid only if the object has been created with `liq_image_create_rgba_rows()`.
-
-These flags can be combined with binary *or*, i.e. `LIQ_OWN_PIXELS | LIQ_OWN_ROWS`.
-
-This function must not be used if the image has been created with `liq_image_create_custom()`.
-
-Returns `LIQ_VALUE_OUT_OF_RANGE` if invalid flags are specified or image is not backed by a bitmap.
-
-----
-
-    liq_error liq_write_remapped_image_rows(liq_result *result, liq_image *input_image, unsigned char **row_pointers);
-
-Similar to `liq_write_remapped_image()`. Writes remapped image, at 1 byte per pixel, to each row pointed by `row_pointers` array. The array must have at least as many elements as height of the image, and each row must have at least as many bytes as width of the image. Rows must not overlap.
-
-For best performance call `liq_get_palette()` *after* this function, as remapping may change the palette.
-
-Returns `LIQ_INVALID_POINTER` if `result` or `input_image` is `NULL`.
-
-----
-
-    double liq_get_quantization_error(liq_result *result);
-
-Returns mean square error of quantization (square of difference between pixel values in the source image and its remapped version). Alpha channel, gamma correction and approximate importance of pixels is taken into account, so the result isn't exactly the mean square error of all channels.
-
-For most images MSE 1-5 is excellent. 7-10 is OK. 20-30 will have noticeable errors. 100 is awful.
-
-This function may return `-1` if the value is not available (this happens when a high speed has been requested, the image hasn't been remapped yet, and quality limit hasn't been set, see `liq_set_speed()` and `liq_set_quality()`). The value is not updated when multiple images are remapped, it applies only to the image used in `liq_quantize_image()` or the first image that has been remapped. See `liq_get_remapping_error()`.
-
-----
-
-    double liq_get_remapping_error(liq_result *result);
-
-Returns mean square error of last remapping done (square of difference between pixel values in the remapped image and its remapped version). Alpha channel and gamma correction are taken into account, so the result isn't exactly the mean square error of all channels.
-
-This function may return `-1` if the value is not available (this happens when a high speed has been requested or the image hasn't been remapped yet).
-
-----
-
-    double liq_get_quantization_quality(liq_result *result);
-
-Analoguous to `liq_get_quantization_error()`, but returns quantization error as quality value in the same 0-100 range that is used by `liq_set_quality()`.
-
-It may return `-1` if the value is not available (see note in `liq_get_quantization_error()`).
-
-This function can be used to add upper limit to quality options presented to the user, e.g.
-
-    liq_attr *attr = liq_attr_create();
-    liq_image *img = liq_image_create_rgba(…);
-    liq_result *res = liq_quantize_image(attr, img);
-    int max_attainable_quality = liq_get_quantization_quality(res);
-    printf("Please select quality between 0 and %d: ", max_attainable_quality);
-    int user_selected_quality = prompt();
-    if (user_selected_quality < max_attainable_quality) {
-        liq_set_quality(user_selected_quality, 0);
-        liq_result_destroy(res);
-        res = liq_quantize_image(attr, img);
-    }
-    liq_write_remapped_image(…);
-
-----
-
-    double liq_get_remapping_quality(liq_result *result);
-
-Analoguous to `liq_get_remapping_error()`, but returns quantization error as quality value in the same 0-100 range that is used by `liq_set_quality()`.
-
-----
-
-    void liq_set_log_callback(liq_attr*, liq_log_callback_function*, void *user_info);
-
-<p>
-
-    void log_callback_function(const liq_attr*, const char *message, void *user_info) {}
-
-----
-
-    void liq_set_log_flush_callback(liq_attr*, liq_log_flush_callback_function*, void *user_info);
-<p>
-
-    void log_flush_callback_function(const liq_attr*, void *user_info) {}
-
-Sets up callback function to be called when the library reports work progress or errors. The callback must not call any library functions.
-
-`user_info` value will be passed to the callback.
-
-`NULL` callback clears the current callback.
-
-In the log callback the `message` is a zero-terminated string containing informative message to output. It is valid only until the callback returns.
-
-`liq_set_log_flush_callback()` sets up callback function that will be called after the last log callback, which can be used to flush buffers and free resources used by the log callback.
-
-----
-
-    liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
-
-Same as `liq_attr_create`, but uses given `malloc` and `free` replacements to allocate all memory used by the library.
-
-The `malloc` function must return 16-byte aligned memory on x86 (and on other architectures memory aligned for `double` and pointers). Conversely, if your stdlib's `malloc` doesn't return appropriately aligned memory, you should use this function to provide aligned replacements.
-
-----
-
-    liq_attr* liq_attr_copy(liq_attr *orig);
-
-Creates an independent copy of `liq_attr`. The copy should also be freed using `liq_attr_destroy()`.
-
----
-
-    liq_error liq_set_output_gamma(liq_result* res, double gamma);
-
-Sets gamma correction for generated palette and remapped image. Must be > 0 and < 1, e.g. `0.45455` for gamma 1/2.2 in PNG images. By default output gamma is same as gamma of the input image.
-
-----
-
-    int liq_image_get_width(const liq_image *img);
-    int liq_image_get_height(const liq_image *img);
-    double liq_get_output_gamma(const liq_result *result);
-
-Getters for `width`, `height` and `gamma` of the input image.
-
-If the input is invalid, these all return -1.
-
----
-
-    liq_error liq_image_add_fixed_color(liq_image* img, liq_color color);
-
-Reserves a color in the output palette created from this image. It behaves as if the given color was used in the image and was very important.
-
-RGB values of `liq_color` are assumed to have the same gamma as the image.
-
-It must be called before the image is quantized.
-
-Returns error if more than 256 colors are added. If image is quantized to fewer colors than the number of fixed colors added, then excess fixed colors will be ignored.
-
----
-
-    int liq_version();
-
-Returns version of the library as an integer. Same as `LIQ_VERSION`. Human-readable version is defined as `LIQ_VERSION_STRING`.
-
-## Multithreading
-
-The library is stateless and doesn't use any global or thread-local storage. It doesn't use any locks.
-
-* Different threads can perform unrelated quantizations/remappings at the same time (e.g. each thread working on a different image).
-* The same `liq_attr`, `liq_result`, etc. can be accessed from different threads, but not at the same time (e.g. you can create `liq_attr` in one thread and free it in another).
-
-The library needs to sort unique colors present in the image. Although the sorting algorithm does few things to make stack usage minimal in typical cases, there is no guarantee against extremely degenerate cases, so threads should have automatically growing stack.
-
-### OpenMP
-
-The library will parallelize some operations if compiled with OpenMP.
-
-You must not increase number of maximum threads after `liq_image` has been created, as it allocates some per-thread buffers.
-
-Callback of `liq_image_create_custom()` may be called from different threads at the same time.
-
-## Acknowledgements
-
-Thanks to Irfan Skiljan for helping test the first version of the library.
-
-The library is developed by [Kornel Lesiński](mailto:%20kornel at pngquant.org).
diff --git a/src/drivers/libimagequant/Makefile b/src/drivers/libimagequant/Makefile
deleted file mode 100644
index e4c5693..0000000
--- a/src/drivers/libimagequant/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
--include config.mk
-
-STATICLIB=libimagequant.a
-SHAREDLIB=libimagequant.so.0
-
-DLL=libimagequant.dll
-DLLIMP=libimagequant_dll.a
-DLLDEF=libimagequant_dll.def
-
-OBJS = pam.o mediancut.o blur.o mempool.o viter.o nearest.o libimagequant.o
-SHAREDOBJS = $(subst .o,.lo,$(OBJS))
-
-DISTFILES = $(OBJS:.o=.c) *.h MANUAL.md COPYRIGHT Makefile configure
-TARNAME = libimagequant-$(VERSION)
-TARFILE = $(TARNAME)-src.tar.bz2
-
-all: static shared
-
-static: $(STATICLIB)
-
-shared: $(SHAREDLIB)
-
-dll:
-	$(MAKE) CFLAGSADD="-DLIQ_EXPORT='__declspec(dllexport)'" $(DLL)
-
-
-$(DLL) $(DLLIMP): $(OBJS)
-	$(CC) -fPIC -shared -o $(DLL) $^ $(LDFLAGS) -Wl,--out-implib,$(DLLIMP),--output-def,$(DLLDEF)
-
-$(STATICLIB): $(OBJS)
-	$(AR) $(ARFLAGS) $@ $^
-
-$(SHAREDOBJS):
-	$(CC) -fPIC $(CFLAGS) -c $(@:.lo=.c) -o $@
-
-$(SHAREDLIB): $(SHAREDOBJS)
-	$(CC) -shared -o $@ $^ $(LDFLAGS)
-
-$(OBJS): $(wildcard *.h) config.mk
-
-dist: $(TARFILE)
-
-$(TARFILE): $(DISTFILES)
-	rm -rf $(TARFILE) $(TARNAME)
-	mkdir $(TARNAME)
-	cp $(DISTFILES) $(TARNAME)
-	tar -cjf $(TARFILE) --numeric-owner --exclude='._*' $(TARNAME)
-	rm -rf $(TARNAME)
-	-shasum $(TARFILE)
-
-clean:
-	rm -f $(OBJS) $(SHAREDOBJS) $(SHAREDLIB) $(STATICLIB) $(TARFILE) $(DLL) $(DLLIMP) $(DLLDEF)
-
-distclean: clean
-	rm -f config.mk
-
-config.mk:
-ifeq ($(filter %clean %distclean, $(MAKECMDGOALS)), )
-	./configure
-endif
-
-.PHONY: all static shared clean dist distclean dll
-.DELETE_ON_ERROR:
diff --git a/src/drivers/libimagequant/blur.c b/src/drivers/libimagequant/blur.c
deleted file mode 100644
index 2e50d23..0000000
--- a/src/drivers/libimagequant/blur.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-** © 2011-2015 by Kornel Lesiński.
-** All rights reserved.
-** See COPYRIGHT file for full license.
-*/
-
-#include "libimagequant.h"
-#include "pam.h"
-#include "blur.h"
-
-/*
- Blurs image horizontally (width 2*size+1) and writes it transposed to dst (called twice gives 2d blur)
- */
-static void transposing_1d_blur(unsigned char *restrict src, unsigned char *restrict dst, unsigned int width, unsigned int height, const unsigned int size)
-{
-    assert(size > 0);
-
-    for(unsigned int j=0; j < height; j++) {
-        unsigned char *restrict row = src + j*width;
-
-        // accumulate sum for pixels outside line
-        unsigned int sum;
-        sum = row[0]*size;
-        for(unsigned int i=0; i < size; i++) {
-            sum += row[i];
-        }
-
-        // blur with left side outside line
-        for(unsigned int i=0; i < size; i++) {
-            sum -= row[0];
-            sum += row[i+size];
-
-            dst[i*height + j] = sum / (size*2);
-        }
-
-        for(unsigned int i=size; i < width-size; i++) {
-            sum -= row[i-size];
-            sum += row[i+size];
-
-            dst[i*height + j] = sum / (size*2);
-        }
-
-        // blur with right side outside line
-        for(unsigned int i=width-size; i < width; i++) {
-            sum -= row[i-size];
-            sum += row[width-1];
-
-            dst[i*height + j] = sum / (size*2);
-        }
-    }
-}
-
-/**
- * Picks maximum of neighboring pixels (blur + lighten)
- */
-LIQ_PRIVATE void liq_max3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height)
-{
-    for(unsigned int j=0; j < height; j++) {
-        const unsigned char *row = src + j*width,
-        *prevrow = src + (j > 1 ? j-1 : 0)*width,
-        *nextrow = src + MIN(height-1,j+1)*width;
-
-        unsigned char prev,curr=row[0],next=row[0];
-
-        for(unsigned int i=0; i < width-1; i++) {
-            prev=curr;
-            curr=next;
-            next=row[i+1];
-
-            unsigned char t1 = MAX(prev,next);
-            unsigned char t2 = MAX(nextrow[i],prevrow[i]);
-            *dst++ = MAX(curr,MAX(t1,t2));
-        }
-        unsigned char t1 = MAX(curr,next);
-        unsigned char t2 = MAX(nextrow[width-1],prevrow[width-1]);
-        *dst++ = MAX(t1,t2);
-    }
-}
-
-/**
- * Picks minimum of neighboring pixels (blur + darken)
- */
-LIQ_PRIVATE void liq_min3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height)
-{
-    for(unsigned int j=0; j < height; j++) {
-        const unsigned char *row = src + j*width,
-        *prevrow = src + (j > 1 ? j-1 : 0)*width,
-        *nextrow = src + MIN(height-1,j+1)*width;
-
-        unsigned char prev,curr=row[0],next=row[0];
-
-        for(unsigned int i=0; i < width-1; i++) {
-            prev=curr;
-            curr=next;
-            next=row[i+1];
-
-            unsigned char t1 = MIN(prev,next);
-            unsigned char t2 = MIN(nextrow[i],prevrow[i]);
-            *dst++ = MIN(curr,MIN(t1,t2));
-        }
-        unsigned char t1 = MIN(curr,next);
-        unsigned char t2 = MIN(nextrow[width-1],prevrow[width-1]);
-        *dst++ = MIN(t1,t2);
-    }
-}
-
-/*
- Filters src image and saves it to dst, overwriting tmp in the process.
- Image must be width*height pixels high. Size controls radius of box blur.
- */
-LIQ_PRIVATE void liq_blur(unsigned char *src, unsigned char *tmp, unsigned char *dst, unsigned int width, unsigned int height, unsigned int size)
-{
-    assert(size > 0);
-    if (width < 2*size+1 || height < 2*size+1) {
-        return;
-    }
-    transposing_1d_blur(src, tmp, width, height, size);
-    transposing_1d_blur(tmp, dst, height, width, size);
-}
diff --git a/src/drivers/libimagequant/blur.h b/src/drivers/libimagequant/blur.h
deleted file mode 100644
index 06ae8cb..0000000
--- a/src/drivers/libimagequant/blur.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-LIQ_PRIVATE void liq_blur(unsigned char *src, unsigned char *tmp, unsigned char *dst, unsigned int width, unsigned int height, unsigned int size);
-LIQ_PRIVATE void liq_max3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height);
-LIQ_PRIVATE void liq_min3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height);
diff --git a/src/drivers/libimagequant/configure b/src/drivers/libimagequant/configure
deleted file mode 100755
index 08476ff..0000000
--- a/src/drivers/libimagequant/configure
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/env bash
-
-CONFIG="config.mk"
-PREFIX="/usr/local"
-VERSION=$(grep LIQ_VERSION_STRING libimagequant.h | grep -Eo "2\.[0-9.]+")
-
-DEBUG=
-SSE=auto
-OPENMP=
-EXTRA_CFLAGS=
-EXTRA_LDFLAGS=
-
-# make gcc default compiler unless CC is already set
-CC=${CC:-gcc}
-
-help() {
-    printf "%4s %s\n" "" "$1"
-}
-
-for i in "$@"; do
-    case $i in
-    --help)
-        echo
-        help "--prefix=<dir>                installation directory [$PREFIX]"
-        help "--extra-cflags=<flags>        append to CFLAGS"
-        help "--extra-ldflags=<flags>       append to LDFLAGS"
-        echo
-        help "--enable-debug"
-        help "--enable-sse/--disable-sse    enable/disable SSE instructions"
-        echo
-        help "--with-openmp=static          compile with multicore support"
-        echo
-        help "CC=<compiler>                 use given compiler command"
-        help "CFLAGS=<flags>                pass options to the compiler"
-        help "LDFLAGS=<flags>               pass options to the linker"
-        echo
-        exit 0
-        ;;
-    # Can be set before or after configure. Latter overrides former.
-    CC=*)
-        CC=${i#*=}
-        ;;
-    CFLAGS=*)
-        CFLAGS=${i#*=}
-        ;;
-    LDFLAGS=*)
-        LDFLAGS=${i#*=}
-        ;;
-    --enable-debug)
-        DEBUG=1
-        ;;
-    --enable-sse)
-        SSE=1
-        ;;
-    --disable-sse)
-        SSE=0
-        ;;
-    --with-openmp)
-        OPENMP=1
-        ;;
-    --with-openmp=static)
-        OPENMP=static
-        ;;
-    --prefix=*)
-        PREFIX=${i#*=}
-        ;;
-    # can be used multiple times or in quotes to set multiple flags
-    --extra-cflags=*)
-        EXTRA_CFLAGS="$EXTRA_CFLAGS ${i#*=}"
-        ;;
-    --extra-ldflags=*)
-        EXTRA_LDFLAGS="$EXTRA_LDFLAGS ${i#*=}"
-        ;;
-    *)
-        echo "error: unknown switch ${i%%=*} (see $0 --help for the list)"
-        exit 1
-        ;;
-    esac
-done
-
-# If someone runs sudo make install as very first command, and configure later,
-# $CONFIG cannot be overwritten, and must be deleted before continuing.
-if [[ -f "$CONFIG" && ! -w "$CONFIG" ]]; then
-    echo "Cannot overwrite file $CONFIG! Please delete it."
-    exit 1
-fi
-
-cflags() {
-    CFLAGS="$CFLAGS $1"
-}
-
-lflags() {
-    LDFLAGS="$LDFLAGS $1"
-}
-
-status() {
-    printf "%10s: %s\n" "$1" "$2"
-}
-
-# Append to CFLAGS if compiler supports flag, with optional prerequisite.
-# Fails on errors and warnings.
-conditional_cflags() {
-    if [ -z "echo | $("$CC" -xc -S -o /dev/null $2 $1 2>&1)" ]; then
-        cflags "$1"
-    fi
-}
-
-error() {
-    status "$1" "error ... $2"
-    echo
-    exit 1
-}
-
-echo
-
-# basic check
-if ! echo "int main(){}" | "$CC" -xc -std=c99 -o /dev/null - > /dev/null; then
-    error "Compiler" "$CC failed to compile anything (make sure it's installed and supports C99)"
-fi
-
-status "Compiler" "$CC"
-
-# init flags
-CFLAGS=${CFLAGS:--O3 -fno-math-errno -funroll-loops -fomit-frame-pointer -Wall}
-cflags "-std=c99 -I."
-
-# DEBUG
-if [ -z "$DEBUG" ]; then
-    cflags "-DNDEBUG"
-    status "Debug" "no"
-else
-    cflags "-g"
-    status "Debug" "yes"
-fi
-
-# SSE
-if [ "$SSE" = 'auto' ]; then
-    if [[ "$(uname -m)" =~ (amd|x86_)64 ||
-          "$(grep -E -m1 "^flags" /proc/cpuinfo)" =~ "sse" ]]; then
-        SSE=1
-    fi
-fi
-
-if [ "$SSE" -eq 1 ]; then
-    status "SSE" "yes"
-    cflags "-DUSE_SSE=1"
-    cflags "-msse"
-    # Silence a later ICC warning due to -msse working slightly different.
-    conditional_cflags "-wd10121"
-    # Must be set explicitly for GCC on x86_32. Other compilers imply it.
-    conditional_cflags "-mfpmath=sse" "-msse"
-elif [ "$SSE" -eq 0 ]; then
-    status "SSE" "no"
-    cflags "-DUSE_SSE=0"
-fi
-
-# OpenMP
-if [ -n "$OPENMP" ]; then
-    if [ "static" = "$OPENMP" ]; then
-        OPENMPFLAGS="-static-libgcc -Bstatic -fopenmp -Bdynamic"
-    else
-        OPENMPFLAGS="-fopenmp"
-    fi
-    if [[ "$("$CC" -xc -E $OPENMPFLAGS <(echo "#ifdef _OPENMP
-           #include <omp.h>
-           #endif") 2>&1)" =~ "omp_get_thread_num" ]]; then
-        cflags "$OPENMPFLAGS"
-        lflags "$OPENMPFLAGS"
-        status "OpenMP" "yes"
-    else
-        error "OpenMP" "not supported by compiler (please install a compiler that supports OpenMP (e.g. gcc) and specify it with the CC= argument)"
-    fi
-else
-    # silence warnings about omp pragmas
-    cflags "-Wno-unknown-pragmas"
-    conditional_cflags "-wd3180" # ICC
-    status "OpenMP" "no"
-fi
-
-echo
-
-# As of GCC 4.5, 387 fp math is significantly slower in C99 mode without this.
-# Note: CPUs without SSE2 use 387 for doubles, even when SSE fp math is set.
-conditional_cflags "-fexcess-precision=fast"
-
-# Intel C++ Compiler
-
-# ICC does usually only produce fast(er) code when it can optimize to the full
-# capabilites of the (Intel) CPU. This is equivalent to -march=native for GCC.
-conditional_cflags "-xHOST"
-
-# Disable unsafe fp optimizations and enforce fp precision as set in the source.
-conditional_cflags "-fp-model source"
-
-# Silence a gold linker warning about string misalignment.
-conditional_cflags "-falign-stack=maintain-16-byte"
-
-lflags "-lm" # Ubuntu requires this library last, issue #38
-
-if [ -n "$EXTRA_CFLAGS" ]; then
-    cflags "$EXTRA_CFLAGS"
-fi
-
-if [ -n "$EXTRA_LDFLAGS" ]; then
-    lflags "$EXTRA_LDFLAGS"
-fi
-
-# Overwrite previous configuration.
-echo "
-# auto-generated by configure
-PREFIX = $PREFIX
-VERSION = $VERSION
-CC = $CC
-CFLAGS = $CFLAGS
-LDFLAGS = $LDFLAGS
-" > "$CONFIG"
diff --git a/src/drivers/libimagequant/libimagequant.c b/src/drivers/libimagequant/libimagequant.c
deleted file mode 100644
index 5023971..0000000
--- a/src/drivers/libimagequant/libimagequant.c
+++ /dev/null
@@ -1,1752 +0,0 @@
-/* pngquant.c - quantize the colors in an alphamap down to a specified number
-**
-** Copyright (C) 1989, 1991 by Jef Poskanzer.
-** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
-**                                Stefan Schneider.
-** © 2009-2015 by Kornel Lesinski.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <limits.h>
-
-#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900L) && !(defined(_MSC_VER) && _MSC_VER >= 1800)
-#error "This program requires C99, e.g. -std=c99 switch in GCC or it requires MSVC 18.0 or higher."
-#error "Ignore torrent of syntax errors that may follow. It's only because compiler is set to use too old C version."
-#endif
-
-#ifdef _OPENMP
-#include <omp.h>
-#else
-#define omp_get_max_threads() 1
-#define omp_get_thread_num() 0
-#endif
-
-#include "libimagequant.h"
-
-#include "pam.h"
-#include "mediancut.h"
-#include "nearest.h"
-#include "blur.h"
-#include "viter.h"
-
-#define LIQ_HIGH_MEMORY_LIMIT (1<<26)  /* avoid allocating buffers larger than 64MB */
-
-// each structure has a pointer as a unique identifier that allows type checking at run time
-static const char *const liq_attr_magic = "liq_attr", *const liq_image_magic = "liq_image",
-     *const liq_result_magic = "liq_result", *const liq_remapping_result_magic = "liq_remapping_result",
-     *const liq_freed_magic = "free";
-#define CHECK_STRUCT_TYPE(attr, kind) liq_crash_if_invalid_handle_pointer_given((const liq_attr*)attr, kind ## _magic)
-#define CHECK_USER_POINTER(ptr) liq_crash_if_invalid_pointer_given(ptr)
-
-struct liq_attr {
-    const char *magic_header;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-
-    double target_mse, max_mse, voronoi_iteration_limit;
-    float min_opaque_val;
-    unsigned int max_colors, max_histogram_entries;
-    unsigned int min_posterization_output /* user setting */, min_posterization_input /* speed setting */;
-    unsigned int voronoi_iterations, feedback_loop_trials;
-    bool last_index_transparent, use_contrast_maps, use_dither_map, fast_palette;
-    unsigned int speed;
-    liq_log_callback_function *log_callback;
-    void *log_callback_user_info;
-    liq_log_flush_callback_function *log_flush_callback;
-    void *log_flush_callback_user_info;
-};
-
-struct liq_image {
-    const char *magic_header;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-
-    f_pixel *f_pixels;
-    rgba_pixel **rows;
-    double gamma;
-    unsigned int width, height;
-    unsigned char *noise, *edges, *dither_map;
-    rgba_pixel *pixels, *temp_row;
-    f_pixel *temp_f_row;
-    liq_image_get_rgba_row_callback *row_callback;
-    void *row_callback_user_info;
-    float min_opaque_val;
-    f_pixel fixed_colors[256];
-    unsigned short fixed_colors_count;
-    bool free_pixels, free_rows, free_rows_internal;
-};
-
-typedef struct liq_remapping_result {
-    const char *magic_header;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-
-    unsigned char *pixels;
-    colormap *palette;
-    liq_palette int_palette;
-    double gamma, palette_error;
-    float dither_level;
-    bool use_dither_map;
-} liq_remapping_result;
-
-struct liq_result {
-    const char *magic_header;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-
-    liq_remapping_result *remapping;
-    colormap *palette;
-    liq_palette int_palette;
-    float dither_level;
-    double gamma, palette_error;
-    int min_posterization_output;
-    bool use_dither_map, fast_palette;
-};
-
-static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, const liq_image *img) LIQ_NONNULL;
-static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels) LIQ_NONNULL;
-static void contrast_maps(liq_image *image) LIQ_NONNULL;
-static histogram *get_histogram(liq_image *input_image, const liq_attr *options) LIQ_NONNULL;
-static const rgba_pixel *liq_image_get_row_rgba(liq_image *input_image, unsigned int row) LIQ_NONNULL;
-static const f_pixel *liq_image_get_row_f(liq_image *input_image, unsigned int row) LIQ_NONNULL;
-static void liq_remapping_result_destroy(liq_remapping_result *result) LIQ_NONNULL;
-
-LIQ_NONNULL static void liq_verbose_printf(const liq_attr *context, const char *fmt, ...)
-{
-    if (context->log_callback) {
-        va_list va;
-        va_start(va, fmt);
-        int required_space = vsnprintf(NULL, 0, fmt, va)+1; // +\0
-        va_end(va);
-
-        char buf[required_space];
-        va_start(va, fmt);
-        vsnprintf(buf, required_space, fmt, va);
-        va_end(va);
-
-        context->log_callback(context, buf, context->log_callback_user_info);
-    }
-}
-
-LIQ_NONNULL inline static void verbose_print(const liq_attr *attr, const char *msg)
-{
-    if (attr->log_callback) {
-        attr->log_callback(attr, msg, attr->log_callback_user_info);
-    }
-}
-
-LIQ_NONNULL static void liq_verbose_printf_flush(liq_attr *attr)
-{
-    if (attr->log_flush_callback) {
-        attr->log_flush_callback(attr, attr->log_flush_callback_user_info);
-    }
-}
-
-#if USE_SSE
-inline static bool is_sse_available()
-{
-#if (defined(__x86_64__) || defined(__amd64))
-    return true;
-#else
-    int a,b,c,d;
-        cpuid(1, a, b, c, d);
-    return d & (1<<25); // edx bit 25 is set when SSE is present
-#endif
-}
-#endif
-
-/* make it clear in backtrace when user-supplied handle points to invalid memory */
-NEVER_INLINE LIQ_EXPORT bool liq_crash_if_invalid_handle_pointer_given(const liq_attr *user_supplied_pointer, const char *const expected_magic_header);
-LIQ_EXPORT bool liq_crash_if_invalid_handle_pointer_given(const liq_attr *user_supplied_pointer, const char *const expected_magic_header)
-{
-    if (!user_supplied_pointer) {
-        return false;
-    }
-
-    if (user_supplied_pointer->magic_header == liq_freed_magic) {
-        fprintf(stderr, "%s used after being freed", expected_magic_header);
-        // this is not normal error handling, this is programmer error that should crash the program.
-        // program cannot safely continue if memory has been used after it's been freed.
-        // abort() is nasty, but security vulnerability may be worse.
-        abort();
-    }
-
-    return user_supplied_pointer->magic_header == expected_magic_header;
-}
-
-NEVER_INLINE LIQ_EXPORT bool liq_crash_if_invalid_pointer_given(void *pointer);
-LIQ_EXPORT bool liq_crash_if_invalid_pointer_given(void *pointer)
-{
-    if (!pointer) {
-        return false;
-    }
-    // Force a read from the given (potentially invalid) memory location in order to check early whether this crashes the program or not.
-    // It doesn't matter what value is read, the code here is just to shut the compiler up about unused read.
-    char test_access = *((volatile char *)pointer);
-    return test_access || true;
-}
-
-LIQ_NONNULL static void liq_log_error(const liq_attr *attr, const char *msg)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
-    liq_verbose_printf(attr, "  error: %s", msg);
-}
-
-static double quality_to_mse(long quality)
-{
-    if (quality == 0) {
-        return MAX_DIFF;
-    }
-    if (quality == 100) {
-        return 0;
-    }
-
-    // curve fudged to be roughly similar to quality of libjpeg
-    // except lowest 10 for really low number of colors
-    const double extra_low_quality_fudge = MAX(0,0.016/(0.001+quality) - 0.001);
-    return extra_low_quality_fudge + 2.5/pow(210.0 + quality, 1.2) * (100.1-quality)/100.0;
-}
-
-static unsigned int mse_to_quality(double mse)
-{
-    for(int i=100; i > 0; i--) {
-        if (mse <= quality_to_mse(i) + 0.000001) { // + epsilon for floating point errors
-            return i;
-        }
-    }
-    return 0;
-}
-
-/** internally MSE is a sum of all channels with pixels 0..1 range,
- but other software gives per-RGB-channel MSE for 0..255 range */
-static double mse_to_standard_mse(double mse) {
-    return mse * 65536.0/6.0;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_quality(liq_attr* attr, int minimum, int target)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
-    if (target < 0 || target > 100 || target < minimum || minimum < 0) return LIQ_VALUE_OUT_OF_RANGE;
-
-    attr->target_mse = quality_to_mse(target);
-    attr->max_mse = quality_to_mse(minimum);
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_min_quality(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-    return mse_to_quality(attr->max_mse);
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_max_quality(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-    return mse_to_quality(attr->target_mse);
-}
-
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_max_colors(liq_attr* attr, int colors)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
-    if (colors < 2 || colors > 256) return LIQ_VALUE_OUT_OF_RANGE;
-
-    attr->max_colors = colors;
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_max_colors(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-
-    return attr->max_colors;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_posterization(liq_attr *attr, int bits)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
-    if (bits < 0 || bits > 4) return LIQ_VALUE_OUT_OF_RANGE;
-
-    attr->min_posterization_output = bits;
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_min_posterization(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-
-    return attr->min_posterization_output;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_speed(liq_attr* attr, int speed)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
-    if (speed < 1 || speed > 10) return LIQ_VALUE_OUT_OF_RANGE;
-
-    unsigned int iterations = MAX(8-speed, 0); iterations += iterations * iterations/2;
-    attr->voronoi_iterations = iterations;
-    attr->voronoi_iteration_limit = 1.0/(double)(1<<(23-speed));
-    attr->feedback_loop_trials = MAX(56-9*speed, 0);
-
-    attr->max_histogram_entries = (1<<17) + (1<<18)*(10-speed);
-    attr->min_posterization_input = (speed >= 8) ? 1 : 0;
-    attr->fast_palette = (speed >= 7);
-    attr->use_dither_map = (speed <= (omp_get_max_threads() > 1 ? 7 : 5)); // parallelized dither map might speed up floyd remapping
-    attr->use_contrast_maps = (speed <= 7) || attr->use_dither_map;
-    attr->speed = speed;
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_speed(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-
-    return attr->speed;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_output_gamma(liq_result* res, double gamma)
-{
-    if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
-    if (gamma <= 0 || gamma >= 1.0) return LIQ_VALUE_OUT_OF_RANGE;
-
-    if (res->remapping) {
-        liq_remapping_result_destroy(res->remapping);
-        res->remapping = NULL;
-    }
-
-    res->gamma = gamma;
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_opacity(liq_attr* attr, int min)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
-    if (min < 0 || min > 255) return LIQ_VALUE_OUT_OF_RANGE;
-
-    attr->min_opaque_val = (double)min/255.0;
-    return LIQ_OK;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_min_opacity(const liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
-
-    return MIN(255, 256.0 * attr->min_opaque_val);
-}
-
-LIQ_EXPORT LIQ_NONNULL void liq_set_last_index_transparent(liq_attr* attr, int is_last)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
-
-    attr->last_index_transparent = !!is_last;
-}
-
-LIQ_EXPORT void liq_set_log_callback(liq_attr *attr, liq_log_callback_function *callback, void* user_info)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
-
-    liq_verbose_printf_flush(attr);
-    attr->log_callback = callback;
-    attr->log_callback_user_info = user_info;
-}
-
-LIQ_EXPORT void liq_set_log_flush_callback(liq_attr *attr, liq_log_flush_callback_function *callback, void* user_info)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
-
-    attr->log_flush_callback = callback;
-    attr->log_flush_callback_user_info = user_info;
-}
-
-LIQ_EXPORT liq_attr* liq_attr_create()
-{
-    return liq_attr_create_with_allocator(NULL, NULL);
-}
-
-LIQ_EXPORT LIQ_NONNULL void liq_attr_destroy(liq_attr *attr)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
-        return;
-    }
-
-    liq_verbose_printf_flush(attr);
-
-    attr->magic_header = liq_freed_magic;
-    attr->free(attr);
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_attr* liq_attr_copy(liq_attr *orig)
-{
-    if (!CHECK_STRUCT_TYPE(orig, liq_attr)) {
-        return NULL;
-    }
-
-    liq_attr *attr = orig->malloc(sizeof(liq_attr));
-    if (!attr) return NULL;
-    *attr = *orig;
-    return attr;
-}
-
-static void *liq_aligned_malloc(size_t size)
-{
-    unsigned char *ptr = malloc(size + 16);
-    if (!ptr) {
-        return NULL;
-    }
-
-    uintptr_t offset = 16 - ((uintptr_t)ptr & 15); // also reserves 1 byte for ptr[-1]
-    ptr += offset;
-    assert(0 == (((uintptr_t)ptr) & 15));
-    ptr[-1] = offset ^ 0x59; // store how much pointer was shifted to get the original for free()
-    return ptr;
-}
-
-LIQ_NONNULL static void liq_aligned_free(void *inptr)
-{
-    unsigned char *ptr = inptr;
-    size_t offset = ptr[-1] ^ 0x59;
-    assert(offset > 0 && offset <= 16);
-    free(ptr - offset);
-}
-
-LIQ_EXPORT liq_attr* liq_attr_create_with_allocator(void* (*custom_malloc)(size_t), void (*custom_free)(void*))
-{
-#if USE_SSE
-    if (!is_sse_available()) {
-        return NULL;
-    }
-#endif
-    if (!custom_malloc && !custom_free) {
-        custom_malloc = liq_aligned_malloc;
-        custom_free = liq_aligned_free;
-    } else if (!custom_malloc != !custom_free) {
-        return NULL; // either specify both or none
-    }
-
-    liq_attr *attr = custom_malloc(sizeof(liq_attr));
-    if (!attr) return NULL;
-    *attr = (liq_attr) {
-        .magic_header = liq_attr_magic,
-        .malloc = custom_malloc,
-        .free = custom_free,
-        .max_colors = 256,
-        .min_opaque_val = 1, // whether preserve opaque colors for IE (1.0=no, does not affect alpha)
-        .last_index_transparent = false, // puts transparent color at last index. This is workaround for blu-ray subtitles.
-        .target_mse = 0,
-        .max_mse = MAX_DIFF,
-    };
-    liq_set_speed(attr, 3);
-    return attr;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_image_add_fixed_color(liq_image *img, liq_color color)
-{
-    if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
-    if (img->fixed_colors_count > 255) return LIQ_BUFFER_TOO_SMALL;
-
-    float gamma_lut[256];
-    to_f_set_gamma(gamma_lut, img->gamma);
-    img->fixed_colors[img->fixed_colors_count++] = to_f(gamma_lut, (rgba_pixel){
-        .r = color.r,
-        .g = color.g,
-        .b = color.b,
-        .a = color.a,
-    });
-    return LIQ_OK;
-}
-
-LIQ_NONNULL static bool liq_image_use_low_memory(liq_image *img)
-{
-    img->temp_f_row = img->malloc(sizeof(img->f_pixels[0]) * img->width * omp_get_max_threads());
-    return img->temp_f_row != NULL;
-}
-
-LIQ_NONNULL static bool liq_image_should_use_low_memory(liq_image *img, const bool low_memory_hint)
-{
-    return img->width * img->height > (low_memory_hint ? LIQ_HIGH_MEMORY_LIMIT/8 : LIQ_HIGH_MEMORY_LIMIT) / sizeof(f_pixel); // Watch out for integer overflow
-}
-
-static liq_image *liq_image_create_internal(liq_attr *attr, rgba_pixel* rows[], liq_image_get_rgba_row_callback *row_callback, void *row_callback_user_info, int width, int height, double gamma)
-{
-    if (gamma < 0 || gamma > 1.0) {
-        liq_log_error(attr, "gamma must be >= 0 and <= 1 (try 1/gamma instead)");
-        return NULL;
-    }
-
-    if (!rows && !row_callback) {
-        liq_log_error(attr, "missing row data");
-        return NULL;
-    }
-
-    liq_image *img = attr->malloc(sizeof(liq_image));
-    if (!img) return NULL;
-    *img = (liq_image){
-        .magic_header = liq_image_magic,
-        .malloc = attr->malloc,
-        .free = attr->free,
-        .width = width, .height = height,
-        .gamma = gamma ? gamma : 0.45455,
-        .rows = rows,
-        .row_callback = row_callback,
-        .row_callback_user_info = row_callback_user_info,
-        .min_opaque_val = attr->min_opaque_val,
-    };
-
-    if (!rows || attr->min_opaque_val < 1.f) {
-        img->temp_row = attr->malloc(sizeof(img->temp_row[0]) * width * omp_get_max_threads());
-        if (!img->temp_row) return NULL;
-    }
-
-    // if image is huge or converted pixels are not likely to be reused then don't cache converted pixels
-    if (liq_image_should_use_low_memory(img, !img->temp_row && !attr->use_contrast_maps && !attr->use_dither_map)) {
-        verbose_print(attr, "  conserving memory");
-        if (!liq_image_use_low_memory(img)) return NULL;
-    }
-
-    if (img->min_opaque_val < 1.f) {
-        verbose_print(attr, "  Working around IE6 bug by making image less transparent...");
-    }
-
-    return img;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_memory_ownership(liq_image *img, int ownership_flags)
-{
-    if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
-    if (!img->rows || !ownership_flags || (ownership_flags & ~(LIQ_OWN_ROWS|LIQ_OWN_PIXELS))) {
-        return LIQ_VALUE_OUT_OF_RANGE;
-    }
-
-    if (ownership_flags & LIQ_OWN_ROWS) {
-        if (img->free_rows_internal) return LIQ_VALUE_OUT_OF_RANGE;
-        img->free_rows = true;
-    }
-
-    if (ownership_flags & LIQ_OWN_PIXELS) {
-        img->free_pixels = true;
-        if (!img->pixels) {
-            // for simplicity of this API there's no explicit bitmap argument,
-            // so the row with the lowest address is assumed to be at the start of the bitmap
-            img->pixels = img->rows[0];
-            for(unsigned int i=1; i < img->height; i++) {
-                img->pixels = MIN(img->pixels, img->rows[i]);
-            }
-        }
-    }
-
-    return LIQ_OK;
-}
-
-LIQ_NONNULL static bool check_image_size(const liq_attr *attr, const int width, const int height)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
-        return false;
-    }
-
-    if (width <= 0 || height <= 0) {
-        liq_log_error(attr, "width and height must be > 0");
-        return false;
-    }
-    if (width > INT_MAX/height) {
-        liq_log_error(attr, "image too large");
-        return false;
-    }
-    return true;
-}
-
-LIQ_EXPORT liq_image *liq_image_create_custom(liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void* user_info, int width, int height, double gamma)
-{
-    if (!check_image_size(attr, width, height)) {
-        return NULL;
-    }
-    return liq_image_create_internal(attr, NULL, row_callback, user_info, width, height, gamma);
-}
-
-LIQ_EXPORT liq_image *liq_image_create_rgba_rows(liq_attr *attr, void* rows[], int width, int height, double gamma)
-{
-    if (!check_image_size(attr, width, height)) {
-        return NULL;
-    }
-
-    for(int i=0; i < height; i++) {
-        if (!CHECK_USER_POINTER(rows+i) || !CHECK_USER_POINTER(rows[i])) {
-            liq_log_error(attr, "invalid row pointers");
-            return NULL;
-        }
-    }
-    return liq_image_create_internal(attr, (rgba_pixel**)rows, NULL, NULL, width, height, gamma);
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma)
-{
-    if (!check_image_size(attr, width, height)) {
-        return NULL;
-    }
-    if (!CHECK_USER_POINTER(bitmap)) {
-        liq_log_error(attr, "invalid bitmap pointer");
-        return NULL;
-    }
-
-    rgba_pixel *pixels = bitmap;
-    rgba_pixel **rows = attr->malloc(sizeof(rows[0])*height);
-    if (!rows) return NULL;
-
-    for(int i=0; i < height; i++) {
-        rows[i] = pixels + width * i;
-    }
-
-    liq_image *image = liq_image_create_internal(attr, rows, NULL, NULL, width, height, gamma);
-    if (!image) {
-        attr->free(rows);
-        return NULL;
-    }
-    image->free_rows = true;
-    image->free_rows_internal = true;
-    return image;
-}
-
-NEVER_INLINE LIQ_EXPORT void liq_executing_user_callback(liq_image_get_rgba_row_callback *callback, liq_color *temp_row, int row, int width, void *user_info);
-LIQ_EXPORT void liq_executing_user_callback(liq_image_get_rgba_row_callback *callback, liq_color *temp_row, int row, int width, void *user_info)
-{
-    assert(callback);
-    assert(temp_row);
-    callback(temp_row, row, width, user_info);
-}
-
-LIQ_NONNULL inline static bool liq_image_can_use_rows(liq_image *img)
-{
-    const bool iebug = img->min_opaque_val < 1.f;
-    return (img->rows && !iebug);
-}
-
-LIQ_NONNULL static const rgba_pixel *liq_image_get_row_rgba(liq_image *img, unsigned int row)
-{
-    if (liq_image_can_use_rows(img)) {
-        return img->rows[row];
-    }
-
-    assert(img->temp_row);
-    rgba_pixel *temp_row = img->temp_row + img->width * omp_get_thread_num();
-    if (img->rows) {
-        memcpy(temp_row, img->rows[row], img->width * sizeof(temp_row[0]));
-    } else {
-        liq_executing_user_callback(img->row_callback, (liq_color*)temp_row, row, img->width, img->row_callback_user_info);
-    }
-
-    if (img->min_opaque_val < 1.f) modify_alpha(img, temp_row);
-    return temp_row;
-}
-
-LIQ_NONNULL static void convert_row_to_f(liq_image *img, f_pixel *row_f_pixels, const unsigned int row, const float gamma_lut[])
-{
-    assert(row_f_pixels);
-    assert(!USE_SSE || 0 == ((uintptr_t)row_f_pixels & 15));
-
-    const rgba_pixel *const row_pixels = liq_image_get_row_rgba(img, row);
-
-    for(unsigned int col=0; col < img->width; col++) {
-        row_f_pixels[col] = to_f(gamma_lut, row_pixels[col]);
-    }
-}
-
-LIQ_NONNULL static const f_pixel *liq_image_get_row_f(liq_image *img, unsigned int row)
-{
-    if (!img->f_pixels) {
-        if (img->temp_f_row) {
-            float gamma_lut[256];
-            to_f_set_gamma(gamma_lut, img->gamma);
-            f_pixel *row_for_thread = img->temp_f_row + img->width * omp_get_thread_num();
-            convert_row_to_f(img, row_for_thread, row, gamma_lut);
-            return row_for_thread;
-        }
-
-        assert(omp_get_thread_num() == 0);
-        if (!liq_image_should_use_low_memory(img, false)) {
-            img->f_pixels = img->malloc(sizeof(img->f_pixels[0]) * img->width * img->height);
-        }
-        if (!img->f_pixels) {
-            if (!liq_image_use_low_memory(img)) return NULL;
-            return liq_image_get_row_f(img, row);
-        }
-
-        float gamma_lut[256];
-        to_f_set_gamma(gamma_lut, img->gamma);
-        for(unsigned int i=0; i < img->height; i++) {
-            convert_row_to_f(img, &img->f_pixels[i*img->width], i, gamma_lut);
-        }
-    }
-    return img->f_pixels + img->width * row;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_image_get_width(const liq_image *input_image)
-{
-    if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
-    return input_image->width;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_image_get_height(const liq_image *input_image)
-{
-    if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
-    return input_image->height;
-}
-
-typedef void free_func(void*);
-
-LIQ_NONNULL static free_func *get_default_free_func(liq_image *img)
-{
-    // When default allocator is used then user-supplied pointers must be freed with free()
-    if (img->free_rows_internal || img->free != liq_aligned_free) {
-        return img->free;
-    }
-    return free;
-}
-
-LIQ_NONNULL static void liq_image_free_rgba_source(liq_image *input_image)
-{
-    if (input_image->free_pixels && input_image->pixels) {
-        get_default_free_func(input_image)(input_image->pixels);
-        input_image->pixels = NULL;
-    }
-
-    if (input_image->free_rows && input_image->rows) {
-        get_default_free_func(input_image)(input_image->rows);
-        input_image->rows = NULL;
-    }
-}
-
-LIQ_EXPORT LIQ_NONNULL void liq_image_destroy(liq_image *input_image)
-{
-    if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return;
-
-    liq_image_free_rgba_source(input_image);
-
-    if (input_image->noise) {
-        input_image->free(input_image->noise);
-    }
-
-    if (input_image->edges) {
-        input_image->free(input_image->edges);
-    }
-
-    if (input_image->dither_map) {
-        input_image->free(input_image->dither_map);
-    }
-
-    if (input_image->f_pixels) {
-        input_image->free(input_image->f_pixels);
-    }
-
-    if (input_image->temp_row) {
-        input_image->free(input_image->temp_row);
-    }
-
-    if (input_image->temp_f_row) {
-        input_image->free(input_image->temp_f_row);
-    }
-
-    input_image->magic_header = liq_freed_magic;
-    input_image->free(input_image);
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_result *liq_quantize_image(liq_attr *attr, liq_image *img)
-{
-    if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return NULL;
-    if (!CHECK_STRUCT_TYPE(img, liq_image)) {
-        liq_log_error(attr, "invalid image pointer");
-        return NULL;
-    }
-
-    histogram *hist = get_histogram(img, attr);
-    if (!hist) {
-        return NULL;
-    }
-
-    liq_result *result = pngquant_quantize(hist, attr, img);
-
-    pam_freeacolorhist(hist);
-    return result;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_set_dithering_level(liq_result *res, float dither_level)
-{
-    if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
-
-    if (res->remapping) {
-        liq_remapping_result_destroy(res->remapping);
-        res->remapping = NULL;
-    }
-
-    if (res->dither_level < 0 || res->dither_level > 1.0f) return LIQ_VALUE_OUT_OF_RANGE;
-    res->dither_level = dither_level;
-    return LIQ_OK;
-}
-
-LIQ_NONNULL static liq_remapping_result *liq_remapping_result_create(liq_result *result)
-{
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) {
-        return NULL;
-    }
-
-    liq_remapping_result *res = result->malloc(sizeof(liq_remapping_result));
-    if (!res) return NULL;
-    *res = (liq_remapping_result) {
-        .magic_header = liq_remapping_result_magic,
-        .malloc = result->malloc,
-        .free = result->free,
-        .dither_level = result->dither_level,
-        .use_dither_map = result->use_dither_map,
-        .palette_error = result->palette_error,
-        .gamma = result->gamma,
-        .palette = pam_duplicate_colormap(result->palette),
-    };
-    return res;
-}
-
-LIQ_EXPORT LIQ_NONNULL double liq_get_output_gamma(const liq_result *result)
-{
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
-
-    return result->gamma;
-}
-
-LIQ_NONNULL static void liq_remapping_result_destroy(liq_remapping_result *result)
-{
-    if (!CHECK_STRUCT_TYPE(result, liq_remapping_result)) return;
-
-    if (result->palette) pam_freecolormap(result->palette);
-    if (result->pixels) result->free(result->pixels);
-
-    result->magic_header = liq_freed_magic;
-    result->free(result);
-}
-
-LIQ_EXPORT LIQ_NONNULL void liq_result_destroy(liq_result *res)
-{
-    if (!CHECK_STRUCT_TYPE(res, liq_result)) return;
-
-    memset(&res->int_palette, 0, sizeof(liq_palette));
-
-    if (res->remapping) {
-        memset(&res->remapping->int_palette, 0, sizeof(liq_palette));
-        liq_remapping_result_destroy(res->remapping);
-    }
-
-    pam_freecolormap(res->palette);
-
-    res->magic_header = liq_freed_magic;
-    res->free(res);
-}
-
-
-LIQ_EXPORT LIQ_NONNULL double liq_get_quantization_error(liq_result *result) {
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
-
-    if (result->palette_error >= 0) {
-        return mse_to_standard_mse(result->palette_error);
-    }
-
-    return -1;
-}
-
-LIQ_EXPORT LIQ_NONNULL double liq_get_remapping_error(liq_result *result) {
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
-
-    if (result->remapping && result->remapping->palette_error >= 0) {
-        return mse_to_standard_mse(result->remapping->palette_error);
-    }
-
-    return -1;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_quantization_quality(liq_result *result) {
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
-
-    if (result->palette_error >= 0) {
-        return mse_to_quality(result->palette_error);
-    }
-
-    return -1;
-}
-
-LIQ_EXPORT LIQ_NONNULL int liq_get_remapping_quality(liq_result *result) {
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
-
-    if (result->remapping && result->remapping->palette_error >= 0) {
-        return mse_to_quality(result->remapping->palette_error);
-    }
-
-    return -1;
-}
-
-LIQ_NONNULL static int compare_popularity(const void *ch1, const void *ch2)
-{
-    const float v1 = ((const colormap_item*)ch1)->popularity;
-    const float v2 = ((const colormap_item*)ch2)->popularity;
-    return v1 > v2 ? -1 : 1;
-}
-
-LIQ_NONNULL static void sort_palette_qsort(colormap *map, int start, int nelem)
-{
-    if (!nelem) return;
-    qsort(map->palette + start, nelem, sizeof(map->palette[0]), compare_popularity);
-}
-
-#define SWAP_PALETTE(map, a,b) { \
-    const colormap_item tmp = (map)->palette[(a)]; \
-    (map)->palette[(a)] = (map)->palette[(b)]; \
-    (map)->palette[(b)] = tmp; }
-
-LIQ_NONNULL static void sort_palette(colormap *map, const liq_attr *options)
-{
-    /*
-    ** Step 3.5 [GRR]: remap the palette colors so that all entries with
-    ** the maximal alpha value (i.e., fully opaque) are at the end and can
-    ** therefore be omitted from the tRNS chunk.
-    */
-    if (options->last_index_transparent) {
-        for(unsigned int i=0; i < map->colors; i++) {
-            if (map->palette[i].acolor.a < 1.0/256.0) {
-                const unsigned int old = i, transparent_dest = map->colors-1;
-
-                SWAP_PALETTE(map, transparent_dest, old);
-
-                /* colors sorted by popularity make pngs slightly more compressible */
-                sort_palette_qsort(map, 0, map->colors-1);
-                return;
-            }
-        }
-    }
-
-    unsigned int non_fixed_colors = 0;
-    for(unsigned int i = 0; i < map->colors; i++) {
-        if (map->palette[i].fixed) {
-            break;
-        }
-        non_fixed_colors++;
-    }
-
-    /* move transparent colors to the beginning to shrink trns chunk */
-    unsigned int num_transparent = 0;
-    for(unsigned int i = 0; i < non_fixed_colors; i++) {
-        if (map->palette[i].acolor.a < 255.0/256.0) {
-            // current transparent color is swapped with earlier opaque one
-            if (i != num_transparent) {
-                SWAP_PALETTE(map, num_transparent, i);
-                i--;
-            }
-            num_transparent++;
-        }
-    }
-
-    liq_verbose_printf(options, "  eliminated opaque tRNS-chunk entries...%d entr%s transparent", num_transparent, (num_transparent == 1)? "y" : "ies");
-
-    /* colors sorted by popularity make pngs slightly more compressible
-     * opaque and transparent are sorted separately
-     */
-    sort_palette_qsort(map, 0, num_transparent);
-    sort_palette_qsort(map, num_transparent, non_fixed_colors - num_transparent);
-
-    if (non_fixed_colors > 9 && map->colors > 16) {
-        SWAP_PALETTE(map, 7, 1); // slightly improves compression
-        SWAP_PALETTE(map, 8, 2);
-        SWAP_PALETTE(map, 9, 3);
-    }
-}
-
-inline static unsigned int posterize_channel(unsigned int color, unsigned int bits)
-{
-    return (color & ~((1<<bits)-1)) | (color >> (8-bits));
-}
-
-LIQ_NONNULL static void set_rounded_palette(liq_palette *const dest, colormap *const map, const double gamma, unsigned int posterize)
-{
-    float gamma_lut[256];
-    to_f_set_gamma(gamma_lut, gamma);
-
-    dest->count = map->colors;
-    for(unsigned int x = 0; x < map->colors; ++x) {
-        rgba_pixel px = to_rgb(gamma, map->palette[x].acolor);
-
-        px.r = posterize_channel(px.r, posterize);
-        px.g = posterize_channel(px.g, posterize);
-        px.b = posterize_channel(px.b, posterize);
-        px.a = posterize_channel(px.a, posterize);
-
-        map->palette[x].acolor = to_f(gamma_lut, px); /* saves rounding error introduced by to_rgb, which makes remapping & dithering more accurate */
-
-        if (!px.a && !map->palette[x].fixed) {
-            px.r = 'L'; px.g = 'i'; px.b = 'q';
-        }
-
-        dest->entries[x] = (liq_color){.r=px.r,.g=px.g,.b=px.b,.a=px.a};
-    }
-}
-
-LIQ_EXPORT LIQ_NONNULL const liq_palette *liq_get_palette(liq_result *result)
-{
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) return NULL;
-
-    if (result->remapping && result->remapping->int_palette.count) {
-        return &result->remapping->int_palette;
-    }
-
-    if (!result->int_palette.count) {
-        set_rounded_palette(&result->int_palette, result->palette, result->gamma, result->min_posterization_output);
-    }
-    return &result->int_palette;
-}
-
-LIQ_NONNULL static float remap_to_palette(liq_image *const input_image, unsigned char *const *const output_pixels, colormap *const map, const bool fast)
-{
-    const int rows = input_image->height;
-    const unsigned int cols = input_image->width;
-    double remapping_error=0;
-
-    if (!liq_image_get_row_f(input_image, 0)) { // trigger lazy conversion
-        return -1;
-    }
-
-    struct nearest_map *const n = nearest_init(map, fast);
-
-    const unsigned int max_threads = omp_get_max_threads();
-    viter_state average_color[(VITER_CACHE_LINE_GAP+map->colors) * max_threads];
-    viter_init(map, max_threads, average_color);
-
-    #pragma omp parallel for if (rows*cols > 3000) \
-        schedule(static) default(none) shared(average_color) reduction(+:remapping_error)
-    for(int row = 0; row < rows; ++row) {
-        const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row);
-        unsigned int last_match=0;
-        for(unsigned int col = 0; col < cols; ++col) {
-            float diff;
-            output_pixels[row][col] = last_match = nearest_search(n, &row_pixels[col], last_match, &diff);
-
-            remapping_error += diff;
-            viter_update_color(row_pixels[col], 1.0, map, last_match, omp_get_thread_num(), average_color);
-        }
-    }
-
-    viter_finalize(map, max_threads, average_color);
-
-    nearest_free(n);
-
-    return remapping_error / (input_image->width * input_image->height);
-}
-
-inline static f_pixel get_dithered_pixel(const float dither_level, const float max_dither_error, const f_pixel thiserr, const f_pixel px)
-{
-    /* Use Floyd-Steinberg errors to adjust actual color. */
-    const float sr = thiserr.r * dither_level,
-                sg = thiserr.g * dither_level,
-                sb = thiserr.b * dither_level,
-                sa = thiserr.a * dither_level;
-
-    float ratio = 1.0;
-
-    // allowing some overflow prevents undithered bands caused by clamping of all channels
-         if (px.r + sr > 1.03) ratio = MIN(ratio, (1.03-px.r)/sr);
-    else if (px.r + sr < 0)    ratio = MIN(ratio, px.r/-sr);
-         if (px.g + sg > 1.03) ratio = MIN(ratio, (1.03-px.g)/sg);
-    else if (px.g + sg < 0)    ratio = MIN(ratio, px.g/-sg);
-         if (px.b + sb > 1.03) ratio = MIN(ratio, (1.03-px.b)/sb);
-    else if (px.b + sb < 0)    ratio = MIN(ratio, px.b/-sb);
-
-    float a = px.a + sa;
-         if (a > 1.0) { a = 1.0; }
-    else if (a < 0)   { a = 0; }
-
-     // If dithering error is crazy high, don't propagate it that much
-     // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
-     const float dither_error = sr*sr + sg*sg + sb*sb + sa*sa;
-     if (dither_error > max_dither_error) {
-         ratio *= 0.8;
-     } else if (dither_error < 2.f/256.f/256.f) {
-        // don't dither areas that don't have noticeable error — makes file smaller
-        return px;
-     }
-
-     return (f_pixel){
-         .r=px.r + sr * ratio,
-         .g=px.g + sg * ratio,
-         .b=px.b + sb * ratio,
-         .a=a,
-     };
-}
-
-/**
-  Uses edge/noise map to apply dithering only to flat areas. Dithering on edges creates jagged lines, and noisy areas are "naturally" dithered.
-
-  If output_image_is_remapped is true, only pixels noticeably changed by error diffusion will be written to output image.
- */
-LIQ_NONNULL static void remap_to_palette_floyd(liq_image *input_image, unsigned char *const output_pixels[], const colormap *map, const float max_dither_error, const bool use_dither_map, const bool output_image_is_remapped, float base_dithering_level)
-{
-    const unsigned int rows = input_image->height, cols = input_image->width;
-    const unsigned char *dither_map = use_dither_map ? (input_image->dither_map ? input_image->dither_map : input_image->edges) : NULL;
-
-    const colormap_item *acolormap = map->palette;
-
-    struct nearest_map *const n = nearest_init(map, false);
-
-    /* Initialize Floyd-Steinberg error vectors. */
-    f_pixel *restrict thiserr, *restrict nexterr;
-    thiserr = input_image->malloc((cols + 2) * sizeof(*thiserr) * 2); // +2 saves from checking out of bounds access
-    nexterr = thiserr + (cols + 2);
-    srand(12345); /* deterministic dithering is better for comparing results */
-    if (!thiserr) return;
-
-    for (unsigned int col = 0; col < cols + 2; ++col) {
-        const double rand_max = RAND_MAX;
-        thiserr[col].r = ((double)rand() - rand_max/2.0)/rand_max/255.0;
-        thiserr[col].g = ((double)rand() - rand_max/2.0)/rand_max/255.0;
-        thiserr[col].b = ((double)rand() - rand_max/2.0)/rand_max/255.0;
-        thiserr[col].a = ((double)rand() - rand_max/2.0)/rand_max/255.0;
-    }
-
-    // response to this value is non-linear and without it any value < 0.8 would give almost no dithering
-    base_dithering_level = 1.0 - (1.0-base_dithering_level)*(1.0-base_dithering_level)*(1.0-base_dithering_level);
-
-    if (dither_map) {
-        base_dithering_level *= 1.0/255.0; // convert byte to float
-    }
-    base_dithering_level *= 15.0/16.0; // prevent small errors from accumulating
-
-    bool fs_direction = true;
-    unsigned int last_match=0;
-    for (unsigned int row = 0; row < rows; ++row) {
-        memset(nexterr, 0, (cols + 2) * sizeof(*nexterr));
-
-        unsigned int col = (fs_direction) ? 0 : (cols - 1);
-        const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row);
-
-        do {
-            float dither_level = base_dithering_level;
-            if (dither_map) {
-                dither_level *= dither_map[row*cols + col];
-            }
-
-            const f_pixel spx = get_dithered_pixel(dither_level, max_dither_error, thiserr[col + 1], row_pixels[col]);
-
-            const unsigned int guessed_match = output_image_is_remapped ? output_pixels[row][col] : last_match;
-            output_pixels[row][col] = last_match = nearest_search(n, &spx, guessed_match, NULL);
-
-            const f_pixel xp = acolormap[last_match].acolor;
-            f_pixel err = {
-                .r = (spx.r - xp.r),
-                .g = (spx.g - xp.g),
-                .b = (spx.b - xp.b),
-                .a = (spx.a - xp.a),
-            };
-
-            // If dithering error is crazy high, don't propagate it that much
-            // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
-            if (err.r*err.r + err.g*err.g + err.b*err.b + err.a*err.a > max_dither_error) {
-                dither_level *= 0.75;
-            }
-
-            const float colorimp = (3.0f + acolormap[last_match].acolor.a)/4.0f * dither_level;
-            err.r *= colorimp;
-            err.g *= colorimp;
-            err.b *= colorimp;
-            err.a *= dither_level;
-
-            /* Propagate Floyd-Steinberg error terms. */
-            if (fs_direction) {
-                thiserr[col + 2].a += err.a * (7.f/16.f);
-                thiserr[col + 2].r += err.r * (7.f/16.f);
-                thiserr[col + 2].g += err.g * (7.f/16.f);
-                thiserr[col + 2].b += err.b * (7.f/16.f);
-
-                nexterr[col + 2].a  = err.a * (1.f/16.f);
-                nexterr[col + 2].r  = err.r * (1.f/16.f);
-                nexterr[col + 2].g  = err.g * (1.f/16.f);
-                nexterr[col + 2].b  = err.b * (1.f/16.f);
-
-                nexterr[col + 1].a += err.a * (5.f/16.f);
-                nexterr[col + 1].r += err.r * (5.f/16.f);
-                nexterr[col + 1].g += err.g * (5.f/16.f);
-                nexterr[col + 1].b += err.b * (5.f/16.f);
-
-                nexterr[col    ].a += err.a * (3.f/16.f);
-                nexterr[col    ].r += err.r * (3.f/16.f);
-                nexterr[col    ].g += err.g * (3.f/16.f);
-                nexterr[col    ].b += err.b * (3.f/16.f);
-
-            } else {
-                thiserr[col    ].a += err.a * (7.f/16.f);
-                thiserr[col    ].r += err.r * (7.f/16.f);
-                thiserr[col    ].g += err.g * (7.f/16.f);
-                thiserr[col    ].b += err.b * (7.f/16.f);
-
-                nexterr[col    ].a  = err.a * (1.f/16.f);
-                nexterr[col    ].r  = err.r * (1.f/16.f);
-                nexterr[col    ].g  = err.g * (1.f/16.f);
-                nexterr[col    ].b  = err.b * (1.f/16.f);
-
-                nexterr[col + 1].a += err.a * (5.f/16.f);
-                nexterr[col + 1].r += err.r * (5.f/16.f);
-                nexterr[col + 1].g += err.g * (5.f/16.f);
-                nexterr[col + 1].b += err.b * (5.f/16.f);
-
-                nexterr[col + 2].a += err.a * (3.f/16.f);
-                nexterr[col + 2].r += err.r * (3.f/16.f);
-                nexterr[col + 2].g += err.g * (3.f/16.f);
-                nexterr[col + 2].b += err.b * (3.f/16.f);
-            }
-
-            // remapping is done in zig-zag
-            if (fs_direction) {
-                ++col;
-                if (col >= cols) break;
-            } else {
-                if (col <= 0) break;
-                --col;
-            }
-        } while(1);
-
-        f_pixel *const temperr = thiserr;
-        thiserr = nexterr;
-        nexterr = temperr;
-        fs_direction = !fs_direction;
-    }
-
-    input_image->free(MIN(thiserr, nexterr)); // MIN because pointers were swapped
-    nearest_free(n);
-}
-
-/* fixed colors are always included in the palette, so it would be wasteful to duplicate them in palette from histogram */
-LIQ_NONNULL static void remove_fixed_colors_from_histogram(histogram *hist, const liq_image *input_image, const float target_mse)
-{
-    const float max_difference = MAX(target_mse/2.0, 2.0/256.0/256.0);
-    if (input_image->fixed_colors_count) {
-        for(int j=0; j < hist->size; j++) {
-            for(unsigned int i=0; i < input_image->fixed_colors_count; i++) {
-                if (colordifference(hist->achv[j].acolor, input_image->fixed_colors[i]) < max_difference) {
-                    hist->achv[j] = hist->achv[--hist->size]; // remove color from histogram by overwriting with the last entry
-                    j--; break; // continue searching histogram
-                }
-            }
-        }
-    }
-}
-
-/* histogram contains information how many times each color is present in the image, weighted by importance_map */
-LIQ_NONNULL static histogram *get_histogram(liq_image *input_image, const liq_attr *options)
-{
-    unsigned int ignorebits=MAX(options->min_posterization_output, options->min_posterization_input);
-    const unsigned int cols = input_image->width, rows = input_image->height;
-
-    if (!input_image->noise && options->use_contrast_maps) {
-        contrast_maps(input_image);
-    }
-
-   /*
-    ** Step 2: attempt to make a histogram of the colors, unclustered.
-    ** If at first we don't succeed, increase ignorebits to increase color
-    ** coherence and try again.
-    */
-
-    unsigned int maxcolors = options->max_histogram_entries;
-
-    struct acolorhash_table *acht;
-    const bool all_rows_at_once = liq_image_can_use_rows(input_image);
-    do {
-        acht = pam_allocacolorhash(maxcolors, rows*cols, ignorebits, options->malloc, options->free);
-        if (!acht) return NULL;
-
-        // histogram uses noise contrast map for importance. Color accuracy in noisy areas is not very important.
-        // noise map does not include edges to avoid ruining anti-aliasing
-        for(unsigned int row=0; row < rows; row++) {
-            bool added_ok;
-            if (all_rows_at_once) {
-                added_ok = pam_computeacolorhash(acht, (const rgba_pixel *const *)input_image->rows, cols, rows, input_image->noise);
-                if (added_ok) break;
-            } else {
-                const rgba_pixel* rows_p[1] = { liq_image_get_row_rgba(input_image, row) };
-                added_ok = pam_computeacolorhash(acht, rows_p, cols, 1, input_image->noise ? &input_image->noise[row * cols] : NULL);
-            }
-            if (!added_ok) {
-                ignorebits++;
-                liq_verbose_printf(options, "  too many colors! Scaling colors to improve clustering... %d", ignorebits);
-                pam_freeacolorhash(acht);
-                acht = NULL;
-                break;
-            }
-        }
-    } while(!acht);
-
-    if (input_image->noise) {
-        input_image->free(input_image->noise);
-        input_image->noise = NULL;
-    }
-
-    if (input_image->free_pixels && input_image->f_pixels) {
-        liq_image_free_rgba_source(input_image); // bow can free the RGBA source if copy has been made in f_pixels
-    }
-
-    histogram *hist = pam_acolorhashtoacolorhist(acht, input_image->gamma, options->malloc, options->free);
-    pam_freeacolorhash(acht);
-    if (hist) {
-        liq_verbose_printf(options, "  made histogram...%d colors found", hist->size);
-        remove_fixed_colors_from_histogram(hist, input_image, options->target_mse);
-    }
-
-    return hist;
-}
-
-LIQ_NONNULL static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels)
-{
-    /* IE6 makes colors with even slightest transparency completely transparent,
-       thus to improve situation in IE, make colors that are less than ~10% transparent
-       completely opaque */
-
-    const float min_opaque_val = input_image->min_opaque_val;
-    const float almost_opaque_val = min_opaque_val * 169.f/256.f;
-    const unsigned int almost_opaque_val_int = (min_opaque_val * 169.f/256.f)*255.f;
-
-    for(unsigned int col = 0; col < input_image->width; col++) {
-        const rgba_pixel px = row_pixels[col];
-
-        /* ie bug: to avoid visible step caused by forced opaqueness, linearily raise opaqueness of almost-opaque colors */
-        if (px.a >= almost_opaque_val_int) {
-            float al = px.a / 255.f;
-            al = almost_opaque_val + (al-almost_opaque_val) * (1.f-almost_opaque_val) / (min_opaque_val-almost_opaque_val);
-            al *= 256.f;
-            row_pixels[col].a = al >= 255.f ? 255 : al;
-        }
-    }
-}
-
-/**
- Builds two maps:
-    noise - approximation of areas with high-frequency noise, except straight edges. 1=flat, 0=noisy.
-    edges - noise map including all edges
- */
-LIQ_NONNULL static void contrast_maps(liq_image *image)
-{
-    const unsigned int cols = image->width, rows = image->height;
-    if (cols < 4 || rows < 4 || (3*cols*rows) > LIQ_HIGH_MEMORY_LIMIT) {
-        return;
-    }
-
-    unsigned char *restrict noise = image->malloc(cols*rows);
-    unsigned char *restrict edges = image->malloc(cols*rows);
-    unsigned char *restrict tmp = image->malloc(cols*rows);
-
-    if (!noise || !edges || !tmp) {
-        image->free(noise);
-        image->free(edges);
-        image->free(tmp);
-        return;
-    }
-
-    const f_pixel *curr_row, *prev_row, *next_row;
-    curr_row = prev_row = next_row = liq_image_get_row_f(image, 0);
-
-    for (unsigned int j=0; j < rows; j++) {
-        prev_row = curr_row;
-        curr_row = next_row;
-        next_row = liq_image_get_row_f(image, MIN(rows-1,j+1));
-
-        f_pixel prev, curr = curr_row[0], next=curr;
-        for (unsigned int i=0; i < cols; i++) {
-            prev=curr;
-            curr=next;
-            next = curr_row[MIN(cols-1,i+1)];
-
-            // contrast is difference between pixels neighbouring horizontally and vertically
-            const float a = fabsf(prev.a+next.a - curr.a*2.f),
-                        r = fabsf(prev.r+next.r - curr.r*2.f),
-                        g = fabsf(prev.g+next.g - curr.g*2.f),
-                        b = fabsf(prev.b+next.b - curr.b*2.f);
-
-            const f_pixel prevl = prev_row[i];
-            const f_pixel nextl = next_row[i];
-
-            const float a1 = fabsf(prevl.a+nextl.a - curr.a*2.f),
-                        r1 = fabsf(prevl.r+nextl.r - curr.r*2.f),
-                        g1 = fabsf(prevl.g+nextl.g - curr.g*2.f),
-                        b1 = fabsf(prevl.b+nextl.b - curr.b*2.f);
-
-            const float horiz = MAX(MAX(a,r),MAX(g,b));
-            const float vert = MAX(MAX(a1,r1),MAX(g1,b1));
-            const float edge = MAX(horiz,vert);
-            float z = edge - fabsf(horiz-vert)*.5f;
-            z = 1.f - MAX(z,MIN(horiz,vert));
-            z *= z; // noise is amplified
-            z *= z;
-
-            z *= 256.f;
-            noise[j*cols+i] = z < 256 ? z : 255;
-            z = (1.f-edge)*256.f;
-            edges[j*cols+i] = z < 256 ? z : 255;
-        }
-    }
-
-    // noise areas are shrunk and then expanded to remove thin edges from the map
-    liq_max3(noise, tmp, cols, rows);
-    liq_max3(tmp, noise, cols, rows);
-
-    liq_blur(noise, tmp, noise, cols, rows, 3);
-
-    liq_max3(noise, tmp, cols, rows);
-
-    liq_min3(tmp, noise, cols, rows);
-    liq_min3(noise, tmp, cols, rows);
-    liq_min3(tmp, noise, cols, rows);
-
-    liq_min3(edges, tmp, cols, rows);
-    liq_max3(tmp, edges, cols, rows);
-    for(unsigned int i=0; i < cols*rows; i++) edges[i] = MIN(noise[i], edges[i]);
-
-    image->free(tmp);
-
-    image->noise = noise;
-    image->edges = edges;
-}
-
-/**
- * Builds map of neighbor pixels mapped to the same palette entry
- *
- * For efficiency/simplicity it mainly looks for same consecutive pixels horizontally
- * and peeks 1 pixel above/below. Full 2d algorithm doesn't improve it significantly.
- * Correct flood fill doesn't have visually good properties.
- */
-LIQ_NONNULL static void update_dither_map(unsigned char *const *const row_pointers, liq_image *input_image)
-{
-    const unsigned int width = input_image->width;
-    const unsigned int height = input_image->height;
-    unsigned char *const edges = input_image->edges;
-
-    for(unsigned int row=0; row < height; row++) {
-        unsigned char lastpixel = row_pointers[row][0];
-        unsigned int lastcol=0;
-
-        for(unsigned int col=1; col < width; col++) {
-            const unsigned char px = row_pointers[row][col];
-
-            if (px != lastpixel || col == width-1) {
-                float neighbor_count = 2.5f + col-lastcol;
-
-                unsigned int i=lastcol;
-                while(i < col) {
-                    if (row > 0) {
-                        unsigned char pixelabove = row_pointers[row-1][i];
-                        if (pixelabove == lastpixel) neighbor_count += 1.f;
-                    }
-                    if (row < height-1) {
-                        unsigned char pixelbelow = row_pointers[row+1][i];
-                        if (pixelbelow == lastpixel) neighbor_count += 1.f;
-                    }
-                    i++;
-                }
-
-                while(lastcol <= col) {
-                    float e = edges[row*width + lastcol] / 255.f;
-                    e *= 1.f - 2.5f/neighbor_count;
-                    edges[row*width + lastcol++] = e * 255.f;
-                }
-                lastpixel = px;
-            }
-        }
-    }
-    input_image->dither_map = input_image->edges;
-    input_image->edges = NULL;
-}
-
-/**
- * Palette can be NULL, in which case it creates a new palette from scratch.
- */
-static colormap *add_fixed_colors_to_palette(colormap *palette, const int max_colors, const f_pixel fixed_colors[], const int fixed_colors_count, void* (*malloc)(size_t), void (*free)(void*))
-{
-    if (!fixed_colors_count) return palette;
-
-    colormap *newpal = pam_colormap(MIN(max_colors, (palette ? palette->colors : 0) + fixed_colors_count), malloc, free);
-    unsigned int i=0;
-    if (palette && fixed_colors_count < max_colors) {
-        unsigned int palette_max = MIN(palette->colors, max_colors - fixed_colors_count);
-        for(; i < palette_max; i++) {
-            newpal->palette[i] = palette->palette[i];
-        }
-    }
-    for(int j=0; j < MIN(max_colors, fixed_colors_count); j++) {
-        newpal->palette[i++] = (colormap_item){
-            .acolor = fixed_colors[j],
-            .fixed = true,
-        };
-    }
-    if (palette) pam_freecolormap(palette);
-    return newpal;
-}
-
-LIQ_NONNULL static void adjust_histogram_callback(hist_item *item, float diff)
-{
-    item->adjusted_weight = (item->perceptual_weight+item->adjusted_weight) * (sqrtf(1.f+diff));
-}
-
-/**
- Repeats mediancut with different histogram weights to find palette with minimum error.
-
- feedback_loop_trials controls how long the search will take. < 0 skips the iteration.
- */
-static colormap *find_best_palette(histogram *hist, const liq_attr *options, const double max_mse, const f_pixel fixed_colors[], const unsigned int fixed_colors_count, double *palette_error_p)
-{
-    unsigned int max_colors = options->max_colors;
-
-    // if output is posterized it doesn't make sense to aim for perfrect colors, so increase target_mse
-    // at this point actual gamma is not set, so very conservative posterization estimate is used
-    const double target_mse = MIN(max_mse, MAX(options->target_mse, pow((1<<options->min_posterization_output)/1024.0, 2)));
-    int feedback_loop_trials = options->feedback_loop_trials;
-    colormap *acolormap = NULL;
-    double least_error = MAX_DIFF;
-    double target_mse_overshoot = feedback_loop_trials>0 ? 1.05 : 1.0;
-    const double percent = (double)(feedback_loop_trials>0?feedback_loop_trials:1)/100.0;
-
-    do {
-        colormap *newmap;
-        if (hist->size && fixed_colors_count < max_colors) {
-            newmap = mediancut(hist, max_colors-fixed_colors_count, target_mse * target_mse_overshoot, MAX(MAX(90.0/65536.0, target_mse), least_error)*1.2,
-            options->malloc, options->free);
-        } else {
-            feedback_loop_trials = 0;
-            newmap = NULL;
-        }
-        newmap = add_fixed_colors_to_palette(newmap, max_colors, fixed_colors, fixed_colors_count, options->malloc, options->free);
-        if (!newmap) {
-            return NULL;
-        }
-
-        if (feedback_loop_trials <= 0) {
-            return newmap;
-        }
-
-        // after palette has been created, total error (MSE) is calculated to keep the best palette
-        // at the same time Voronoi iteration is done to improve the palette
-        // and histogram weights are adjusted based on remapping error to give more weight to poorly matched colors
-
-        const bool first_run_of_target_mse = !acolormap && target_mse > 0;
-        double total_error = viter_do_iteration(hist, newmap, first_run_of_target_mse ? NULL : adjust_histogram_callback, !acolormap || options->fast_palette);
-
-        // goal is to increase quality or to reduce number of colors used if quality is good enough
-        if (!acolormap || total_error < least_error || (total_error <= target_mse && newmap->colors < max_colors)) {
-            if (acolormap) pam_freecolormap(acolormap);
-            acolormap = newmap;
-
-            if (total_error < target_mse && total_error > 0) {
-                // voronoi iteration improves quality above what mediancut aims for
-                // this compensates for it, making mediancut aim for worse
-                target_mse_overshoot = MIN(target_mse_overshoot*1.25, target_mse/total_error);
-            }
-
-            least_error = total_error;
-
-            // if number of colors could be reduced, try to keep it that way
-            // but allow extra color as a bit of wiggle room in case quality can be improved too
-            max_colors = MIN(newmap->colors+1, max_colors);
-
-            feedback_loop_trials -= 1; // asymptotic improvement could make it go on forever
-        } else {
-            for(unsigned int j=0; j < hist->size; j++) {
-                hist->achv[j].adjusted_weight = (hist->achv[j].perceptual_weight + hist->achv[j].adjusted_weight)/2.0;
-            }
-
-            target_mse_overshoot = 1.0;
-            feedback_loop_trials -= 6;
-            // if error is really bad, it's unlikely to improve, so end sooner
-            if (total_error > least_error*4) feedback_loop_trials -= 3;
-            pam_freecolormap(newmap);
-        }
-
-        liq_verbose_printf(options, "  selecting colors...%d%%",100-MAX(0,(int)(feedback_loop_trials/percent)));
-    }
-    while(feedback_loop_trials > 0);
-
-    *palette_error_p = least_error;
-    return acolormap;
-}
-
-static colormap *histogram_to_palette(const histogram *hist, const liq_attr *options) {
-    if (!hist->size) {
-        return NULL;
-    }
-    colormap *acolormap = pam_colormap(hist->size, options->malloc, options->free);
-    for(unsigned int i=0; i < hist->size; i++) {
-        acolormap->palette[i].acolor = hist->achv[i].acolor;
-        acolormap->palette[i].popularity = hist->achv[i].perceptual_weight;
-    }
-    return acolormap;
-}
-
-LIQ_NONNULL static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, const liq_image *img)
-{
-    colormap *acolormap;
-    double palette_error = -1;
-
-    // no point having perfect match with imperfect colors (ignorebits > 0)
-    const bool fast_palette = options->fast_palette || hist->ignorebits > 0;
-    const bool few_input_colors = hist->size+img->fixed_colors_count <= options->max_colors;
-
-    // If image has few colors to begin with (and no quality degradation is required)
-    // then it's possible to skip quantization entirely
-    if (few_input_colors && options->target_mse == 0) {
-        acolormap = add_fixed_colors_to_palette(histogram_to_palette(hist, options), options->max_colors, img->fixed_colors, img->fixed_colors_count, options->malloc, options->free);
-        palette_error = 0;
-    } else {
-        const double max_mse = options->max_mse * (few_input_colors ? 0.33 : 1.0); // when degrading image that's already paletted, require much higher improvement, since pal2pal often looks bad and there's little gain
-        acolormap = find_best_palette(hist, options, max_mse, img->fixed_colors, img->fixed_colors_count, &palette_error);
-        if (!acolormap) {
-            return NULL;
-        }
-
-        // Voronoi iteration approaches local minimum for the palette
-        const double iteration_limit = options->voronoi_iteration_limit;
-        unsigned int iterations = options->voronoi_iterations;
-
-        if (!iterations && palette_error < 0 && max_mse < MAX_DIFF) iterations = 1; // otherwise total error is never calculated and MSE limit won't work
-
-        if (iterations) {
-            // likely_colormap_index (used and set in viter_do_iteration) can't point to index outside colormap
-            if (acolormap->colors < 256) for(unsigned int j=0; j < hist->size; j++) {
-                if (hist->achv[j].tmp.likely_colormap_index >= acolormap->colors) {
-                    hist->achv[j].tmp.likely_colormap_index = 0; // actual value doesn't matter, as the guess is out of date anyway
-                }
-            }
-
-            verbose_print(options, "  moving colormap towards local minimum");
-
-            double previous_palette_error = MAX_DIFF;
-
-            for(unsigned int i=0; i < iterations; i++) {
-                palette_error = viter_do_iteration(hist, acolormap, NULL, i==0 || options->fast_palette);
-
-                if (fabs(previous_palette_error-palette_error) < iteration_limit) {
-                    break;
-                }
-
-                if (palette_error > max_mse*1.5) { // probably hopeless
-                    if (palette_error > max_mse*3.0) break; // definitely hopeless
-                    i++;
-                }
-
-                previous_palette_error = palette_error;
-            }
-        }
-
-        if (palette_error > max_mse) {
-            liq_verbose_printf(options, "  image degradation MSE=%.3f (Q=%d) exceeded limit of %.3f (%d)",
-                               mse_to_standard_mse(palette_error), mse_to_quality(palette_error),
-                               mse_to_standard_mse(max_mse), mse_to_quality(max_mse));
-            pam_freecolormap(acolormap);
-            return NULL;
-        }
-    }
-
-    sort_palette(acolormap, options);
-
-    liq_result *result = options->malloc(sizeof(liq_result));
-    if (!result) return NULL;
-    *result = (liq_result){
-        .magic_header = liq_result_magic,
-        .malloc = options->malloc,
-        .free = options->free,
-        .palette = acolormap,
-        .palette_error = palette_error,
-        .fast_palette = fast_palette,
-        .use_dither_map = options->use_dither_map,
-        .gamma = img->gamma,
-        .min_posterization_output = options->min_posterization_output,
-    };
-    return result;
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size)
-{
-    if (!CHECK_STRUCT_TYPE(result, liq_result)) {
-        return LIQ_INVALID_POINTER;
-    }
-    if (!CHECK_STRUCT_TYPE(input_image, liq_image)) {
-        return LIQ_INVALID_POINTER;
-    }
-    if (!CHECK_USER_POINTER(buffer)) {
-        return LIQ_INVALID_POINTER;
-    }
-
-    const size_t required_size = input_image->width * input_image->height;
-    if (buffer_size < required_size) {
-        return LIQ_BUFFER_TOO_SMALL;
-    }
-
-    unsigned char *rows[input_image->height];
-    unsigned char *buffer_bytes = buffer;
-    for(unsigned int i=0; i < input_image->height; i++) {
-        rows[i] = &buffer_bytes[input_image->width * i];
-    }
-    return liq_write_remapped_image_rows(result, input_image, rows);
-}
-
-LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image_rows(liq_result *quant, liq_image *input_image, unsigned char **row_pointers)
-{
-    if (!CHECK_STRUCT_TYPE(quant, liq_result)) return LIQ_INVALID_POINTER;
-    if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return LIQ_INVALID_POINTER;
-    for(unsigned int i=0; i < input_image->height; i++) {
-        if (!CHECK_USER_POINTER(row_pointers+i) || !CHECK_USER_POINTER(row_pointers[i])) return LIQ_INVALID_POINTER;
-    }
-
-    if (quant->remapping) {
-        liq_remapping_result_destroy(quant->remapping);
-    }
-    liq_remapping_result *const result = quant->remapping = liq_remapping_result_create(quant);
-    if (!result) return LIQ_OUT_OF_MEMORY;
-
-    if (!input_image->edges && !input_image->dither_map && quant->use_dither_map) {
-        contrast_maps(input_image);
-    }
-
-    /*
-     ** Step 4: map the colors in the image to their closest match in the
-     ** new colormap, and write 'em out.
-     */
-
-    float remapping_error = result->palette_error;
-    if (result->dither_level == 0) {
-        set_rounded_palette(&result->int_palette, result->palette, result->gamma, quant->min_posterization_output);
-        remapping_error = remap_to_palette(input_image, row_pointers, result->palette, quant->fast_palette);
-    } else {
-        const bool generate_dither_map = result->use_dither_map && (input_image->edges && !input_image->dither_map);
-        if (generate_dither_map) {
-            // If dithering (with dither map) is required, this image is used to find areas that require dithering
-            remapping_error = remap_to_palette(input_image, row_pointers, result->palette, quant->fast_palette);
-            update_dither_map(row_pointers, input_image);
-        }
-
-        // remapping above was the last chance to do voronoi iteration, hence the final palette is set after remapping
-        set_rounded_palette(&result->int_palette, result->palette, result->gamma, quant->min_posterization_output);
-
-        remap_to_palette_floyd(input_image, row_pointers, result->palette,
-            MAX(remapping_error*2.4, 16.f/256.f), result->use_dither_map, generate_dither_map, result->dither_level);
-    }
-
-    // remapping error from dithered image is absurd, so always non-dithered value is used
-    // palette_error includes some perceptual weighting from histogram which is closer correlated with dssim
-    // so that should be used when possible.
-    if (result->palette_error < 0) {
-        result->palette_error = remapping_error;
-    }
-
-    return LIQ_OK;
-}
-
-LIQ_EXPORT int liq_version() {
-    return LIQ_VERSION;
-}
diff --git a/src/drivers/libimagequant/libimagequant.h b/src/drivers/libimagequant/libimagequant.h
deleted file mode 100644
index 014604c..0000000
--- a/src/drivers/libimagequant/libimagequant.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * http://pngquant.org
- */
-
-#ifndef LIBIMAGEQUANT_H
-#define LIBIMAGEQUANT_H
-
-#ifndef LIQ_EXPORT
-#define LIQ_EXPORT extern
-#endif
-
-#define LIQ_VERSION 20502
-#define LIQ_VERSION_STRING "2.5.2"
-
-#ifndef LIQ_PRIVATE
-#if defined(__GNUC__) || defined (__llvm__)
-#define LIQ_PRIVATE __attribute__((visibility("hidden")))
-#define LIQ_NONNULL __attribute__((nonnull))
-#define LIQ_USERESULT __attribute__((warn_unused_result))
-#else
-#define LIQ_PRIVATE
-#define LIQ_NONNULL
-#define LIQ_USERESULT
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-typedef struct liq_attr liq_attr;
-typedef struct liq_image liq_image;
-typedef struct liq_result liq_result;
-
-typedef struct liq_color {
-    unsigned char r, g, b, a;
-} liq_color;
-
-typedef struct liq_palette {
-    unsigned int count;
-    liq_color entries[256];
-} liq_palette;
-
-typedef enum liq_error {
-    LIQ_OK = 0,
-    LIQ_QUALITY_TOO_LOW = 99,
-    LIQ_VALUE_OUT_OF_RANGE = 100,
-    LIQ_OUT_OF_MEMORY,
-    LIQ_NOT_READY,
-    LIQ_BITMAP_NOT_AVAILABLE,
-    LIQ_BUFFER_TOO_SMALL,
-    LIQ_INVALID_POINTER,
-} liq_error;
-
-enum liq_ownership {LIQ_OWN_ROWS=4, LIQ_OWN_PIXELS=8};
-
-LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create(void);
-LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
-LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_copy(liq_attr *orig) LIQ_NONNULL;
-LIQ_EXPORT void liq_attr_destroy(liq_attr *attr) LIQ_NONNULL;
-
-LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_max_colors(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_speed(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_min_opacity(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr* attr, int bits) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_min_posterization(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_min_quality(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_get_max_quality(const liq_attr* attr) LIQ_NONNULL;
-LIQ_EXPORT void liq_set_last_index_transparent(liq_attr* attr, int is_last) LIQ_NONNULL;
-
-typedef void liq_log_callback_function(const liq_attr*, const char *message, void* user_info);
-typedef void liq_log_flush_callback_function(const liq_attr*, void* user_info);
-LIQ_EXPORT void liq_set_log_callback(liq_attr*, liq_log_callback_function*, void* user_info);
-LIQ_EXPORT void liq_set_log_flush_callback(liq_attr*, liq_log_flush_callback_function*, void* user_info);
-
-LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba_rows(liq_attr *attr, void* rows[], int width, int height, double gamma) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma) LIQ_NONNULL;
-
-typedef void liq_image_get_rgba_row_callback(liq_color row_out[], int row, int width, void* user_info);
-LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_custom(liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void* user_info, int width, int height, double gamma);
-
-LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image *image, int ownership_flags) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_image_add_fixed_color(liq_image *img, liq_color color) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_image_get_width(const liq_image *img) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT int liq_image_get_height(const liq_image *img) LIQ_NONNULL;
-LIQ_EXPORT void liq_image_destroy(liq_image *img) LIQ_NONNULL;
-
-LIQ_EXPORT LIQ_USERESULT liq_result *liq_quantize_image(liq_attr *options, liq_image *input_image) LIQ_NONNULL;
-
-LIQ_EXPORT liq_error liq_set_dithering_level(liq_result *res, float dither_level) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma) LIQ_NONNULL;
-LIQ_EXPORT LIQ_USERESULT double liq_get_output_gamma(const liq_result *result) LIQ_NONNULL;
-
-LIQ_EXPORT LIQ_USERESULT const liq_palette *liq_get_palette(liq_result *result) LIQ_NONNULL;
-
-LIQ_EXPORT liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_write_remapped_image_rows(liq_result *result, liq_image *input_image, unsigned char **row_pointers) LIQ_NONNULL;
-
-LIQ_EXPORT double liq_get_quantization_error(liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT int liq_get_quantization_quality(liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT double liq_get_remapping_error(liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT int liq_get_remapping_quality(liq_result *result) LIQ_NONNULL;
-
-LIQ_EXPORT void liq_result_destroy(liq_result *) LIQ_NONNULL;
-
-LIQ_EXPORT int liq_version(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/drivers/libimagequant/mediancut.c b/src/drivers/libimagequant/mediancut.c
deleted file mode 100644
index 3fae039..0000000
--- a/src/drivers/libimagequant/mediancut.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
-** Copyright (C) 1989, 1991 by Jef Poskanzer.
-** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
-**                                Stefan Schneider.
-** © 2009-2015 by Kornel Lesinski.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-*/
-
-#include <stdlib.h>
-#include <stddef.h>
-
-#include "libimagequant.h"
-#include "pam.h"
-#include "mediancut.h"
-
-#define index_of_channel(ch) (offsetof(f_pixel,ch)/sizeof(float))
-
-static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], const f_pixel center);
-
-struct box {
-    f_pixel color;
-    f_pixel variance;
-    double sum, total_error, max_error;
-    unsigned int ind;
-    unsigned int colors;
-};
-
-ALWAYS_INLINE static double variance_diff(double val, const double good_enough);
-inline static double variance_diff(double val, const double good_enough)
-{
-    val *= val;
-    if (val < good_enough*good_enough) return val*0.25;
-    return val;
-}
-
-/** Weighted per-channel variance of the box. It's used to decide which channel to split by */
-static f_pixel box_variance(const hist_item achv[], const struct box *box)
-{
-    f_pixel mean = box->color;
-    double variancea=0, variancer=0, varianceg=0, varianceb=0;
-
-    for(unsigned int i = 0; i < box->colors; ++i) {
-        f_pixel px = achv[box->ind + i].acolor;
-        double weight = achv[box->ind + i].adjusted_weight;
-        variancea += variance_diff(mean.a - px.a, 2.0/256.0)*weight;
-        variancer += variance_diff(mean.r - px.r, 1.0/256.0)*weight;
-        varianceg += variance_diff(mean.g - px.g, 1.0/256.0)*weight;
-        varianceb += variance_diff(mean.b - px.b, 1.0/256.0)*weight;
-    }
-
-    return (f_pixel){
-        .a = variancea*(4.0/16.0),
-        .r = variancer*(7.0/16.0),
-        .g = varianceg*(9.0/16.0),
-        .b = varianceb*(5.0/16.0),
-    };
-}
-
-static double box_max_error(const hist_item achv[], const struct box *box)
-{
-    f_pixel mean = box->color;
-    double max_error = 0;
-
-    for(unsigned int i = 0; i < box->colors; ++i) {
-        const double diff = colordifference(mean, achv[box->ind + i].acolor);
-        if (diff > max_error) {
-            max_error = diff;
-        }
-    }
-    return max_error;
-}
-
-ALWAYS_INLINE static double color_weight(f_pixel median, hist_item h);
-
-static inline void hist_item_swap(hist_item *l, hist_item *r)
-{
-    if (l != r) {
-        hist_item t = *l;
-        *l = *r;
-        *r = t;
-    }
-}
-
-ALWAYS_INLINE static unsigned int qsort_pivot(const hist_item *const base, const unsigned int len);
-inline static unsigned int qsort_pivot(const hist_item *const base, const unsigned int len)
-{
-    if (len < 32) {
-        return len/2;
-    }
-
-    const unsigned int aidx=8, bidx=len/2, cidx=len-1;
-    const unsigned int a=base[aidx].tmp.sort_value, b=base[bidx].tmp.sort_value, c=base[cidx].tmp.sort_value;
-    return (a < b) ? ((b < c) ? bidx : ((a < c) ? cidx : aidx ))
-                   : ((b > c) ? bidx : ((a < c) ? aidx : cidx ));
-}
-
-ALWAYS_INLINE static unsigned int qsort_partition(hist_item *const base, const unsigned int len);
-inline static unsigned int qsort_partition(hist_item *const base, const unsigned int len)
-{
-    unsigned int l = 1, r = len;
-    if (len >= 8) {
-        hist_item_swap(&base[0], &base[qsort_pivot(base,len)]);
-    }
-
-    const unsigned int pivot_value = base[0].tmp.sort_value;
-    while (l < r) {
-        if (base[l].tmp.sort_value >= pivot_value) {
-            l++;
-        } else {
-            while(l < --r && base[r].tmp.sort_value <= pivot_value) {}
-            hist_item_swap(&base[l], &base[r]);
-        }
-    }
-    l--;
-    hist_item_swap(&base[0], &base[l]);
-
-    return l;
-}
-
-/** quick select algorithm */
-static void hist_item_sort_range(hist_item *base, unsigned int len, unsigned int sort_start)
-{
-    for(;;) {
-        const unsigned int l = qsort_partition(base, len), r = l+1;
-
-        if (l > 0 && sort_start < l) {
-            len = l;
-        }
-        else if (r < len && sort_start > r) {
-            base += r; len -= r; sort_start -= r;
-        }
-        else break;
-    }
-}
-
-/** sorts array to make sum of weights lower than halfvar one side, returns edge between <halfvar and >halfvar parts of the set */
-static hist_item *hist_item_sort_halfvar(hist_item *base, unsigned int len, double *const lowervar, const double halfvar)
-{
-    do {
-        const unsigned int l = qsort_partition(base, len), r = l+1;
-
-        // check if sum of left side is smaller than half,
-        // if it is, then it doesn't need to be sorted
-        unsigned int t = 0; double tmpsum = *lowervar;
-        while (t <= l && tmpsum < halfvar) tmpsum += base[t++].color_weight;
-
-        if (tmpsum < halfvar) {
-            *lowervar = tmpsum;
-        } else {
-            if (l > 0) {
-                hist_item *res = hist_item_sort_halfvar(base, l, lowervar, halfvar);
-                if (res) return res;
-            } else {
-                // End of left recursion. This will be executed in order from the first element.
-                *lowervar += base[0].color_weight;
-                if (*lowervar > halfvar) return &base[0];
-            }
-        }
-
-        if (len > r) {
-            base += r; len -= r; // tail-recursive "call"
-        } else {
-            *lowervar += base[r].color_weight;
-            return (*lowervar > halfvar) ? &base[r] : NULL;
-        }
-    } while(1);
-}
-
-static f_pixel get_median(const struct box *b, hist_item achv[]);
-
-typedef struct {
-    unsigned int chan; float variance;
-} channelvariance;
-
-static int comparevariance(const void *ch1, const void *ch2)
-{
-    return ((const channelvariance*)ch1)->variance > ((const channelvariance*)ch2)->variance ? -1 :
-          (((const channelvariance*)ch1)->variance < ((const channelvariance*)ch2)->variance ? 1 : 0);
-}
-
-/** Finds which channels need to be sorted first and preproceses achv for fast sort */
-static double prepare_sort(struct box *b, hist_item achv[])
-{
-    /*
-     ** Sort dimensions by their variance, and then sort colors first by dimension with highest variance
-     */
-    channelvariance channels[4] = {
-        {index_of_channel(r), b->variance.r},
-        {index_of_channel(g), b->variance.g},
-        {index_of_channel(b), b->variance.b},
-        {index_of_channel(a), b->variance.a},
-    };
-
-    qsort(channels, 4, sizeof(channels[0]), comparevariance);
-
-    for(unsigned int i=0; i < b->colors; i++) {
-        const float *chans = (const float *)&achv[b->ind + i].acolor;
-        // Only the first channel really matters. When trying median cut many times
-        // with different histogram weights, I don't want sort randomness to influence outcome.
-        achv[b->ind + i].tmp.sort_value = ((unsigned int)(chans[channels[0].chan]*65535.0)<<16) |
-                                       (unsigned int)((chans[channels[2].chan] + chans[channels[1].chan]/2.0 + chans[channels[3].chan]/4.0)*65535.0);
-    }
-
-    const f_pixel median = get_median(b, achv);
-
-    // box will be split to make color_weight of each side even
-    const unsigned int ind = b->ind, end = ind+b->colors;
-    double totalvar = 0;
-    for(unsigned int j=ind; j < end; j++) totalvar += (achv[j].color_weight = color_weight(median, achv[j]));
-    return totalvar / 2.0;
-}
-
-/** finds median in unsorted set by sorting only minimum required */
-static f_pixel get_median(const struct box *b, hist_item achv[])
-{
-    const unsigned int median_start = (b->colors-1)/2;
-
-    hist_item_sort_range(&(achv[b->ind]), b->colors,
-                         median_start);
-
-    if (b->colors&1) return achv[b->ind + median_start].acolor;
-
-    // technically the second color is not guaranteed to be sorted correctly
-    // but most of the time it is good enough to be useful
-    return averagepixels(2, &achv[b->ind + median_start], (f_pixel){0.5,0.5,0.5,0.5});
-}
-
-/*
- ** Find the best splittable box. -1 if no boxes are splittable.
- */
-static int best_splittable_box(struct box* bv, unsigned int boxes, const double max_mse)
-{
-    int bi=-1; double maxsum=0;
-    for(unsigned int i=0; i < boxes; i++) {
-        if (bv[i].colors < 2) {
-            continue;
-        }
-
-        // looks only at max variance, because it's only going to split by it
-        const double cv = MAX(bv[i].variance.r, MAX(bv[i].variance.g,bv[i].variance.b));
-        double thissum = bv[i].sum * MAX(bv[i].variance.a, cv);
-
-        if (bv[i].max_error > max_mse) {
-            thissum = thissum* bv[i].max_error/max_mse;
-        }
-
-        if (thissum > maxsum) {
-            maxsum = thissum;
-            bi = i;
-        }
-    }
-    return bi;
-}
-
-inline static double color_weight(f_pixel median, hist_item h)
-{
-    float diff = colordifference(median, h.acolor);
-    // if color is "good enough", don't split further
-    if (diff < 2.f/256.f/256.f) diff /= 2.f;
-    return sqrt(diff) * (sqrt(1.0+h.adjusted_weight)-1.0);
-}
-
-static void set_colormap_from_boxes(colormap *map, struct box* bv, unsigned int boxes, hist_item *achv);
-static void adjust_histogram(hist_item *achv, const colormap *map, const struct box* bv, unsigned int boxes);
-
-static double box_error(const struct box *box, const hist_item achv[])
-{
-    f_pixel avg = box->color;
-
-    double total_error=0;
-    for (unsigned int i = 0; i < box->colors; ++i) {
-        total_error += colordifference(avg, achv[box->ind + i].acolor) * achv[box->ind + i].perceptual_weight;
-    }
-
-    return total_error;
-}
-
-
-static bool total_box_error_below_target(double target_mse, struct box bv[], unsigned int boxes, const histogram *hist)
-{
-    target_mse *= hist->total_perceptual_weight;
-    double total_error=0;
-
-    for(unsigned int i=0; i < boxes; i++) {
-        // error is (re)calculated lazily
-        if (bv[i].total_error >= 0) {
-            total_error += bv[i].total_error;
-        }
-        if (total_error > target_mse) return false;
-    }
-
-    for(unsigned int i=0; i < boxes; i++) {
-        if (bv[i].total_error < 0) {
-            bv[i].total_error = box_error(&bv[i], hist->achv);
-            total_error += bv[i].total_error;
-        }
-        if (total_error > target_mse) return false;
-    }
-
-    return true;
-}
-
-/*
- ** Here is the fun part, the median-cut colormap generator.  This is based
- ** on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer
- ** Display," SIGGRAPH 1982 Proceedings, page 297.
- */
-LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*))
-{
-    hist_item *achv = hist->achv;
-    struct box bv[newcolors];
-
-    /*
-     ** Set up the initial box.
-     */
-    bv[0].ind = 0;
-    bv[0].colors = hist->size;
-    bv[0].color = averagepixels(bv[0].colors, &achv[bv[0].ind], (f_pixel){0.5,0.5,0.5,0.5});
-    bv[0].variance = box_variance(achv, &bv[0]);
-    bv[0].max_error = box_max_error(achv, &bv[0]);
-    bv[0].sum = 0;
-    bv[0].total_error = -1;
-    for(unsigned int i=0; i < bv[0].colors; i++) bv[0].sum += achv[i].adjusted_weight;
-
-    unsigned int boxes = 1;
-
-    /*
-     ** Main loop: split boxes until we have enough.
-     */
-    while (boxes < newcolors) {
-
-        // first splits boxes that exceed quality limit (to have colors for things like odd green pixel),
-        // later raises the limit to allow large smooth areas/gradients get colors.
-        const double current_max_mse = max_mse + (boxes/(double)newcolors)*16.0*max_mse;
-        const int bi = best_splittable_box(bv, boxes, current_max_mse);
-        if (bi < 0)
-            break;        /* ran out of colors! */
-
-        unsigned int indx = bv[bi].ind;
-        unsigned int clrs = bv[bi].colors;
-
-        /*
-         Classic implementation tries to get even number of colors or pixels in each subdivision.
-
-         Here, instead of popularity I use (sqrt(popularity)*variance) metric.
-         Each subdivision balances number of pixels (popular colors) and low variance -
-         boxes can be large if they have similar colors. Later boxes with high variance
-         will be more likely to be split.
-
-         Median used as expected value gives much better results than mean.
-         */
-
-        const double halfvar = prepare_sort(&bv[bi], achv);
-        double lowervar=0;
-
-        // hist_item_sort_halfvar sorts and sums lowervar at the same time
-        // returns item to break at …minus one, which does smell like an off-by-one error.
-        hist_item *break_p = hist_item_sort_halfvar(&achv[indx], clrs, &lowervar, halfvar);
-        unsigned int break_at = MIN(clrs-1, break_p - &achv[indx] + 1);
-
-        /*
-         ** Split the box.
-         */
-        double sm = bv[bi].sum;
-        double lowersum = 0;
-        for(unsigned int i=0; i < break_at; i++) lowersum += achv[indx + i].adjusted_weight;
-
-        const f_pixel previous_center = bv[bi].color;
-        bv[bi].colors = break_at;
-        bv[bi].sum = lowersum;
-        bv[bi].color = averagepixels(bv[bi].colors, &achv[bv[bi].ind], previous_center);
-        bv[bi].total_error = -1;
-        bv[bi].variance = box_variance(achv, &bv[bi]);
-        bv[bi].max_error = box_max_error(achv, &bv[bi]);
-        bv[boxes].ind = indx + break_at;
-        bv[boxes].colors = clrs - break_at;
-        bv[boxes].sum = sm - lowersum;
-        bv[boxes].color = averagepixels(bv[boxes].colors, &achv[bv[boxes].ind], previous_center);
-        bv[boxes].total_error = -1;
-        bv[boxes].variance = box_variance(achv, &bv[boxes]);
-        bv[boxes].max_error = box_max_error(achv, &bv[boxes]);
-
-        ++boxes;
-
-        if (total_box_error_below_target(target_mse, bv, boxes, hist)) {
-            break;
-        }
-    }
-
-    colormap *map = pam_colormap(boxes, malloc, free);
-    set_colormap_from_boxes(map, bv, boxes, achv);
-
-    adjust_histogram(achv, map, bv, boxes);
-
-    return map;
-}
-
-static void set_colormap_from_boxes(colormap *map, struct box* bv, unsigned int boxes, hist_item *achv)
-{
-    /*
-     ** Ok, we've got enough boxes.  Now choose a representative color for
-     ** each box.  There are a number of possible ways to make this choice.
-     ** One would be to choose the center of the box; this ignores any structure
-     ** within the boxes.  Another method would be to average all the colors in
-     ** the box - this is the method specified in Heckbert's paper.
-     */
-
-    for(unsigned int bi = 0; bi < boxes; ++bi) {
-        map->palette[bi].acolor = bv[bi].color;
-
-        /* store total color popularity (perceptual_weight is approximation of it) */
-        map->palette[bi].popularity = 0;
-        for(unsigned int i=bv[bi].ind; i < bv[bi].ind+bv[bi].colors; i++) {
-            map->palette[bi].popularity += achv[i].perceptual_weight;
-        }
-    }
-}
-
-/* increase histogram popularity by difference from the final color (this is used as part of feedback loop) */
-static void adjust_histogram(hist_item *achv, const colormap *map, const struct box* bv, unsigned int boxes)
-{
-    for(unsigned int bi = 0; bi < boxes; ++bi) {
-        for(unsigned int i=bv[bi].ind; i < bv[bi].ind+bv[bi].colors; i++) {
-            achv[i].adjusted_weight *= sqrt(1.0 +colordifference(map->palette[bi].acolor, achv[i].acolor)/4.0);
-            achv[i].tmp.likely_colormap_index = bi;
-        }
-    }
-}
-
-inline static f_pixel setalpha(f_pixel px, float new_a) {
-    if (px.a) {
-        px.r /= px.a;
-        px.g /= px.a;
-        px.b /= px.a;
-    }
-
-    px.r *= new_a;
-    px.g *= new_a;
-    px.b *= new_a;
-    px.a = new_a;
-
-    return px;
-}
-
-static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], f_pixel center)
-{
-    double r = 0, g = 0, b = 0, a = 0, new_a=0, sum = 0;
-    float maxa = 0;
-
-    // first find final opacity in order to blend colors at that opacity
-    for(unsigned int i = 0; i < clrs; ++i) {
-        const f_pixel px = achv[i].acolor;
-        new_a += px.a * achv[i].adjusted_weight;
-        sum += achv[i].adjusted_weight;
-
-        /* find if there are opaque colors, in case we're supposed to preserve opacity exactly (ie_bug) */
-        if (px.a > maxa) maxa = px.a;
-    }
-
-    if (sum) new_a /= sum;
-
-    center = setalpha(center, new_a);
-
-    sum=0;
-    // reverse iteration for cache locality with previous loop
-    for(int i = clrs-1; i >= 0; i--) {
-        double tmp, weight = 1.0f;
-        f_pixel px = setalpha(achv[i].acolor, new_a);
-
-        /* give more weight to colors that are further away from average
-         this is intended to prevent desaturation of images and fading of whites
-         */
-        tmp = (center.r - px.r);
-        weight += tmp*tmp;
-        tmp = (center.g - px.g);
-        weight += tmp*tmp;
-        tmp = (center.b - px.b);
-        weight += tmp*tmp;
-        tmp = (center.a - px.a);
-        weight += tmp*tmp;
-
-        weight *= achv[i].adjusted_weight;
-        sum += weight;
-
-        r += px.r * weight;
-        g += px.g * weight;
-        b += px.b * weight;
-        a += px.a * weight;
-    }
-
-    if (sum) {
-        a /= sum;
-        r /= sum;
-        g /= sum;
-        b /= sum;
-    }
-
-    assert(!isnan(r) && !isnan(g) && !isnan(b) && !isnan(a));
-
-    return (f_pixel){.r=r, .g=g, .b=b, .a=a};
-}
diff --git a/src/drivers/libimagequant/mediancut.h b/src/drivers/libimagequant/mediancut.h
deleted file mode 100644
index d97696c..0000000
--- a/src/drivers/libimagequant/mediancut.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*));
diff --git a/src/drivers/libimagequant/mempool.c b/src/drivers/libimagequant/mempool.c
deleted file mode 100644
index 4bf7d2a..0000000
--- a/src/drivers/libimagequant/mempool.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-** © 2011-2015 by Kornel Lesiński.
-** All rights reserved.
-** See COPYRIGHT file for full license.
-*/
-
-#include "libimagequant.h"
-#include "mempool.h"
-#include <stdlib.h>
-#include <stdint.h>
-#include <assert.h>
-
-#define ALIGN_MASK 15UL
-#define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
-
-struct mempool {
-    unsigned int used, size;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-    struct mempool *next;
-};
-LIQ_PRIVATE void* mempool_create(mempool *mptr, const unsigned int size, unsigned int max_size, void* (*malloc)(size_t), void (*free)(void*))
-{
-    if (*mptr && ((*mptr)->used+size) <= (*mptr)->size) {
-        unsigned int prevused = (*mptr)->used;
-        (*mptr)->used += (size+15UL) & ~0xFUL;
-        return ((char*)(*mptr)) + prevused;
-    }
-
-    mempool old = *mptr;
-    if (!max_size) max_size = (1<<17);
-    max_size = size+ALIGN_MASK > max_size ? size+ALIGN_MASK : max_size;
-
-    *mptr = malloc(MEMPOOL_RESERVED + max_size);
-    if (!*mptr) return NULL;
-    **mptr = (struct mempool){
-        .malloc = malloc,
-        .free = free,
-        .size = MEMPOOL_RESERVED + max_size,
-        .used = sizeof(struct mempool),
-        .next = old,
-    };
-    uintptr_t mptr_used_start = (uintptr_t)(*mptr) + (*mptr)->used;
-    (*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK; // reserve bytes required to make subsequent allocations aligned
-    assert(!(((uintptr_t)(*mptr) + (*mptr)->used) & ALIGN_MASK));
-
-    return mempool_alloc(mptr, size, size);
-}
-
-LIQ_PRIVATE void* mempool_alloc(mempool *mptr, unsigned int size, unsigned int max_size)
-{
-    if (((*mptr)->used+size) <= (*mptr)->size) {
-        unsigned int prevused = (*mptr)->used;
-        (*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
-        return ((char*)(*mptr)) + prevused;
-    }
-
-    return mempool_create(mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
-}
-
-LIQ_PRIVATE void mempool_destroy(mempool m)
-{
-    while (m) {
-        mempool next = m->next;
-        m->free(m);
-        m = next;
-    }
-}
diff --git a/src/drivers/libimagequant/mempool.h b/src/drivers/libimagequant/mempool.h
deleted file mode 100644
index e61b8dd..0000000
--- a/src/drivers/libimagequant/mempool.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef MEMPOOL_H
-#define MEMPOOL_H
-
-#include <stddef.h>
-
-struct mempool;
-typedef struct mempool *mempool;
-
-LIQ_PRIVATE void* mempool_create(mempool *mptr, unsigned int size, unsigned int capacity, void* (*malloc)(size_t), void (*free)(void*));
-LIQ_PRIVATE void* mempool_alloc(mempool *mptr, unsigned int size, unsigned int capacity);
-LIQ_PRIVATE void mempool_destroy(mempool m);
-
-#endif
diff --git a/src/drivers/libimagequant/nearest.c b/src/drivers/libimagequant/nearest.c
deleted file mode 100644
index 752c477..0000000
--- a/src/drivers/libimagequant/nearest.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-** © 2011-2015 by Kornel Lesiński.
-** All rights reserved.
-** See COPYRIGHT file for full license.
-*/
-
-#include "libimagequant.h"
-#include "pam.h"
-#include "nearest.h"
-#include "mempool.h"
-#include <stdlib.h>
-
-typedef struct vp_sort_tmp {
-    float distance_squared;
-    unsigned int idx;
-} vp_sort_tmp;
-
-typedef struct vp_search_tmp {
-    float distance;
-    unsigned int idx;
-    int exclude;
-} vp_search_tmp;
-
-typedef struct vp_node {
-    struct vp_node *near, *far;
-    f_pixel vantage_point;
-    float radius;
-    unsigned int idx;
-} vp_node;
-
-struct nearest_map {
-    vp_node *root;
-    const colormap_item *palette;
-    float nearest_other_color_dist[256];
-    mempool mempool;
-};
-
-static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate);
-
-static int vp_compare_distance(const void *ap, const void *bp) {
-    float a = ((const vp_sort_tmp*)ap)->distance_squared;
-    float b = ((const vp_sort_tmp*)bp)->distance_squared;
-    return a > b ? 1 : -1;
-}
-
-static void vp_sort_indexes_by_distance(const f_pixel vantage_point, vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
-    for(int i=0; i < num_indexes; i++) {
-        indexes[i].distance_squared = colordifference(vantage_point, items[indexes[i].idx].acolor);
-    }
-    qsort(indexes, num_indexes, sizeof(indexes[0]), vp_compare_distance);
-}
-
-/*
- * Usually it should pick farthest point, but picking most popular point seems to make search quicker anyway
- */
-static int vp_find_best_vantage_point_index(vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
-    int best = 0;
-    float best_popularity = items[indexes[0].idx].popularity;
-    for(int i = 1; i < num_indexes; i++) {
-        if (items[indexes[i].idx].popularity > best_popularity) {
-            best_popularity = items[indexes[i].idx].popularity;
-            best = i;
-        }
-    }
-    return best;
-}
-
-static vp_node *vp_create_node(mempool *m, vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
-    if (num_indexes <= 0) {
-        return NULL;
-    }
-
-    vp_node *node = mempool_alloc(m, sizeof(node[0]), 0);
-
-    if (num_indexes == 1) {
-        *node = (vp_node){
-            .vantage_point = items[indexes[0].idx].acolor,
-            .idx = indexes[0].idx,
-            .radius = MAX_DIFF,
-        };
-        return node;
-    }
-
-    const int ref = vp_find_best_vantage_point_index(indexes, num_indexes, items);
-    const int ref_idx = indexes[ref].idx;
-
-    // Removes the `ref_idx` item from remaining items, because it's included in the current node
-    num_indexes -= 1;
-    indexes[ref] = indexes[num_indexes];
-
-    vp_sort_indexes_by_distance(items[ref_idx].acolor, indexes, num_indexes, items);
-
-    // Remaining items are split by the median distance
-    const int half_idx = num_indexes/2;
-
-    *node = (vp_node){
-        .vantage_point = items[ref_idx].acolor,
-        .idx = ref_idx,
-        .radius = sqrtf(indexes[half_idx].distance_squared),
-    };
-    node->near = vp_create_node(m, indexes, half_idx, items);
-    node->far = vp_create_node(m, &indexes[half_idx], num_indexes - half_idx, items);
-
-    return node;
-}
-
-LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *map, const bool fast) {
-    mempool m = NULL;
-    struct nearest_map *handle = mempool_create(&m, sizeof(handle[0]), sizeof(handle[0]) + sizeof(vp_node)*map->colors+16, map->malloc, map->free);
-
-    vp_sort_tmp indexes[map->colors];
-
-    for(unsigned int i=0; i < map->colors; i++) {
-        indexes[i].idx = i;
-    }
-
-    vp_node *root = vp_create_node(&m, indexes, map->colors, map->palette);
-    *handle = (struct nearest_map){
-        .root = root,
-        .palette = map->palette,
-        .mempool = m,
-    };
-
-    for(unsigned int i=0; i < map->colors; i++) {
-        vp_search_tmp best = {
-            .distance = MAX_DIFF,
-            .exclude = i,
-        };
-        vp_search_node(root, &map->palette[i].acolor, &best);
-        handle->nearest_other_color_dist[i] = best.distance * best.distance / 4.0; // half of squared distance
-    }
-
-    return handle;
-}
-
-static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate) {
-    do {
-        const float distance = sqrtf(colordifference(node->vantage_point, *needle));
-
-        if (distance < best_candidate->distance && best_candidate->exclude != node->idx) {
-            best_candidate->distance = distance;
-            best_candidate->idx = node->idx;
-        }
-
-        // Recurse towards most likely candidate first to narrow best candidate's distance as soon as possible
-        if (distance < node->radius) {
-            if (node->near) {
-                vp_search_node(node->near, needle, best_candidate);
-            }
-            // The best node (final answer) may be just ouside the radius, but not farther than
-            // the best distance we know so far. The vp_search_node above should have narrowed
-            // best_candidate->distance, so this path is rarely taken.
-            if (node->far && distance >= node->radius - best_candidate->distance) {
-                node = node->far; // Fast tail recursion
-            } else {
-                break;
-            }
-        } else {
-            if (node->far) {
-                vp_search_node(node->far, needle, best_candidate);
-            }
-            if (node->near && distance <= node->radius + best_candidate->distance) {
-                node = node->near; // Fast tail recursion
-            } else {
-                break;
-            }
-        }
-    } while(true);
-}
-
-LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *handle, const f_pixel *px, const int likely_colormap_index, float *diff) {
-    const float guess_diff = colordifference(handle->palette[likely_colormap_index].acolor, *px);
-    if (guess_diff < handle->nearest_other_color_dist[likely_colormap_index]) {
-        if (diff) *diff = guess_diff;
-        return likely_colormap_index;
-    }
-
-    vp_search_tmp best_candidate = {
-        .distance = sqrtf(guess_diff),
-        .idx = likely_colormap_index,
-        .exclude = -1,
-    };
-    vp_search_node(handle->root, px, &best_candidate);
-    if (diff) {
-        *diff = best_candidate.distance * best_candidate.distance;
-    }
-    return best_candidate.idx;
-}
-
-LIQ_PRIVATE void nearest_free(struct nearest_map *centroids)
-{
-    mempool_destroy(centroids->mempool);
-}
diff --git a/src/drivers/libimagequant/nearest.h b/src/drivers/libimagequant/nearest.h
deleted file mode 100644
index 0a98ca6..0000000
--- a/src/drivers/libimagequant/nearest.h
+++ /dev/null
@@ -1,8 +0,0 @@
-//
-//  nearest.h
-//  pngquant
-//
-struct nearest_map;
-LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *palette, const bool fast);
-LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *map, const f_pixel *px, const int palette_index_guess, float *diff);
-LIQ_PRIVATE void nearest_free(struct nearest_map *map);
diff --git a/src/drivers/libimagequant/pam.c b/src/drivers/libimagequant/pam.c
deleted file mode 100644
index d79da64..0000000
--- a/src/drivers/libimagequant/pam.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* pam.c - pam (portable alpha map) utility library
-**
-** Copyright (C) 1989, 1991 by Jef Poskanzer.
-** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
-**                                Stefan Schneider.
-** © 2009-2015 by Kornel Lesinski.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "libimagequant.h"
-#include "pam.h"
-#include "mempool.h"
-
-LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const rgba_pixel *const pixels[], unsigned int cols, unsigned int rows, const unsigned char *importance_map)
-{
-    const unsigned int maxacolors = acht->maxcolors, ignorebits = acht->ignorebits;
-    const unsigned int channel_mask = 255U>>ignorebits<<ignorebits;
-    const unsigned int channel_hmask = (255U>>ignorebits) ^ 0xFFU;
-    const unsigned int posterize_mask = channel_mask << 24 | channel_mask << 16 | channel_mask << 8 | channel_mask;
-    const unsigned int posterize_high_mask = channel_hmask << 24 | channel_hmask << 16 | channel_hmask << 8 | channel_hmask;
-    struct acolorhist_arr_head *const buckets = acht->buckets;
-
-    unsigned int colors = acht->colors;
-    const unsigned int hash_size = acht->hash_size;
-
-    const unsigned int stacksize = sizeof(acht->freestack)/sizeof(acht->freestack[0]);
-    struct acolorhist_arr_item **freestack = acht->freestack;
-    unsigned int freestackp=acht->freestackp;
-
-    /* Go through the entire image, building a hash table of colors. */
-    for(unsigned int row = 0; row < rows; ++row) {
-
-        float boost=1.0;
-        for(unsigned int col = 0; col < cols; ++col) {
-            if (importance_map) {
-                boost = 0.5f+ (double)*importance_map++/255.f;
-            }
-
-            // RGBA color is casted to long for easier hasing/comparisons
-            union rgba_as_int px = {pixels[row][col]};
-            unsigned int hash;
-            if (!px.rgba.a) {
-                // "dirty alpha" has different RGBA values that end up being the same fully transparent color
-                px.l=0; hash=0;
-            } else {
-                // mask posterizes all 4 channels in one go
-                px.l = (px.l & posterize_mask) | ((px.l & posterize_high_mask) >> (8-ignorebits));
-                // fancier hashing algorithms didn't improve much
-                hash = px.l % hash_size;
-            }
-
-            /* head of the hash function stores first 2 colors inline (achl->used = 1..2),
-               to reduce number of allocations of achl->other_items.
-             */
-            struct acolorhist_arr_head *achl = &buckets[hash];
-            if (achl->inline1.color.l == px.l && achl->used) {
-                achl->inline1.perceptual_weight += boost;
-                continue;
-            }
-            if (achl->used) {
-                if (achl->used > 1) {
-                    if (achl->inline2.color.l == px.l) {
-                        achl->inline2.perceptual_weight += boost;
-                        continue;
-                    }
-                    // other items are stored as an array (which gets reallocated if needed)
-                    struct acolorhist_arr_item *other_items = achl->other_items;
-                    unsigned int i = 0;
-                    for (; i < achl->used-2; i++) {
-                        if (other_items[i].color.l == px.l) {
-                            other_items[i].perceptual_weight += boost;
-                            goto continue_outer_loop;
-                        }
-                    }
-
-                    // the array was allocated with spare items
-                    if (i < achl->capacity) {
-                        other_items[i] = (struct acolorhist_arr_item){
-                            .color = px,
-                            .perceptual_weight = boost,
-                        };
-                        achl->used++;
-                        ++colors;
-                        continue;
-                    }
-
-                    if (++colors > maxacolors) {
-                        acht->colors = colors;
-                        acht->freestackp = freestackp;
-                        return false;
-                    }
-
-                    struct acolorhist_arr_item *new_items;
-                    unsigned int capacity;
-                    if (!other_items) { // there was no array previously, alloc "small" array
-                        capacity = 8;
-                        if (freestackp <= 0) {
-                            // estimate how many colors are going to be + headroom
-                            const size_t mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 1024) * sizeof(struct acolorhist_arr_item);
-                            new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
-                        } else {
-                            // freestack stores previously freed (reallocated) arrays that can be reused
-                            // (all pesimistically assumed to be capacity = 8)
-                            new_items = freestack[--freestackp];
-                        }
-                    } else {
-                        // simply reallocs and copies array to larger capacity
-                        capacity = achl->capacity*2 + 16;
-                        if (freestackp < stacksize-1) {
-                            freestack[freestackp++] = other_items;
-                        }
-                        const size_t mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 32*capacity) * sizeof(struct acolorhist_arr_item);
-                        new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
-                        if (!new_items) return false;
-                        memcpy(new_items, other_items, sizeof(other_items[0])*achl->capacity);
-                    }
-
-                    achl->other_items = new_items;
-                    achl->capacity = capacity;
-                    new_items[i] = (struct acolorhist_arr_item){
-                        .color = px,
-                        .perceptual_weight = boost,
-                    };
-                    achl->used++;
-                } else {
-                    // these are elses for first checks whether first and second inline-stored colors are used
-                    achl->inline2.color.l = px.l;
-                    achl->inline2.perceptual_weight = boost;
-                    achl->used = 2;
-                    ++colors;
-                }
-            } else {
-                achl->inline1.color.l = px.l;
-                achl->inline1.perceptual_weight = boost;
-                achl->used = 1;
-                ++colors;
-            }
-
-            continue_outer_loop:;
-        }
-
-    }
-    acht->colors = colors;
-    acht->cols = cols;
-    acht->rows += rows;
-    acht->freestackp = freestackp;
-    return true;
-}
-
-LIQ_PRIVATE struct acolorhash_table *pam_allocacolorhash(unsigned int maxcolors, unsigned int surface, unsigned int ignorebits, void* (*malloc)(size_t), void (*free)(void*))
-{
-    const size_t estimated_colors = MIN(maxcolors, surface/(ignorebits + (surface > 512*512 ? 6 : 5)));
-    const size_t hash_size = estimated_colors < 66000 ? 6673 : (estimated_colors < 200000 ? 12011 : 24019);
-
-    mempool m = NULL;
-    const size_t buckets_size = hash_size * sizeof(struct acolorhist_arr_head);
-    const size_t mempool_size = sizeof(struct acolorhash_table) + buckets_size + estimated_colors * sizeof(struct acolorhist_arr_item);
-    struct acolorhash_table *t = mempool_create(&m, sizeof(*t) + buckets_size, mempool_size, malloc, free);
-    if (!t) return NULL;
-    *t = (struct acolorhash_table){
-        .mempool = m,
-        .hash_size = hash_size,
-        .maxcolors = maxcolors,
-        .ignorebits = ignorebits,
-    };
-    memset(t->buckets, 0, hash_size * sizeof(struct acolorhist_arr_head));
-    return t;
-}
-
-#define PAM_ADD_TO_HIST(entry) { \
-    hist->achv[j].acolor = to_f(gamma_lut, entry.color.rgba); \
-    total_weight += hist->achv[j].adjusted_weight = hist->achv[j].perceptual_weight = MIN(entry.perceptual_weight, max_perceptual_weight); \
-    ++j; \
-}
-
-LIQ_PRIVATE histogram *pam_acolorhashtoacolorhist(const struct acolorhash_table *acht, const double gamma, void* (*malloc)(size_t), void (*free)(void*))
-{
-    histogram *hist = malloc(sizeof(hist[0]));
-    if (!hist || !acht) return NULL;
-    *hist = (histogram){
-        .achv = malloc(acht->colors * sizeof(hist->achv[0])),
-        .size = acht->colors,
-        .free = free,
-        .ignorebits = acht->ignorebits,
-    };
-    if (!hist->achv) return NULL;
-
-    float gamma_lut[256];
-    to_f_set_gamma(gamma_lut, gamma);
-
-    /* Limit perceptual weight to 1/10th of the image surface area to prevent
-       a single color from dominating all others. */
-    float max_perceptual_weight = 0.1f * acht->cols * acht->rows;
-    double total_weight = 0;
-
-    for(unsigned int j=0, i=0; i < acht->hash_size; ++i) {
-        const struct acolorhist_arr_head *const achl = &acht->buckets[i];
-        if (achl->used) {
-            PAM_ADD_TO_HIST(achl->inline1);
-
-            if (achl->used > 1) {
-                PAM_ADD_TO_HIST(achl->inline2);
-
-                for(unsigned int k=0; k < achl->used-2; k++) {
-                    PAM_ADD_TO_HIST(achl->other_items[k]);
-                }
-            }
-        }
-    }
-
-    hist->total_perceptual_weight = total_weight;
-    return hist;
-}
-
-
-LIQ_PRIVATE void pam_freeacolorhash(struct acolorhash_table *acht)
-{
-    mempool_destroy(acht->mempool);
-}
-
-LIQ_PRIVATE void pam_freeacolorhist(histogram *hist)
-{
-    hist->free(hist->achv);
-    hist->free(hist);
-}
-
-LIQ_PRIVATE colormap *pam_colormap(unsigned int colors, void* (*malloc)(size_t), void (*free)(void*))
-{
-    assert(colors > 0 && colors < 65536);
-
-    colormap *map;
-    const size_t colors_size = colors * sizeof(map->palette[0]);
-    map = malloc(sizeof(colormap) + colors_size);
-    if (!map) return NULL;
-    *map = (colormap){
-        .malloc = malloc,
-        .free = free,
-        .colors = colors,
-    };
-    memset(map->palette, 0, colors_size);
-    return map;
-}
-
-LIQ_PRIVATE colormap *pam_duplicate_colormap(colormap *map)
-{
-    colormap *dupe = pam_colormap(map->colors, map->malloc, map->free);
-    for(unsigned int i=0; i < map->colors; i++) {
-        dupe->palette[i] = map->palette[i];
-    }
-    return dupe;
-}
-
-LIQ_PRIVATE void pam_freecolormap(colormap *c)
-{
-    c->free(c);
-}
-
-LIQ_PRIVATE void to_f_set_gamma(float gamma_lut[], const double gamma)
-{
-    for(int i=0; i < 256; i++) {
-        gamma_lut[i] = pow((double)i/255.0, internal_gamma/gamma);
-    }
-}
-
diff --git a/src/drivers/libimagequant/pam.h b/src/drivers/libimagequant/pam.h
deleted file mode 100644
index f20e71c..0000000
--- a/src/drivers/libimagequant/pam.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* pam.h - pam (portable alpha map) utility library
- **
- ** Colormap routines.
- **
- ** Copyright (C) 1989, 1991 by Jef Poskanzer.
- ** Copyright (C) 1997 by Greg Roelofs.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation.  This software is provided "as is" without express or
- ** implied warranty.
- */
-
-#ifndef PAM_H
-#define PAM_H
-
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#ifndef MAX
-#  define MAX(a,b)  ((a) > (b)? (a) : (b))
-#  define MIN(a,b)  ((a) < (b)? (a) : (b))
-#endif
-
-#define MAX_DIFF 1e20
-
-#ifndef USE_SSE
-#  if defined(__SSE__) && (defined(__amd64__) || defined(__X86_64__) || defined(_WIN64) || defined(WIN32) || defined(__WIN32__))
-#    define USE_SSE 1
-#  else
-#    define USE_SSE 0
-#  endif
-#endif
-
-#if USE_SSE
-#  include <xmmintrin.h>
-#  ifdef _MSC_VER
-#    include <intrin.h>
-#    define SSE_ALIGN
-#  else
-#    define SSE_ALIGN __attribute__ ((aligned (16)))
-#    if defined(__i386__) && defined(__PIC__)
-#       define cpuid(func,ax,bx,cx,dx)\
-        __asm__ __volatile__ ( \
-        "push %%ebx\n" \
-        "cpuid\n" \
-        "mov %%ebx, %1\n" \
-        "pop %%ebx\n" \
-        : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) \
-        : "a" (func));
-#    else
-#       define cpuid(func,ax,bx,cx,dx)\
-        __asm__ __volatile__ ("cpuid":\
-        "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
-#    endif
-#endif
-#else
-#  define SSE_ALIGN
-#endif
-
-#if defined(__GNUC__) || defined (__llvm__)
-#define ALWAYS_INLINE __attribute__((always_inline)) inline
-#define NEVER_INLINE __attribute__ ((noinline))
-#elif defined(_MSC_VER)
-#define inline __inline
-#define restrict __restrict
-#define ALWAYS_INLINE __forceinline
-#define NEVER_INLINE __declspec(noinline)
-#else
-#define ALWAYS_INLINE inline
-#define NEVER_INLINE
-#endif
-
-/* from pam.h */
-
-typedef struct {
-    unsigned char r, g, b, a;
-} rgba_pixel;
-
-typedef struct {
-    float a, r, g, b;
-} SSE_ALIGN f_pixel;
-
-static const double internal_gamma = 0.5499;
-
-LIQ_PRIVATE void to_f_set_gamma(float gamma_lut[], const double gamma);
-
-/**
- Converts 8-bit color to internal gamma and premultiplied alpha.
- (premultiplied color space is much better for blending of semitransparent colors)
- */
-ALWAYS_INLINE static f_pixel to_f(const float gamma_lut[], const rgba_pixel px);
-inline static f_pixel to_f(const float gamma_lut[], const rgba_pixel px)
-{
-    float a = px.a/255.f;
-
-    return (f_pixel) {
-        .a = a,
-        .r = gamma_lut[px.r]*a,
-        .g = gamma_lut[px.g]*a,
-        .b = gamma_lut[px.b]*a,
-    };
-}
-
-inline static rgba_pixel to_rgb(const float gamma, const f_pixel px)
-{
-    if (px.a < 1.f/256.f) {
-        return (rgba_pixel){0,0,0,0};
-    }
-
-    float r = px.r / px.a,
-          g = px.g / px.a,
-          b = px.b / px.a,
-          a = px.a;
-
-    r = powf(r, gamma/internal_gamma);
-    g = powf(g, gamma/internal_gamma);
-    b = powf(b, gamma/internal_gamma);
-
-    // 256, because numbers are in range 1..255.9999… rounded down
-    r *= 256.f;
-    g *= 256.f;
-    b *= 256.f;
-    a *= 256.f;
-
-    return (rgba_pixel){
-        .r = r>=255.f ? 255 : r,
-        .g = g>=255.f ? 255 : g,
-        .b = b>=255.f ? 255 : b,
-        .a = a>=255.f ? 255 : a,
-    };
-}
-
-ALWAYS_INLINE static double colordifference_ch(const double x, const double y, const double alphas);
-inline static double colordifference_ch(const double x, const double y, const double alphas)
-{
-    // maximum of channel blended on white, and blended on black
-    // premultiplied alpha and backgrounds 0/1 shorten the formula
-    const double black = x-y, white = black+alphas;
-    return black*black + white*white;
-}
-
-ALWAYS_INLINE static float colordifference_stdc(const f_pixel px, const f_pixel py);
-inline static float colordifference_stdc(const f_pixel px, const f_pixel py)
-{
-    // px_b.rgb = px.rgb + 0*(1-px.a) // blend px on black
-    // px_b.a   = px.a   + 1*(1-px.a)
-    // px_w.rgb = px.rgb + 1*(1-px.a) // blend px on white
-    // px_w.a   = px.a   + 1*(1-px.a)
-
-    // px_b.rgb = px.rgb              // difference same as in opaque RGB
-    // px_b.a   = 1
-    // px_w.rgb = px.rgb - px.a       // difference simplifies to formula below
-    // px_w.a   = 1
-
-    // (px.rgb - px.a) - (py.rgb - py.a)
-    // (px.rgb - py.rgb) + (py.a - px.a)
-
-    const double alphas = py.a-px.a;
-    return colordifference_ch(px.r, py.r, alphas) +
-           colordifference_ch(px.g, py.g, alphas) +
-           colordifference_ch(px.b, py.b, alphas);
-}
-
-ALWAYS_INLINE static float colordifference(f_pixel px, f_pixel py);
-inline static float colordifference(f_pixel px, f_pixel py)
-{
-#if USE_SSE
-    const __m128 vpx = _mm_load_ps((const float*)&px);
-    const __m128 vpy = _mm_load_ps((const float*)&py);
-
-    // y.a - x.a
-    __m128 alphas = _mm_sub_ss(vpy, vpx);
-    alphas = _mm_shuffle_ps(alphas,alphas,0); // copy first to all four
-
-    __m128 onblack = _mm_sub_ps(vpx, vpy); // x - y
-    __m128 onwhite = _mm_add_ps(onblack, alphas); // x - y + (y.a - x.a)
-
-    onblack = _mm_mul_ps(onblack, onblack);
-    onwhite = _mm_mul_ps(onwhite, onwhite);
-    const __m128 max = _mm_add_ps(onwhite, onblack);
-
-    // add rgb, not a
-    const __m128 maxhl = _mm_movehl_ps(max, max);
-    const __m128 tmp = _mm_add_ps(max, maxhl);
-    const __m128 sum = _mm_add_ss(maxhl, _mm_shuffle_ps(tmp, tmp, 1));
-
-    const float res = _mm_cvtss_f32(sum);
-    assert(fabs(res - colordifference_stdc(px,py)) < 0.001);
-    return res;
-#else
-    return colordifference_stdc(px,py);
-#endif
-}
-
-/* from pamcmap.h */
-union rgba_as_int {
-    rgba_pixel rgba;
-    unsigned int l;
-};
-
-typedef struct {
-    f_pixel acolor;
-    float adjusted_weight,   // perceptual weight changed to tweak how mediancut selects colors
-          perceptual_weight; // number of pixels weighted by importance of different areas of the picture
-
-    float color_weight;      // these two change every time histogram subset is sorted
-    union {
-        unsigned int sort_value;
-        unsigned char likely_colormap_index;
-    } tmp;
-} hist_item;
-
-typedef struct {
-    hist_item *achv;
-    void (*free)(void*);
-    double total_perceptual_weight;
-    unsigned int size;
-    unsigned int ignorebits;
-} histogram;
-
-typedef struct {
-    f_pixel acolor;
-    float popularity;
-    bool fixed; // if true it's user-supplied and must not be changed (e.g in voronoi iteration)
-} colormap_item;
-
-typedef struct colormap {
-    unsigned int colors;
-    void* (*malloc)(size_t);
-    void (*free)(void*);
-    colormap_item palette[];
-} colormap;
-
-struct acolorhist_arr_item {
-    union rgba_as_int color;
-    float perceptual_weight;
-};
-
-struct acolorhist_arr_head {
-    unsigned int used, capacity;
-    struct {
-        union rgba_as_int color;
-        float perceptual_weight;
-    } inline1, inline2;
-    struct acolorhist_arr_item *other_items;
-};
-
-struct acolorhash_table {
-    struct mempool *mempool;
-    unsigned int ignorebits, maxcolors, colors, cols, rows;
-    unsigned int hash_size;
-    unsigned int freestackp;
-    struct acolorhist_arr_item *freestack[512];
-    struct acolorhist_arr_head buckets[];
-};
-
-LIQ_PRIVATE void pam_freeacolorhash(struct acolorhash_table *acht);
-LIQ_PRIVATE struct acolorhash_table *pam_allocacolorhash(unsigned int maxcolors, unsigned int surface, unsigned int ignorebits, void* (*malloc)(size_t), void (*free)(void*));
-LIQ_PRIVATE histogram *pam_acolorhashtoacolorhist(const struct acolorhash_table *acht, const double gamma, void* (*malloc)(size_t), void (*free)(void*));
-LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const rgba_pixel *const pixels[], unsigned int cols, unsigned int rows, const unsigned char *importance_map);
-
-LIQ_PRIVATE void pam_freeacolorhist(histogram *h);
-
-LIQ_PRIVATE colormap *pam_colormap(unsigned int colors, void* (*malloc)(size_t), void (*free)(void*));
-LIQ_PRIVATE colormap *pam_duplicate_colormap(colormap *map);
-LIQ_PRIVATE void pam_freecolormap(colormap *c);
-
-#endif
diff --git a/src/drivers/libimagequant/pngquant.c b/src/drivers/libimagequant/pngquant.c
deleted file mode 100644
index 08851cc..0000000
--- a/src/drivers/libimagequant/pngquant.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* pngquant.c - quantize the colors in an alphamap down to a specified number
-**
-** Copyright (C) 1989, 1991 by Jef Poskanzer.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-**
-** - - - -
-**
-** © 1997-2002 by Greg Roelofs; based on an idea by Stefan Schneider.
-** © 2009-2014 by Kornel Lesiński.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without modification,
-** are permitted provided that the following conditions are met:
-**
-** 1. Redistributions of source code must retain the above copyright notice,
-**    this list of conditions and the following disclaimer.
-**
-** 2. Redistributions in binary form must reproduce the above copyright notice,
-**    this list of conditions and the following disclaimer in the documentation
-**    and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-*/
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <unistd.h>
-
-#include "pngquant.h"
-
-void verbose_printf(struct pngquant_options *context, const char *fmt, ...)
-{
-    if (context->log_callback) {
-        va_list va;
-        va_start(va, fmt);
-        int required_space = vsnprintf(NULL, 0, fmt, va)+1; // +\0
-        va_end(va);
-
-        char buf[required_space];
-        va_start(va, fmt);
-        vsnprintf(buf, required_space, fmt, va);
-        va_end(va);
-
-        context->log_callback(context->liq, buf, context->log_callback_user_info);
-    }
-}
-
-
-pngquant_error pngquant_file(const char *filename, const char *outname, struct pngquant_options *options)
-{
-    pngquant_error  retval             = SUCCESS;
-    liq_image*      input_image        = NULL;
-    png24_image     input_image_rwpng  = {};
-
-   retval = read_image(options->liq, filename, options->using_stdin, &input_image_rwpng, &input_image, false, options->verbose);
-
-    int quality_percent = 90; // quality on 0-100 scale, updated upon successful remap
-    png8_image output_image = {};
-
-    if (SUCCESS == retval)
-    {
-         // when using image as source of a fixed palette the palette is extracted using regular quantization
-        liq_result *remap = liq_quantize_image(options->liq, options->fixed_palette_image ? options->fixed_palette_image : input_image);
-
-        if (remap) {
-            liq_set_output_gamma(remap, 0.45455); // fixed gamma ~2.2 for the web. PNG can't store exact 1/2.2
-            liq_set_dithering_level(remap, options->floyd);
-
-            retval = prepare_output_image(remap, input_image, &output_image);
-            if (SUCCESS == retval) {
-                if (LIQ_OK != liq_write_remapped_image_rows(remap, input_image, output_image.row_pointers)) {
-                    retval = OUT_OF_MEMORY_ERROR;
-                }
-
-                set_palette(remap, &output_image);
-
-                double palette_error = liq_get_quantization_error(remap);
-                if (palette_error >= 0) {
-                    quality_percent = liq_get_quantization_quality(remap);
-                    //verbose_printf(options, "  mapped image to new colors...MSE=%.3f (Q=%d)", palette_error, quality_percent);
-                }
-            }
-            liq_result_destroy(remap);
-        } else {
-            retval = TOO_LOW_QUALITY;
-        }
-    }
-
-    if (SUCCESS == retval) {
-        output_image.fast_compression  = options->fast_compression;
-        output_image.chunks            = input_image_rwpng.chunks;
-        input_image_rwpng.chunks       = NULL;
-
-        retval = write_image(&output_image, NULL, outname, options);
-    }
-/*
-    if (options->using_stdout && keep_input_pixels && (TOO_LARGE_FILE == retval || TOO_LOW_QUALITY == retval)) {
-        // when outputting to stdout it'd be nasty to create 0-byte file
-        // so if quality is too low, output 24-bit original
-        pngquant_error write_retval = write_image(NULL, &input_image_rwpng, outname, options);
-        if (write_retval) {
-            retval = write_retval;
-        }
-    }
-*/
-    liq_image_destroy(input_image);
-    rwpng_free_image24(&input_image_rwpng);
-    rwpng_free_image8(&output_image);
-    return retval;
-}
-
-/**************************************************************************
- * 
- */
-void set_palette(liq_result *result, png8_image *output_image)
-{
-    const liq_palette *palette = liq_get_palette(result);
-
-    // tRNS, etc.
-    output_image->num_palette = palette->count;
-    output_image->num_trans = 0;
-    for(unsigned int i=0; i < palette->count; i++) {
-        liq_color px = palette->entries[i];
-        if (px.a < 255) {
-            output_image->num_trans = i+1;
-        }
-        output_image->palette[i] = (png_color){.red=px.r, .green=px.g, .blue=px.b};
-        output_image->trans[i] = px.a;
-    }
-}
-
-
-/**************************************************************************
- * 
- */
-char *temp_filename(const char *basename) {
-    size_t x = strlen(basename);
-
-    char *outname = (char *)malloc(x+1+4);
-    if (!outname) return NULL;
-
-    strcpy(outname, basename);
-    strcpy(outname+x, ".tmp");
-
-    return outname;
-}
-
-
-/**************************************************************************
- * 
- */
-pngquant_error write_image(png8_image *output_image, png24_image *output_image24, const char *outname, struct pngquant_options *options)
-{
-    FILE *outfile;
-    char *tempname = NULL;
-
-        tempname = temp_filename(outname);
-        if (!tempname) return OUT_OF_MEMORY_ERROR;
-
-        if ((outfile = fopen(tempname, "wb")) == NULL) {
-            fprintf(stderr, "  error: cannot open '%s' for writing\n", tempname);
-            free(tempname);
-            return CANT_WRITE_ERROR;
-        }
-
-        if (output_image) {
-            verbose_printf(options, "  writing %d-color image as %s", output_image->num_palette, outname);
-        } else {
-            verbose_printf(options, "  writing truecolor image as %s", outname);
-        }
-
-    pngquant_error retval;
-        if (output_image) {
-            retval = rwpng_write_image8(outfile, output_image);
-        } else {
-            retval = rwpng_write_image24(outfile, output_image24);
-        }
-
-    if (!options->using_stdout) {
-        fclose(outfile);
-
-        if (SUCCESS == retval) {
-            // Image has been written to a temporary file and then moved over destination.
-            // This makes replacement atomic and avoids damaging destination file on write error.
-            if (0 != rename(tempname, outname)) {
-                retval = CANT_WRITE_ERROR;
-            }
-        }
-
-        if (retval) {
-            unlink(tempname);
-        }
-        free(tempname);
-    }
-
-    if (retval && retval != TOO_LARGE_FILE) {
-        fprintf(stderr, "  error: failed writing image to %s\n", outname);
-    }
-    return retval;
-}
-
-/**************************************************************************
- * 
- */
-pngquant_error read_image(liq_attr *options, const char *filename, int using_stdin, png24_image *input_image_p, liq_image **liq_image_p, bool keep_input_pixels, bool verbose)
-{
-    FILE *infile;
-
-    if ((infile = fopen(filename, "rb")) == NULL) {
-        fprintf(stderr, "  error: cannot open %s for reading\n", filename);
-        return READ_ERROR;
-    }
-
-    pngquant_error retval;
-        retval = rwpng_read_image24(infile, input_image_p, verbose);
-
-        fclose(infile);
-
-    if (retval) {
-        fprintf(stderr, "  error: rwpng_read_image() error %d with file %s\n", retval, filename);
-        return retval;
-    }
-
-    *liq_image_p = liq_image_create_rgba_rows(options, (void**)input_image_p->row_pointers, input_image_p->width, input_image_p->height, input_image_p->gamma);
-
-    if (!*liq_image_p) {
-        return OUT_OF_MEMORY_ERROR;
-    }
-
-    if (!keep_input_pixels) {
-        if (LIQ_OK != liq_image_set_memory_ownership(*liq_image_p, LIQ_OWN_ROWS | LIQ_OWN_PIXELS)) {
-            return OUT_OF_MEMORY_ERROR;
-        }
-        input_image_p->row_pointers = NULL;
-        input_image_p->rgba_data = NULL;
-    }
-    return SUCCESS;
-}
-
-/**************************************************************************
- * 
- */
-pngquant_error prepare_output_image(liq_result *result, liq_image *input_image, png8_image *output_image)
-{
-    output_image->width = liq_image_get_width(input_image);
-    output_image->height = liq_image_get_height(input_image);
-    output_image->gamma = liq_get_output_gamma(result);
-
-    /*
-    ** Step 3.7 [GRR]: allocate memory for the entire indexed image
-    */
-    output_image->indexed_data = (unsigned char *)malloc(output_image->height * output_image->width);
-    output_image->row_pointers = (unsigned char **)malloc(output_image->height * sizeof(output_image->row_pointers[0]));
-
-    if (!output_image->indexed_data || !output_image->row_pointers) {
-        return OUT_OF_MEMORY_ERROR;
-    }
-
-    for(unsigned int row = 0;  row < output_image->height;  ++row) {
-        output_image->row_pointers[row] = output_image->indexed_data + row*output_image->width;
-    }
-
-    const liq_palette *palette = liq_get_palette(result);
-    // tRNS, etc.
-    output_image->num_palette = palette->count;
-    output_image->num_trans = 0;
-    for(unsigned int i=0; i < palette->count; i++) {
-        if (palette->entries[i].a < 255) {
-            output_image->num_trans = i+1;
-        }
-    }
-    return SUCCESS;
-}
diff --git a/src/drivers/libimagequant/pngquant.h b/src/drivers/libimagequant/pngquant.h
deleted file mode 100644
index 929db15..0000000
--- a/src/drivers/libimagequant/pngquant.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* pngquant.c - quantize the colors in an alphamap down to a specified number
-**
-** Copyright (C) 1989, 1991 by Jef Poskanzer.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-**
-** - - - -
-**
-** © 1997-2002 by Greg Roelofs; based on an idea by Stefan Schneider.
-** © 2009-2014 by Kornel Lesiński.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without modification,
-** are permitted provided that the following conditions are met:
-**
-** 1. Redistributions of source code must retain the above copyright notice,
-**    this list of conditions and the following disclaimer.
-**
-** 2. Redistributions in binary form must reproduce the above copyright notice,
-**    this list of conditions and the following disclaimer in the documentation
-**    and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-*/
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include "rwpng.h"  /* typedefs, common macros, public prototypes */
-#include "libimagequant.h"
-
-struct pngquant_options {
-    liq_attr *liq;
-    liq_image *fixed_palette_image;
-    liq_log_callback_function *log_callback;
-    void *log_callback_user_info;
-    float floyd;
-    bool using_stdin, using_stdout, force, fast_compression, ie_mode,
-        min_quality_limit, skip_if_larger,
-        verbose;
-};
-
-pngquant_error  prepare_output_image(liq_result *result, liq_image *input_image, png8_image *output_image);
-void            set_palette(liq_result *result, png8_image *output_image);
-pngquant_error  read_image(liq_attr *options, const char *filename, int using_stdin, png24_image *input_image_p, liq_image **liq_image_p, bool keep_input_pixels, bool verbose);
-pngquant_error  write_image(png8_image *output_image, png24_image *output_image24, const char *outname, struct pngquant_options *options);
-char           *add_filename_extension(const char *filename, const char *newext);
-
-void verbose_printf(struct pngquant_options *context, const char *fmt, ...);
-pngquant_error pngquant_file(const char *filename, const char *outname, struct pngquant_options *options);
-
diff --git a/src/drivers/libimagequant/rwpng.c b/src/drivers/libimagequant/rwpng.c
deleted file mode 100644
index 07bcf71..0000000
--- a/src/drivers/libimagequant/rwpng.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*---------------------------------------------------------------------------
-
-   pngquant:  RGBA -> RGBA-palette quantization program             rwpng.c
-
-  ---------------------------------------------------------------------------
-
-   © 1998-2000 by Greg Roelofs.
-   © 2009-2015 by Kornel Lesiński.
-
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without modification,
-   are permitted provided that the following conditions are met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  ---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#include "png.h"
-#include "rwpng.h"
-#if USE_LCMS
-#include "lcms2.h"
-#endif
-
-#ifndef Z_BEST_COMPRESSION
-#define Z_BEST_COMPRESSION 9
-#endif
-#ifndef Z_BEST_SPEED
-#define Z_BEST_SPEED 1
-#endif
-
-#ifdef _OPENMP
-#include <omp.h>
-#else
-#define omp_get_max_threads() 1
-#endif
-
-#if PNG_LIBPNG_VER < 10500
-typedef png_const_charp png_const_bytep;
-#endif
-
-static void rwpng_error_handler(png_structp png_ptr, png_const_charp msg);
-static void rwpng_warning_stderr_handler(png_structp png_ptr, png_const_charp msg);
-static void rwpng_warning_silent_handler(png_structp png_ptr, png_const_charp msg);
-int rwpng_read_image24_cocoa(FILE *infile, png24_image *mainprog_ptr);
-
-
-void rwpng_version_info(FILE *fp)
-{
-    const char *pngver = png_get_header_ver(NULL);
-
-#if USE_COCOA
-    fprintf(fp, "   Color profiles are supported via Cocoa. Using libpng %s.\n", pngver);
-#elif USE_LCMS
-    fprintf(fp, "   Color profiles are supported via Little CMS. Using libpng %s.\n", pngver);
-#else
-    fprintf(fp, "   Compiled without support for color profiles. Using libpng %s.\n", pngver);
-#endif
-
-#if PNG_LIBPNG_VER < 10600
-    if (strcmp(pngver, "1.3.") < 0) {
-        fputs("\nWARNING: Your version of libpng is outdated and may produce corrupted files.\n"
-              "Please recompile pngquant with the current version of libpng (1.6 or later).\n", fp);
-    } else if (strcmp(pngver, "1.6.") < 0) {
-        #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-        fputs("\nWARNING: Your version of libpng is old and has buggy support for custom chunks.\n"
-              "Please recompile pngquant with the current version of libpng (1.6 or later).\n", fp);
-        #endif
-    }
-#endif
-}
-
-
-struct rwpng_read_data {
-    FILE *const fp;
-    png_size_t bytes_read;
-};
-
-static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-    struct rwpng_read_data *read_data = (struct rwpng_read_data *)png_get_io_ptr(png_ptr);
-
-    png_size_t read = fread(data, 1, length, read_data->fp);
-    if (!read) {
-        png_error(png_ptr, "Read error");
-    }
-    read_data->bytes_read += read;
-}
-
-struct rwpng_write_state {
-    FILE *outfile;
-    png_size_t maximum_file_size;
-    png_size_t bytes_written;
-    pngquant_error retval;
-};
-
-static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-    struct rwpng_write_state *write_state = (struct rwpng_write_state *)png_get_io_ptr(png_ptr);
-
-    if (SUCCESS != write_state->retval) {
-        return;
-    }
-
-    if (!fwrite(data, length, 1, write_state->outfile)) {
-        write_state->retval = CANT_WRITE_ERROR;
-    }
-
-    write_state->bytes_written += length;
-}
-
-static void user_flush_data(png_structp png_ptr)
-{
-    // libpng never calls this :(
-}
-
-
-static png_bytepp rwpng_create_row_pointers(png_infop info_ptr, png_structp png_ptr, unsigned char *base, unsigned int height, png_size_t rowbytes)
-{
-    if (!rowbytes) {
-        rowbytes = png_get_rowbytes(png_ptr, info_ptr);
-    }
-
-    png_bytepp row_pointers = malloc(height * sizeof(row_pointers[0]));
-    if (!row_pointers) return NULL;
-    for(size_t row = 0; row < height; row++) {
-        row_pointers[row] = base + row * rowbytes;
-    }
-    return row_pointers;
-}
-
-static int read_chunk_callback(png_structp png_ptr, png_unknown_chunkp in_chunk)
-{
-    if (0 == memcmp("iCCP", in_chunk->name, 5) ||
-        0 == memcmp("cHRM", in_chunk->name, 5) ||
-        0 == memcmp("gAMA", in_chunk->name, 5)) {
-        return 0; // not handled
-    }
-
-    struct rwpng_chunk **head = (struct rwpng_chunk **)png_get_user_chunk_ptr(png_ptr);
-
-    struct rwpng_chunk *chunk = malloc(sizeof(struct rwpng_chunk));
-    memcpy(chunk->name, in_chunk->name, 5);
-    chunk->size = in_chunk->size;
-    chunk->location = in_chunk->location;
-    chunk->data = in_chunk->size ? malloc(in_chunk->size) : NULL;
-    if (in_chunk->size) {
-        memcpy(chunk->data, in_chunk->data, in_chunk->size);
-    }
-
-    chunk->next = *head;
-    *head = chunk;
-
-    return 1; // marks as "handled", libpng won't store it
-}
-
-/*
-   retval:
-     0 = success
-    21 = bad sig
-    22 = bad IHDR
-    24 = insufficient memory
-    25 = libpng error (via longjmp())
-    26 = wrong PNG color type (no alpha channel)
- */
-
-static pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr, int verbose)
-{
-    png_structp  png_ptr = NULL;
-    png_infop    info_ptr = NULL;
-    png_size_t   rowbytes;
-    int          color_type, bit_depth;
-
-    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
-      rwpng_error_handler, verbose ? rwpng_warning_stderr_handler : rwpng_warning_silent_handler);
-    if (!png_ptr) {
-        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
-    }
-
-    info_ptr = png_create_info_struct(png_ptr);
-    if (!info_ptr) {
-        png_destroy_read_struct(&png_ptr, NULL, NULL);
-        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
-    }
-
-    /* setjmp() must be called in every function that calls a non-trivial
-     * libpng function */
-
-    if (setjmp(mainprog_ptr->jmpbuf)) {
-        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-        return LIBPNG_FATAL_ERROR;   /* fatal libpng error (via longjmp()) */
-    }
-
-#if PNG_LIBPNG_VER >= 10500 && defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-    /* copy standard chunks too */
-    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_IF_SAFE, (png_const_bytep)"pHYs\0iTXt\0tEXt\0zTXt", 4);
-#endif
-    png_set_read_user_chunk_fn(png_ptr, &mainprog_ptr->chunks, read_chunk_callback);
-
-    struct rwpng_read_data read_data = {infile, 0};
-    png_set_read_fn(png_ptr, &read_data, user_read_data);
-
-    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */
-
-    /* alternatively, could make separate calls to png_get_image_width(),
-     * etc., but want bit_depth and color_type for later [don't care about
-     * compression_type and filter_type => NULLs] */
-
-    png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, &mainprog_ptr->height,
-                 &bit_depth, &color_type, NULL, NULL, NULL);
-
-    // For overflow safety reject images that won't fit in 32-bit
-    if (mainprog_ptr->width > INT_MAX/mainprog_ptr->height) {
-        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-        return PNG_OUT_OF_MEMORY_ERROR;  /* not quite true, but whatever */
-    }
-
-    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
-     * transparency chunks to full alpha channel; strip 16-bit-per-sample
-     * images to 8 bits per sample; and convert grayscale to RGB[A] */
-
-    /* GRR TO DO:  preserve all safe-to-copy ancillary PNG chunks */
-
-    if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
-#ifdef PNG_READ_FILLER_SUPPORTED
-        png_set_expand(png_ptr);
-        png_set_filler(png_ptr, 65535L, PNG_FILLER_AFTER);
-#else
-        fprintf(stderr, "pngquant readpng:  image is neither RGBA nor GA\n");
-        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-        mainprog_ptr->retval = WRONG_INPUT_COLOR_TYPE;
-        return mainprog_ptr->retval;
-#endif
-    }
-
-    if (bit_depth == 16) {
-        png_set_strip_16(png_ptr);
-    }
-
-    if (!(color_type & PNG_COLOR_MASK_COLOR)) {
-        png_set_gray_to_rgb(png_ptr);
-    }
-
-
-    /* get source gamma for gamma correction, or use sRGB default */
-    double gamma = 0.45455;
-    if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
-        png_get_gAMA(png_ptr, info_ptr, &gamma);
-        if (gamma < 0 || gamma > 1.0) {
-            fprintf(stderr, "pngquant readpng:  ignored out-of-range gamma %f\n", gamma);
-            gamma = 0.45455;
-        }
-    }
-    mainprog_ptr->gamma = gamma;
-
-    png_set_interlace_handling(png_ptr);
-
-    /* all transformations have been registered; now update info_ptr data,
-     * get rowbytes and channels, and allocate image memory */
-
-    png_read_update_info(png_ptr, info_ptr);
-
-    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
-
-    if ((mainprog_ptr->rgba_data = malloc(rowbytes * mainprog_ptr->height)) == NULL) {
-        fprintf(stderr, "pngquant readpng:  unable to allocate image data\n");
-        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-        return PNG_OUT_OF_MEMORY_ERROR;
-    }
-
-    png_bytepp row_pointers = rwpng_create_row_pointers(info_ptr, png_ptr, mainprog_ptr->rgba_data, mainprog_ptr->height, 0);
-
-    /* now we can go ahead and just read the whole image */
-
-    png_read_image(png_ptr, row_pointers);
-
-    /* and we're done!  (png_read_end() can be omitted if no processing of
-     * post-IDAT text/time/etc. is desired) */
-
-    png_read_end(png_ptr, NULL);
-
-#if USE_LCMS
-#if PNG_LIBPNG_VER < 10500
-    png_charp ProfileData;
-#else
-    png_bytep ProfileData;
-#endif
-    png_uint_32 ProfileLen;
-
-    cmsHPROFILE hInProfile = NULL;
-
-    /* color_type is read from the image before conversion to RGBA */
-    int COLOR_PNG = color_type & PNG_COLOR_MASK_COLOR;
-
-    mainprog_ptr->lcms_status = NONE;
-
-    /* embedded ICC profile */
-    if (png_get_iCCP(png_ptr, info_ptr, &(png_charp){0}, &(int){0}, &ProfileData, &ProfileLen)) {
-
-        hInProfile = cmsOpenProfileFromMem(ProfileData, ProfileLen);
-        cmsColorSpaceSignature colorspace = cmsGetColorSpace(hInProfile);
-
-        /* only RGB (and GRAY) valid for PNGs */
-        if (colorspace == cmsSigRgbData && COLOR_PNG) {
-            mainprog_ptr->lcms_status = ICCP;
-        } else {
-            if (colorspace == cmsSigGrayData && !COLOR_PNG) {
-                mainprog_ptr->lcms_status = ICCP_WARN_GRAY;
-            }
-            cmsCloseProfile(hInProfile);
-            hInProfile = NULL;
-        }
-    }
-
-    /* build RGB profile from cHRM and gAMA */
-    if (hInProfile == NULL && COLOR_PNG &&
-        !png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB) &&
-        png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) &&
-        png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) {
-
-        cmsCIExyY WhitePoint;
-        cmsCIExyYTRIPLE Primaries;
-
-        png_get_cHRM(png_ptr, info_ptr, &WhitePoint.x, &WhitePoint.y,
-                     &Primaries.Red.x, &Primaries.Red.y,
-                     &Primaries.Green.x, &Primaries.Green.y,
-                     &Primaries.Blue.x, &Primaries.Blue.y);
-
-        WhitePoint.Y = Primaries.Red.Y = Primaries.Green.Y = Primaries.Blue.Y = 1.0;
-
-        cmsToneCurve *GammaTable[3];
-        GammaTable[0] = GammaTable[1] = GammaTable[2] = cmsBuildGamma(NULL, 1/gamma);
-
-        hInProfile = cmsCreateRGBProfile(&WhitePoint, &Primaries, GammaTable);
-
-        cmsFreeToneCurve(GammaTable[0]);
-
-        mainprog_ptr->lcms_status = GAMA_CHRM;
-    }
-
-    /* transform image to sRGB colorspace */
-    if (hInProfile != NULL) {
-
-        cmsHPROFILE hOutProfile = cmsCreate_sRGBProfile();
-        cmsHTRANSFORM hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_8,
-                                                      hOutProfile, TYPE_RGBA_8,
-                                                      INTENT_PERCEPTUAL,
-                                                      omp_get_max_threads() > 1 ? cmsFLAGS_NOCACHE : 0);
-
-        #pragma omp parallel for \
-            if (mainprog_ptr->height*mainprog_ptr->width > 8000) \
-            schedule(static)
-        for (unsigned int i = 0; i < mainprog_ptr->height; i++) {
-            /* It is safe to use the same block for input and output,
-               when both are of the same TYPE. */
-            cmsDoTransform(hTransform, row_pointers[i],
-                                       row_pointers[i],
-                                       mainprog_ptr->width);
-        }
-
-        cmsDeleteTransform(hTransform);
-        cmsCloseProfile(hOutProfile);
-        cmsCloseProfile(hInProfile);
-
-        mainprog_ptr->gamma = 0.45455;
-    }
-#endif
-
-    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-
-    mainprog_ptr->file_size = read_data.bytes_read;
-    mainprog_ptr->row_pointers = (unsigned char **)row_pointers;
-
-    return SUCCESS;
-}
-
-static void rwpng_free_chunks(struct rwpng_chunk *chunk) {
-    if (!chunk) return;
-    rwpng_free_chunks(chunk->next);
-    free(chunk->data);
-    free(chunk);
-}
-
-void rwpng_free_image24(png24_image *image)
-{
-    free(image->row_pointers);
-    image->row_pointers = NULL;
-
-    free(image->rgba_data);
-    image->rgba_data = NULL;
-
-    rwpng_free_chunks(image->chunks);
-    image->chunks = NULL;
-}
-
-void rwpng_free_image8(png8_image *image)
-{
-    free(image->indexed_data);
-    image->indexed_data = NULL;
-
-    free(image->row_pointers);
-    image->row_pointers = NULL;
-
-    rwpng_free_chunks(image->chunks);
-    image->chunks = NULL;
-}
-
-pngquant_error rwpng_read_image24(FILE *infile, png24_image *input_image_p, int verbose)
-{
-#if USE_COCOA
-    return rwpng_read_image24_cocoa(infile, input_image_p);
-#else
-    return rwpng_read_image24_libpng(infile, input_image_p, verbose);
-#endif
-}
-
-
-static pngquant_error rwpng_write_image_init(rwpng_png_image *mainprog_ptr, png_structpp png_ptr_p, png_infopp info_ptr_p, int fast_compression)
-{
-    /* could also replace libpng warning-handler (final NULL), but no need: */
-
-    *png_ptr_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, rwpng_error_handler, NULL);
-
-    if (!(*png_ptr_p)) {
-        return LIBPNG_INIT_ERROR;   /* out of memory */
-    }
-
-    *info_ptr_p = png_create_info_struct(*png_ptr_p);
-    if (!(*info_ptr_p)) {
-        png_destroy_write_struct(png_ptr_p, NULL);
-        return LIBPNG_INIT_ERROR;   /* out of memory */
-    }
-
-    /* setjmp() must be called in every function that calls a PNG-writing
-     * libpng function, unless an alternate error handler was installed--
-     * but compatible error handlers must either use longjmp() themselves
-     * (as in this program) or exit immediately, so here we go: */
-
-    if (setjmp(mainprog_ptr->jmpbuf)) {
-        png_destroy_write_struct(png_ptr_p, info_ptr_p);
-        return LIBPNG_INIT_ERROR;   /* libpng error (via longjmp()) */
-    }
-
-    png_set_compression_level(*png_ptr_p, fast_compression ? Z_BEST_SPEED : Z_BEST_COMPRESSION);
-    png_set_compression_mem_level(*png_ptr_p, fast_compression ? 9 : 5); // judging by optipng results, smaller mem makes libpng compress slightly better
-
-    return SUCCESS;
-}
-
-
-static void rwpng_write_end(png_infopp info_ptr_p, png_structpp png_ptr_p, png_bytepp row_pointers)
-{
-    png_write_info(*png_ptr_p, *info_ptr_p);
-
-    png_set_packing(*png_ptr_p);
-
-    png_write_image(*png_ptr_p, row_pointers);
-
-    png_write_end(*png_ptr_p, NULL);
-
-    png_destroy_write_struct(png_ptr_p, info_ptr_p);
-}
-
-static void rwpng_set_gamma(png_infop info_ptr, png_structp png_ptr, double gamma)
-{
-    /* remap sets gamma to 0.45455 */
-    png_set_gAMA(png_ptr, info_ptr, gamma);
-    png_set_sRGB(png_ptr, info_ptr, 0); // 0 = Perceptual
-}
-
-pngquant_error rwpng_write_image8(FILE *outfile, png8_image *mainprog_ptr)
-{
-    png_structp png_ptr;
-    png_infop info_ptr;
-
-    pngquant_error retval = rwpng_write_image_init((rwpng_png_image*)mainprog_ptr, &png_ptr, &info_ptr, mainprog_ptr->fast_compression);
-    if (retval) return retval;
-
-    struct rwpng_write_state write_state;
-    write_state = (struct rwpng_write_state){
-        .outfile = outfile,
-        .maximum_file_size = mainprog_ptr->maximum_file_size,
-        .retval = SUCCESS,
-    };
-    png_set_write_fn(png_ptr, &write_state, user_write_data, user_flush_data);
-
-    // Palette images generally don't gain anything from filtering
-    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_VALUE_NONE);
-
-    rwpng_set_gamma(info_ptr, png_ptr, mainprog_ptr->gamma);
-
-    /* set the image parameters appropriately */
-    int sample_depth;
-#if PNG_LIBPNG_VER > 10400 /* old libpng corrupts files with low depth */
-    if (mainprog_ptr->num_palette <= 2)
-        sample_depth = 1;
-    else if (mainprog_ptr->num_palette <= 4)
-        sample_depth = 2;
-    else if (mainprog_ptr->num_palette <= 16)
-        sample_depth = 4;
-    else
-#endif
-        sample_depth = 8;
-
-    struct rwpng_chunk *chunk = mainprog_ptr->chunks;
-    int chunk_num=0;
-    while(chunk) {
-        png_unknown_chunk pngchunk = {
-            .size = chunk->size,
-            .data = chunk->data,
-            .location = chunk->location,
-        };
-        memcpy(pngchunk.name, chunk->name, 5);
-        png_set_unknown_chunks(png_ptr, info_ptr, &pngchunk, 1);
-
-        #if defined(PNG_HAVE_IHDR) && PNG_LIBPNG_VER < 10600
-        png_set_unknown_chunk_location(png_ptr, info_ptr, chunk_num, pngchunk.location ? pngchunk.location : PNG_HAVE_IHDR);
-        #endif
-
-        chunk = chunk->next;
-        chunk_num++;
-    }
-
-    png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
-      sample_depth, PNG_COLOR_TYPE_PALETTE,
-      0, PNG_COMPRESSION_TYPE_DEFAULT,
-      PNG_FILTER_TYPE_BASE);
-
-    png_set_PLTE(png_ptr, info_ptr, &mainprog_ptr->palette[0], mainprog_ptr->num_palette);
-
-    if (mainprog_ptr->num_trans > 0) {
-        png_set_tRNS(png_ptr, info_ptr, mainprog_ptr->trans, mainprog_ptr->num_trans, NULL);
-    }
-
-    rwpng_write_end(&info_ptr, &png_ptr, mainprog_ptr->row_pointers);
-
-    if (SUCCESS == write_state.retval && write_state.maximum_file_size && write_state.bytes_written > write_state.maximum_file_size) {
-        return TOO_LARGE_FILE;
-    }
-
-    return write_state.retval;
-}
-
-pngquant_error rwpng_write_image24(FILE *outfile, png24_image *mainprog_ptr)
-{
-    png_structp png_ptr;
-    png_infop info_ptr;
-
-    pngquant_error retval = rwpng_write_image_init((rwpng_png_image*)mainprog_ptr, &png_ptr, &info_ptr, 0);
-    if (retval) return retval;
-
-    png_init_io(png_ptr, outfile);
-
-    rwpng_set_gamma(info_ptr, png_ptr, mainprog_ptr->gamma);
-
-    png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
-                 8, PNG_COLOR_TYPE_RGB_ALPHA,
-                 0, PNG_COMPRESSION_TYPE_DEFAULT,
-                 PNG_FILTER_TYPE_BASE);
-
-
-    png_bytepp row_pointers = rwpng_create_row_pointers(info_ptr, png_ptr, mainprog_ptr->rgba_data, mainprog_ptr->height, 0);
-
-    rwpng_write_end(&info_ptr, &png_ptr, row_pointers);
-
-    free(row_pointers);
-
-    return SUCCESS;
-}
-
-
-static void rwpng_warning_stderr_handler(png_structp png_ptr, png_const_charp msg) {
-    fprintf(stderr, "  %s\n", msg);
-}
-
-static void rwpng_warning_silent_handler(png_structp png_ptr, png_const_charp msg) {
-}
-
-static void rwpng_error_handler(png_structp png_ptr, png_const_charp msg)
-{
-    rwpng_png_image  *mainprog_ptr;
-
-    /* This function, aside from the extra step of retrieving the "error
-     * pointer" (below) and the fact that it exists within the application
-     * rather than within libpng, is essentially identical to libpng's
-     * default error handler.  The second point is critical:  since both
-     * setjmp() and longjmp() are called from the same code, they are
-     * guaranteed to have compatible notions of how big a jmp_buf is,
-     * regardless of whether _BSD_SOURCE or anything else has (or has not)
-     * been defined. */
-
-    fprintf(stderr, "  error: %s (libpng failed)\n", msg);
-    fflush(stderr);
-
-    mainprog_ptr = png_get_error_ptr(png_ptr);
-    if (mainprog_ptr == NULL) abort();
-
-    longjmp(mainprog_ptr->jmpbuf, 1);
-}
diff --git a/src/drivers/libimagequant/rwpng.h b/src/drivers/libimagequant/rwpng.h
deleted file mode 100644
index b031710..0000000
--- a/src/drivers/libimagequant/rwpng.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*---------------------------------------------------------------------------
-
-   pngquant:  RGBA -> RGBA-palette quantization program             rwpng.h
-
-  ---------------------------------------------------------------------------
-
-   © 1998-2000 by Greg Roelofs.
-   © 2009-2015 by Kornel Lesiński.
-
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without modification,
-   are permitted provided that the following conditions are met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  ---------------------------------------------------------------------------*/
-
-#ifndef RWPNG_H
-#define RWPNG_H
-
-#include "png.h"  /* if this include fails, you need to install libpng (e.g. libpng-devel package) and run ./configure */
-#include <setjmp.h>
-
-#ifndef USE_COCOA
-#define USE_COCOA 0
-#endif
-
-typedef enum {
-    SUCCESS = 0,
-    MISSING_ARGUMENT = 1,
-    READ_ERROR = 2,
-    INVALID_ARGUMENT = 4,
-    NOT_OVERWRITING_ERROR = 15,
-    CANT_WRITE_ERROR = 16,
-    OUT_OF_MEMORY_ERROR = 17,
-    WRONG_ARCHITECTURE = 18, // Missing SSE
-    PNG_OUT_OF_MEMORY_ERROR = 24,
-    LIBPNG_FATAL_ERROR = 25,
-    WRONG_INPUT_COLOR_TYPE = 26,
-    LIBPNG_INIT_ERROR = 35,
-    TOO_LARGE_FILE = 98,
-    TOO_LOW_QUALITY = 99,
-} pngquant_error;
-
-struct rwpng_chunk {
-    struct rwpng_chunk *next;
-    png_byte *data;
-    png_size_t size;
-    png_byte name[5];
-    png_byte location;
-};
-
-#if USE_LCMS
-typedef enum {
-  NONE = 0,
-  ICCP = 1, // used ICC profile
-  ICCP_WARN_GRAY = 2, // ignore and warn about GRAY ICC profile
-  GAMA_CHRM = 3, // used gAMA and cHARM
-} lcms_transform;
-#endif
-
-typedef struct {
-    jmp_buf jmpbuf;
-    png_uint_32 width;
-    png_uint_32 height;
-    png_size_t file_size;
-    double gamma;
-    unsigned char **row_pointers;
-    unsigned char *rgba_data;
-    struct rwpng_chunk *chunks;
-#if USE_LCMS
-    lcms_transform lcms_status;
-#endif
-} png24_image;
-
-typedef struct {
-    jmp_buf jmpbuf;
-    png_uint_32 width;
-    png_uint_32 height;
-    png_size_t maximum_file_size;
-    double gamma;
-    unsigned char **row_pointers;
-    unsigned char *indexed_data;
-    unsigned int num_palette;
-    unsigned int num_trans;
-    png_color palette[256];
-    unsigned char trans[256];
-    struct rwpng_chunk *chunks;
-    char fast_compression;
-} png8_image;
-
-typedef union {
-    jmp_buf jmpbuf;
-    png24_image png24;
-    png8_image png8;
-} rwpng_png_image;
-
-/* prototypes for public functions in rwpng.c */
-
-void rwpng_version_info(FILE *fp);
-
-pngquant_error rwpng_read_image24(FILE *infile, png24_image *mainprog_ptr, int verbose);
-pngquant_error rwpng_write_image8(FILE *outfile, png8_image *mainprog_ptr);
-pngquant_error rwpng_write_image24(FILE *outfile, png24_image *mainprog_ptr);
-void rwpng_free_image24(png24_image *);
-void rwpng_free_image8(png8_image *);
-
-#endif
diff --git a/src/drivers/libimagequant/viter.c b/src/drivers/libimagequant/viter.c
deleted file mode 100644
index b578c65..0000000
--- a/src/drivers/libimagequant/viter.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-** © 2011-2015 by Kornel Lesiński.
-** All rights reserved.
-** See COPYRIGHT file for full license.
-*/
-
-#include "libimagequant.h"
-#include "pam.h"
-#include "viter.h"
-#include "nearest.h"
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef _OPENMP
-#include <omp.h>
-#else
-#define omp_get_max_threads() 1
-#define omp_get_thread_num() 0
-#endif
-
-/*
- * Voronoi iteration: new palette color is computed from weighted average of colors that map to that palette entry.
- */
-LIQ_PRIVATE void viter_init(const colormap *map, const unsigned int max_threads, viter_state average_color[])
-{
-    memset(average_color, 0, sizeof(average_color[0])*(VITER_CACHE_LINE_GAP+map->colors)*max_threads);
-}
-
-LIQ_PRIVATE void viter_update_color(const f_pixel acolor, const float value, const colormap *map, unsigned int match, const unsigned int thread, viter_state average_color[])
-{
-    match += thread * (VITER_CACHE_LINE_GAP+map->colors);
-    average_color[match].a += acolor.a * value;
-    average_color[match].r += acolor.r * value;
-    average_color[match].g += acolor.g * value;
-    average_color[match].b += acolor.b * value;
-    average_color[match].total += value;
-}
-
-LIQ_PRIVATE void viter_finalize(colormap *map, const unsigned int max_threads, const viter_state average_color[])
-{
-    for (unsigned int i=0; i < map->colors; i++) {
-        double a=0, r=0, g=0, b=0, total=0;
-
-        // Aggregate results from all threads
-        for(unsigned int t=0; t < max_threads; t++) {
-            const unsigned int offset = (VITER_CACHE_LINE_GAP+map->colors) * t + i;
-
-            a += average_color[offset].a;
-            r += average_color[offset].r;
-            g += average_color[offset].g;
-            b += average_color[offset].b;
-            total += average_color[offset].total;
-        }
-
-        if (total && !map->palette[i].fixed) {
-            map->palette[i].acolor = (f_pixel){
-                .a = a / total,
-                .r = r / total,
-                .g = g / total,
-                .b = b / total,
-            };
-        } else {
-            total = i/1024.0;
-        }
-        map->palette[i].popularity = total;
-    }
-}
-
-LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, viter_callback callback, const bool fast_palette)
-{
-    const unsigned int max_threads = omp_get_max_threads();
-    viter_state average_color[(VITER_CACHE_LINE_GAP+map->colors) * max_threads];
-    viter_init(map, max_threads, average_color);
-    struct nearest_map *const n = nearest_init(map, fast_palette);
-    hist_item *const achv = hist->achv;
-    const int hist_size = hist->size;
-
-    double total_diff=0;
-    #pragma omp parallel for if (hist_size > 3000) \
-        schedule(static) default(none) shared(average_color,callback) reduction(+:total_diff)
-    for(int j=0; j < hist_size; j++) {
-        float diff;
-        unsigned int match = nearest_search(n, &achv[j].acolor, achv[j].tmp.likely_colormap_index, &diff);
-        achv[j].tmp.likely_colormap_index = match;
-        total_diff += diff * achv[j].perceptual_weight;
-
-        viter_update_color(achv[j].acolor, achv[j].perceptual_weight, map, match, omp_get_thread_num(), average_color);
-
-        if (callback) callback(&achv[j], diff);
-    }
-
-    nearest_free(n);
-    viter_finalize(map, max_threads, average_color);
-
-    return total_diff / hist->total_perceptual_weight;
-}
diff --git a/src/drivers/libimagequant/viter.h b/src/drivers/libimagequant/viter.h
deleted file mode 100644
index bbbaaa1..0000000
--- a/src/drivers/libimagequant/viter.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef VITER_H
-#define VITER_H
-
-// Spread memory touched by different threads at least 64B apart which I assume is the cache line size. This should avoid memory write contention.
-#define VITER_CACHE_LINE_GAP ((64+sizeof(viter_state)-1)/sizeof(viter_state))
-
-typedef struct {
-    double a, r, g, b, total;
-} viter_state;
-
-typedef void (*viter_callback)(hist_item *item, float diff);
-
-LIQ_PRIVATE void viter_init(const colormap *map, const unsigned int max_threads, viter_state state[]);
-LIQ_PRIVATE void viter_update_color(const f_pixel acolor, const float value, const colormap *map, unsigned int match, const unsigned int thread, viter_state average_color[]);
-LIQ_PRIVATE void viter_finalize(colormap *map, const unsigned int max_threads, const viter_state state[]);
-LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, viter_callback callback, const bool fast_palette);
-
-#endif
diff --git a/src/libMagWrapper/MagPlus.cc b/src/libMagWrapper/MagPlus.cc
index ea29eab..74e8949 100644
--- a/src/libMagWrapper/MagPlus.cc
+++ b/src/libMagWrapper/MagPlus.cc
@@ -231,6 +231,7 @@ MagPlus::MagPlus() : root_(0), superpage_(-1), geographical_(true), mode_(intera
         sceneCreators_["MWIND"] = &MagPlus::wind;
         sceneCreators_["MGRAPH"] = &MagPlus::graph;
  		sceneCreators_["SUPERPAGE"] = &MagPlus::superpage;
+ 		sceneCreators_["LAYER"] = &MagPlus::layer;
         sceneCreators_["PTEXT"] = &MagPlus::ptext;
         sceneCreators_["MTEXT"] = &MagPlus::text;
         sceneCreators_["MLEGEND"] = &MagPlus::legend;
@@ -292,6 +293,21 @@ bool MagPlus::newpage(magics::MagRequest& in)
 	return false;
 }
 
+bool MagPlus::layer(magics::MagRequest& in)
+{
+	
+	in.print();
+	int visibility = in("VISIBILITY");
+	visibility_ = visibility;
+	zindex_ = in("STACKING_ORDER");
+	transparency_ = in("TRANSPARENCY");
+	id_ = (string) in("_ID");
+	layer_ = (string) in("_NAME");
+	
+
+	return false;
+}
+
 
 bool MagPlus::psdriver(magics::MagRequest& in)
 {
@@ -402,7 +418,7 @@ bool MagPlus::page_update(magics::MagRequest& in)
 
 	// get the Metview ID;
 	// reset the page!!!
-	int id = in("METVIEW_ID");
+	int id = in("_ID");
 	FortranViewNodeWrapper* page = pages_[id];
 	page->set(in);
 	FortranViewNodeAttributes* node= page->object();
@@ -417,17 +433,20 @@ bool MagPlus::page_update(magics::MagRequest& in)
 bool MagPlus::page(magics::MagRequest& in)
 {
 	MagLog::dev()<< "page and subpage--->" << endl;
+
 	sceneCreators_["MLEGEND"] = &MagPlus::legend;
 
 
 	while ( !empty() ) pop();
 
 	geographical_ = true;
-	in.print();
+	
 	FortranSceneNodeWrapper scenehelper;
 	scenehelper.set(in);
 
+
 	setIconInfo(in, *scenehelper.object());
+	
 	root_->insert(scenehelper.object());
 
 	push(scenehelper.object());
@@ -436,18 +455,15 @@ bool MagPlus::page(magics::MagRequest& in)
 
 	page_ = 0;
 
-	string def = get(in, "SUBPAGE_MAP_AREA_DEFINITION", "FULL");
-	if ( def == "FULL") {
-		in("SUBPAGE_MAP_AREA_DEFINITION") = in.countValues("SUBPAGE_LOWER_LEFT_LONGITUDE") ? "CORNERS" : "FULL";
-	}
+	
 
 	if ( (string) in("SUBPAGE_MAP_PROJECTION") != "NEXT" ) {
 		FortranViewNodeWrapper* viewhelper = new FortranViewNodeWrapper();
 		viewhelper->set(in);
 		FortranViewNode* view = viewhelper->object();
 
-		string id =  in("METVIEW_ID");
-		int i =  in("METVIEW_ID");
+		string id =  in("_ID");
+		int i =  in("_ID");
 		pages_[i] = viewhelper;
 		if ( !id.empty() )
 		{
@@ -470,7 +486,7 @@ bool MagPlus::page(magics::MagRequest& in)
 		page_ = new FortranViewNodeWrapper();
 		in("SUBPAGE_MAP_PROJECTION") = "cartesian";
 		page_->set(in);
-		int id = in("METVIEW_ID");
+		int id = in("_ID");
 		pages_[id] = page_;
 	}
 
@@ -478,36 +494,53 @@ bool MagPlus::page(magics::MagRequest& in)
 	return false; // do not exit
 }
 
+
+
 bool MagPlus::cartesian(magics::MagRequest& in) {
 
 	string projection = get(in, "MAP_PROJECTION", "cartesian");
-	 in("SUBPAGE_MAP_PROJECTION") = projection;
+ 	in("SUBPAGE_MAP_PROJECTION") = projection;
 
 
-			if ( !page_ ) page_ = new FortranViewNodeWrapper();
-			page_->set(in);
-			FortranViewNode* view = page_->object();
+	if ( !page_ ) page_ = new FortranViewNodeWrapper();
+	page_->set(in);
+	id_ =  (string)in("_ID");
+	in("_ID") = id_;
 
-			string id =  in("METVIEW_ID");
-			if (  !id.empty()  )
-			{
-				string id =  in("METVIEW_ID");
-				view->setInteractiveInfo(id.c_str(),
-				in("ZOOM_NUMBER_OF_LEVELS"), in("ZOOM_CURRENT_LEVEL"));
-			}
-			top()->insert(view);
-			push(view);
+	string zindex = in("STACKING_ORDER");
+	zindex_ = zindex.empty() ? -1 : tonumber(zindex);
+	
+	string visibility = in("VISIBILITY");
+	visibility_ = visibility.empty() ? true : tonumber(visibility);
+	
+	string transparency = in("TRANSPARENCY");
+	transparency_ = transparency.empty() ? 0 : tonumber(transparency);
+	
+
+	layer_ =  (string)in("_NAME");
+	FortranViewNode* view = page_->object();
+	setIconInfo(in, *view);
+	
+	if (  !id_.empty()  )
+	{
+		
+		view->setInteractiveInfo(id_.c_str(),
+		in("ZOOM_NUMBER_OF_LEVELS"), in("ZOOM_CURRENT_LEVEL"));
+	}
+	top()->insert(view);
+	push(view);
 
-			in.print();
+	in.print();
+			
 
-			 map<string,  ObjectCreator >::iterator creator = sceneCreators_.find(projection);
-			   	    if ( creator != sceneCreators_.end() ) {
+	map<string,  ObjectCreator >::iterator creator = sceneCreators_.find(projection);
+    if ( creator != sceneCreators_.end() ) {
 
-			   	    	  (this->*creator->second)(in) ;
-			   	    }
+    	  (this->*creator->second)(in) ;
+    }
 
-            geographical_ = false;
-			return false; // do not exit
+    geographical_ = false;
+	return false; // do not exit
 }
 
 bool MagPlus::cartesianGrid(magics::MagRequest& in) {
@@ -927,6 +960,9 @@ void MagPlus::setIconInfo(magics::MagRequest& mv, MetviewIcon& object)
 		 iconclass =  get(mv, "_VERB", "");
 	string iconid =  get(mv, "_ID", "");
 	object.icon(iconname, iconclass, iconid);
+	if ( layer_.empty() ) 
+		layer_ = "UNKNOW";
+	object.layerInfo(visibility_, zindex_, transparency_, id_, layer_);
 }
 
 bool MagPlus::gribloop(magics::MagRequest& in)
@@ -952,6 +988,7 @@ bool MagPlus::gribloop(magics::MagRequest& in)
 	GribLoopWrapper grib;
 	grib.set(in);
 	setIconInfo(in, *grib.object());
+	
 
 	action->loop(grib.object());
 #else
@@ -1642,6 +1679,7 @@ bool MagPlus::text(magics::MagRequest& in)
 
 	TextVisitorWrapper helper(node);
 	helper.set(in);
+	setIconInfo(in, *helper.object());
 	top()->text(node);
 
 
@@ -1666,6 +1704,7 @@ bool MagPlus::legend(magics::MagRequest& in)
 		legend = new FortranAutomaticLegendVisitor();
 	LegendVisitorWrapper helper(legend);
 	helper.set(in);
+	setIconInfo(in, *helper.object());
 	top()->legend(legend);
 	return false; // do not exit
 }
@@ -1702,9 +1741,9 @@ bool MagPlus::device(magics::MagRequest& in)
 
 void MagPlus::execute( magics::MagRequest& in)
 {
-	cout << "MagPlus::execute-->" << endl;
+	
 	in.print();
-	cout << "<---MagPlus::execute" << endl;
+	
 	try {
 	// Start from a fersh tree!
 #ifndef MAG_NEXT
diff --git a/src/libMagWrapper/MagPlus.h b/src/libMagWrapper/MagPlus.h
index cfeae9b..7d138d9 100644
--- a/src/libMagWrapper/MagPlus.h
+++ b/src/libMagWrapper/MagPlus.h
@@ -100,6 +100,7 @@ protected:
 	bool dataloop(magics::MagRequest&);
 	bool bufr(magics::MagRequest&);
 	bool visdef(magics::MagRequest&);
+	bool layer(magics::MagRequest&);
 	
 #ifdef HAVE_ODB
 	bool geoodb(magics::MagRequest&);
@@ -150,6 +151,13 @@ protected:
 	MetviewMode mvMode_;
 	FortranViewNodeWrapper* page_;
 	vector<Visdef*>* currentMulti_;
+	
+	// Information related to the current layer
+	bool visibility_;
+	int zindex_;
+	int transparency_;
+	string id_;
+	string layer_;
 
 #ifdef MAGICS_QT
 	//! Keep the instance of the QtDrver!
diff --git a/src/params/AdvancedColourTechnique.xml b/src/params/AdvancedColourTechnique.xml
new file mode 100644
index 0000000..287dc6f
--- /dev/null
+++ b/src/params/AdvancedColourTechnique.xml
@@ -0,0 +1,30 @@
+<magics>
+<class inherits="ColourTechnique" name="GradientColourTechnique" directory="visualisers" action="pcont">
+<!--
+(C) Copyright 1996-2016 ECMWF.
+
+This software is licensed under the terms of the Apache Licence Version 2.0
+which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+In applying this licence, ECMWF does not waive the privileges and immunities 
+granted to it by virtue of its status as an intergovernmental organisation nor
+does it submit to any jurisdiction.
+-->
+
+	
+  	<parameter member="colours" to="stringarray" default="stringarray()" from="stringarray" name="contour_gradients_colour_list">
+         		<documentation>  Colour used at the stops : the gradeint will be calculated between 2 consecutive ones.		</documentation>
+  	</parameter>
+
+    <parameter member="values" to="floatarray" default="floatarray()" from="floatarray" name="contour_gradients_value_list">
+            <documentation>  List of stops.   </documentation>
+    </parameter>
+
+    <parameter member="techniques" to="stringarray" default="stringarray()" from="stringarray" name="contour_gradients_technique_list">
+            <documentation>  Technique to apply to compute the gradients linear-clockwise/linear-anticlockwise   </documentation>
+    </parameter>
+  	
+  	 <parameter member="steps" to="intarray" default="intarray()" from="intarray" name="contour_gradients_step_list">
+            <documentation>  Nimber of steps to compute for each interval </documentation>
+    </parameter>
+</class>
+</magics>
diff --git a/src/params/Akima474Method.xml b/src/params/Akima474Method.xml
index 91a2bec..a887a59 100644
--- a/src/params/Akima474Method.xml
+++ b/src/params/Akima474Method.xml
@@ -26,4 +26,5 @@ does it submit to any jurisdiction.
          		<documentation> Y Resolution 		</documentation>
          		<release>Magics++0.1		</release>
   	</parameter>
-</class></magics>
+</class>
+</magics>
diff --git a/src/params/ArrowPlotting.xml b/src/params/ArrowPlotting.xml
index b6a22de..a72e75e 100644
--- a/src/params/ArrowPlotting.xml
+++ b/src/params/ArrowPlotting.xml
@@ -90,4 +90,7 @@ does it submit to any jurisdiction.
   	<parameter member="legend_unit" to="string" default="m/s" from="string" name="wind_arrow_legend_text">
         		<documentation> Text to be used as units in the legend text 		</documentation>
   	</parameter>
+  	<parameter member="fixed_velocity" to="float" default="0.0" from="float" name="wind_arrow_fixed_velocity">
+        		<documentation>Fixed velocity arrows (m/s).		</documentation>
+  	</parameter>  
 </class></magics>
diff --git a/src/params/Axis.xml b/src/params/Axis.xml
index 1909f8a..5d1eb58 100644
--- a/src/params/Axis.xml
+++ b/src/params/Axis.xml
@@ -141,7 +141,7 @@ does it submit to any jurisdiction.
   	<parameter member="tick" to="bool" default="on" from="string" name="axis_tick">
          		<documentation> Plot ticks 		</documentation>
           		<set name="axis_tick_interval" value="on">		</set>  
-          		<set name="axis_tick_position" value="on">		</set>
+          		<set name="axis_tick_position_list" value="on">		</set>
   		  		<set name="axis_tick_colour" value="on">		</set>
   		  		<set name="axis_tick_size" value="on">		</set>
   		  		<set name="axis_tick_thickness" value="on">		</set>  
diff --git a/src/params/Bar.xml b/src/params/Bar.xml
index 53ae0ed..e9609de 100644
--- a/src/params/Bar.xml
+++ b/src/params/Bar.xml
@@ -13,7 +13,7 @@ does it submit to any jurisdiction.
             <documentation>   Orientation of the bars : Vertical or horizontal   </documentation>
     </parameter>
 
-  	<parameter xml="width" from="float" name="graph_bar_width" default="INT_MAX" member="width" to="float">
+  	<parameter xml="width" from="float" name="graph_bar_width" default="-1" member="width" to="float">
          		<documentation> The width of a bar in a bar chart 		</documentation>
   	</parameter>
   	<parameter member="justification" to="Justification" default="centre" from="string" name="graph_bar_justification">
diff --git a/src/params/BothValuePlotMethod.xml b/src/params/BothValuePlotMethod.xml
index d9c58bb..812efb1 100644
--- a/src/params/BothValuePlotMethod.xml
+++ b/src/params/BothValuePlotMethod.xml
@@ -32,4 +32,9 @@ does it submit to any jurisdiction.
          		<documentation> Table number of marker index. See Appendix for Plotting Attributes 		</documentation>
          		<release>0.2		</release>
   	</parameter>
+
+	<parameter member="position" to="string" default="top" from="string" name="contour_grid_value_position"
+         			values="right/left/bottom/top">
+         		<documentation> Position of the value </documentation>
+	</parameter>
 </class></magics>
diff --git a/src/params/Boundaries.xml b/src/params/Boundaries.xml
index 21e5f79..c668fe9 100644
--- a/src/params/Boundaries.xml
+++ b/src/params/Boundaries.xml
@@ -59,7 +59,7 @@ does it submit to any jurisdiction.
     		<set name="map_administrative_boundaries_thickness" value="on">		</set>
 	</parameter>
 
-	<parameter from="stringarray" name="map_administrative_boundaries_countries_list" default="stringarray()" member="administrative_list" to="stringarray" values="AGO:Angola/DZA:Algeria/EGY:Egypt/BGD:Bangladesh/NAM:Namibia/BOL:Bolivia/GHA:Ghana/CCK:Australia CCK/PAK:Pakistan/LBY:Libya/MYS:Malaysia/PRK:Korea, North/TZA:Tanzania/BWA:Botswana/PRY:Paraguay/SAU:Saudi Arabia/MRT:Mauritania/CHL:Chile/CHN:China/LAO:Laos/GIB:United Kingdom GIB/GIN:Guinea/FIN:Finland/URY:Uruguay/NPL:Nepal/CXR:Austra [...]
+	<parameter from="stringarray" name="map_administrative_boundaries_countries_list" default="stringarray()" member="administrative_list" to="stringarray" values="Afghanistan:AFG/Algeria:DZA/Angola:AGO/Argentina:ARG/Australia:AUS/Australia CCK:CCK/Australia CXR:CXR/Australia HMD:HMD/Australia NFK:NFK/Austria:AUT/Baikonur Cosmodrome:RUS/Bangladesh:BGD/Belarus:BLR/Bolivia:BOL/Botswana:BWA/Brazil:BRA/Cameroon:CMR/Canada:CAN/Central African Republic:CAF/Chad:TCD/Chile:CHL/China:CHN/Colombia:CO [...]
   		<documentation>List of countries for which to show second level administrative borders. The convention used is the 3 Letters ISO Codes 3166 for countries 		</documentation>
 	</parameter> 
 
diff --git a/src/params/CMakeLists.txt b/src/params/CMakeLists.txt
index fb88d36..e9f26b8 100644
--- a/src/params/CMakeLists.txt
+++ b/src/params/CMakeLists.txt
@@ -14,6 +14,7 @@ BothValuePlotMethod.xml
 Boundaries.xml
 CalculateColourTechnique.xml
 GradientsColourTechnique.xml
+PaletteColourTechnique.xml
 CalculateHeightTechnique.xml
 CalmIndicator.xml
 CartesianTransformation.xml
@@ -87,7 +88,10 @@ LegendMethod.xml
 LegendVisitor.xml
 
 LevelListSelectionType.xml
+
 LevelSelection.xml
+
+
 ListColourTechnique.xml
 ListHeightTechnique.xml
 LogarithmicAxisMethod.xml
@@ -239,7 +243,7 @@ YRegularCoordinate.xml
 		EpsBufr.xml
 		ImageCalculateColourTechnique.xml
 ImageListColourTechnique.xml
-ImagePlotting.xml
+#ImagePlotting.xml
 InputMatrix.xml
 InputMatrixIrregularInterpretor.xml
 InputMatrixRegularInterpretor.xml
@@ -281,15 +285,19 @@ endif()
 if( HAVE_NETCDF )
 	list( APPEND _common_xmls 
 		NetcdfDecoder.xml
-		NetcdfGeoMatrixInterpretor.xml
-		NetcdfGeoPolarMatrixInterpretor.xml
-		NetcdfGeoVectorInterpretor.xml
-		NetcdfGeopointsInterpretor.xml
 		NetcdfInterpretor.xml
-		NetcdfMatrixInterpretor.xml
+		NetcdfXYpointsInterpretor.xml
 		NetcdfOrcaInterpretor.xml
+		NetcdfGeopointsInterpretor.xml
+		NetcdfGeoPolarMatrixInterpretor.xml
+		NetcdfGeoVectorInterpretor.xml
+		NetcdfGuessInterpretor.xml
 		NetcdfVectorInterpretor.xml
-		NetcdfXYpointsInterpretor.xml )
+		NetcdfGeoMatrixInterpretor.xml
+		NetcdfMatrixInterpretor.xml
+
+
+		)
 endif()
 
 if ( HAVE_ODB )
diff --git a/src/params/Cities.xml b/src/params/Cities.xml
index 1044000..5db69b4 100644
--- a/src/params/Cities.xml
+++ b/src/params/Cities.xml
@@ -23,6 +23,10 @@ does it submit to any jurisdiction.
   		<release>Work in progress		</release>
  		<documentation>Font style used for city names.		</documentation>
 	</parameter>
+	<parameter member="blanking" to="bool" default="on" from="string" name="map_cities_text_blanking">
+ 		<documentation>Use Blanking when plotting the cityes names .		</documentation>
+	</parameter>
+
 
 	<parameter member="font_size" to="float" default="2.5" from="float" name="map_cities_font_size">
  		<documentation>Font size of city names.		</documentation>
diff --git a/src/params/FortranRootSceneNode.xml b/src/params/FortranRootSceneNode.xml
index 5c64342..356610f 100644
--- a/src/params/FortranRootSceneNode.xml
+++ b/src/params/FortranRootSceneNode.xml
@@ -30,7 +30,7 @@ does it submit to any jurisdiction.
          		<documentation> Colour of super page frame 		</documentation>
   	</parameter>
 
-    <parameter member="theme" to="string" default="xxmagics" from="string" name="super_page_theme">
+    <parameter member="theme" to="string" default="dark" from="string" name="super_page_theme">
             <documentation>   Theme to apply to the content of the document : the default magics will ensure that no theme is applied and ensure fully backwards compatibility  </documentation>
     </parameter>
   	
diff --git a/src/params/FortranSceneNode.xml b/src/params/FortranSceneNode.xml
index 8893fd8..9d60181 100644
--- a/src/params/FortranSceneNode.xml
+++ b/src/params/FortranSceneNode.xml
@@ -62,13 +62,13 @@ does it submit to any jurisdiction.
   
  
   
-P  	<parameter from="float" name="page_x_gap" default="0.0cm" member="page_x_gap" to="float" implemented="no">
+ 	<parameter from="float" name="page_x_gap" default="0.0" member="page_x_gap" to="float" implemented="no">
          		<documentation> Gap between pages in X direction 		</documentation>
          		<release>Magics++0.2		</release>
          		<release_info>Not fully implemented		</release_info>
   	</parameter>
 
-  	<parameter from="float" name="page_y_gap" default="0.0cm" member="page_y_gap" to="float" implemented="no">
+  	<parameter from="float" name="page_y_gap" default="0.0" member="page_y_gap" to="float" implemented="no">
          		<documentation> Gap between pages in Y direction 		</documentation>
          		<release>Magics++0.2		</release>
           		<release_info>Not fully implemented		</release_info>
diff --git a/src/params/GradientsColourTechnique.xml b/src/params/GradientsColourTechnique.xml
index 7e6011e..08853d3 100644
--- a/src/params/GradientsColourTechnique.xml
+++ b/src/params/GradientsColourTechnique.xml
@@ -16,21 +16,18 @@ does it submit to any jurisdiction.
          
   	</parameter>
 
-    <parameter member="stops" to="floatarray" default="floatarray()" from="floatarray" name="contour_gradients_waypoint_list">
-            <documentation>  List of waypoints.   </documentation>
-        
-    </parameter>
+    
     <parameter member="stop_method" to="string" default="both" from="string" name="contour_gradients_waypoint_method" values='both/ignore/left/right'>
             <documentation> waypoints at the left, right, middle of the interval.   </documentation>
         
     </parameter>
 
-    <parameter member="technique" to="string" default="linear" from="string" name="contour_gradients_technique" values='linear/hcl/hsl'>
-            <documentation>  Technique to apply to compute the gradients linear-clockwise/linear-anticlockwise   </documentation>
+    <parameter member="technique" to="string" default="rgb" from="string" name="contour_gradients_technique" values='rgb/hcl/hsl'>
+            <documentation>  Technique to apply to compute the gradients rgb/hcl/hsl   </documentation>
            
     </parameter>
     <parameter member="technique_direction" to="string" default="clockwise" from="string" name="contour_gradients_technique_direction" values='clockwise/anti_clockwise/shortest/longest'>
-            <documentation>  Technique to apply to compute the gradients linear-clockwise/linear-anticlockwise   </documentation>
+            <documentation>  Technique to apply to compute the gradients clockwise/anticlockwise   </documentation>
            
     </parameter>
   	
diff --git a/src/params/IsoPlot.xml b/src/params/IsoPlot.xml
index 3db2a35..743a2fa 100644
--- a/src/params/IsoPlot.xml
+++ b/src/params/IsoPlot.xml
@@ -17,7 +17,10 @@ does it submit to any jurisdiction.
         		<documentation> Used in wrep to produce special legend such as spaghetti! 		</documentation>
         		<release>2.10		</release>
     	</parameter>
-  
+        <parameter from="int" name="contour_threads" visible="no" default="4" member="user_thread" to="int" documented="off">
+                    <documentation> NUmber of threads used to optimise the contouring  (possible 1, 4 or 9)       </documentation>
+                   
+            </parameter>
     	<parameter from="float" name="contour_internal_reduction_factor" visible="no" default="4" member="resolution" to="float" documented="off">
         		<documentation> Internal factor for contouring   		</documentation>
         		<release>2.10		</release> 
@@ -126,6 +129,7 @@ does it submit to any jurisdiction.
         		<option xml="count" fortran="count" include="CountSelectionType.h" name="CountSelectionType">		</option>
         		<option xml="interval" fortran="interval" include="IntervalSelectionType.h" name="IntervalSelectionType">		</option>
         		<option xml="list" fortran="level_list" include="LevelListSelectionType.h" name="LevelListSelectionType">		</option>
+               
     	</parameter>
 
 
diff --git a/src/params/IsoShading.xml b/src/params/IsoShading.xml
index 4d21be6..b665be1 100644
--- a/src/params/IsoShading.xml
+++ b/src/params/IsoShading.xml
@@ -41,7 +41,8 @@ does it submit to any jurisdiction.
         		<option xml="calculate" fortran="calculate" include="CalculateColourTechnique.h" name="CalculateColourTechnique">		</option>
         		<option xml="list" fortran="list" include="ListColourTechnique.h" name="ListColourTechnique">		</option>
             <option xml="gradients" fortran="gradients" include="GradientsColourTechnique.h" name="GradientsColourTechnique">   </option>
-  	</parameter>
+  	        <option xml="palette" fortran="palette" include="ColourTechnique.h" name="PaletteColourTechnique">   </option>
+    </parameter>
 
   	<metview_parameter from="string" name="contour_shade_label_blanking" default="on" metview="hidden" member="" to="bool">
          		<documentation> Added for backwards compatibility with existing Metview Contour icons/macros 		</documentation>
diff --git a/src/params/NetcdfDecoder.xml b/src/params/NetcdfDecoder.xml
index 5af18e7..6771d3c 100644
--- a/src/params/NetcdfDecoder.xml
+++ b/src/params/NetcdfDecoder.xml
@@ -16,10 +16,11 @@ does it submit to any jurisdiction.
 
     
 
-     	<parameter member="interpretor" to="NetcdfInterpretor" default="matrix" from="string" name="netcdf_type">
+     	<parameter member="interpretor" to="NetcdfInterpretor" default="guess" from="string" name="netcdf_type">
+            <option xml="guess" fortran="guess" include="NetcdfInterpretor.h" name="NetcdfGuessInterpretor">    </option>
         		<option xml="matrix" fortran="matrix" include="NetcdfMatrixInterpretor.h" name="NetcdfMatrixInterpretor">		</option>
                 
-           		<option xml="geomatrix" fortran="geomatrix" include="NetcdfGeoMatrixInterpretor.h" name="NetcdfGeoMatrixInterpretor">		</option>
+           	<option xml="geomatrix" fortran="geomatrix" include="NetcdfGeoMatrixInterpretor.h" name="NetcdfGeoMatrixInterpretor">		</option>
           
           		<option xml="vector" fortran="vector" include="NetcdfVectorInterpretor.h" name="NetcdfVectorInterpretor">		</option>
            		<option xml="geovector" fortran="geovector" include="NetcdfVectorInterpretor.h" name="NetcdfGeoVectorInterpretor">		</option>
diff --git a/src/params/NetcdfGeoMatrixInterpretor.xml b/src/params/NetcdfGeoMatrixInterpretor.xml
index 8054666..43a2bff 100644
--- a/src/params/NetcdfGeoMatrixInterpretor.xml
+++ b/src/params/NetcdfGeoMatrixInterpretor.xml
@@ -1,5 +1,5 @@
 <magics>
-<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfGeoMatrixInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
+<class inherits="NetcdfInterpretor" xmltag="geomatrix" name="NetcdfGeoMatrixInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -10,39 +10,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-        	<parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name representing the latitude dimension		</documentation>
-        	</parameter> 
-         	<parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name representing the longitude dimension		</documentation>
-        	</parameter>
-         	<parameter member="longitude_sample" to="int" default="1" from="int" name="netcdf_longitude_sample">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>sample the input data by taking aa longitude every nth longitude		</documentation>
-        	</parameter>
-         	<parameter member="latitude_sample" to="int" default="1" from="int" name="netcdf_latitude_sample">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>sample the input data by taking a latitude every nth latitude		</documentation>
-        	</parameter>
-        	<parameter member="x_component" to="string" default="" from="string" name="netcdf_x_component_variable">
-              		<release>Magics++2.6		</release>
-              		<documentation>Variable name representing the x component of the vector		</documentation>
-        	</parameter> 
-         	<parameter member="y_component" to="string" default="" from="string" name="netcdf_y_component_variable">
-             		<release>Magics++2.6		</release>
-            		<documentation>Variable name representing the y component of the vector		</documentation>
-        	</parameter>
-        	<parameter member="colour_component" to="string" default="" from="string" name="netcdf_colour_component_variable">
-             		<release>Magics++2.6		</release>
-            		<documentation>Variable name representing the colour component of the vector ( in case of coloured wind)		</documentation>
-        	</parameter>
-            	<parameter member="primary_index" to="string" default="longitude" from="string" name="netcdf_matrix_primary_index">
-             		<release>Magics++2.4		</release>
-            		<documentation> Primary index latitude/longitude		</documentation>
-        	</parameter>
+    
 </class></magics>
diff --git a/src/params/NetcdfGeoPolarMatrixInterpretor.xml b/src/params/NetcdfGeoPolarMatrixInterpretor.xml
index 4e0ff57..f9599f3 100644
--- a/src/params/NetcdfGeoPolarMatrixInterpretor.xml
+++ b/src/params/NetcdfGeoPolarMatrixInterpretor.xml
@@ -10,20 +10,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-        	<parameter member="speed" to="string" default="" from="string" name="netcdf_speed_component_variable">
-              		<release>Magics++2.6		</release>
-              		<documentation>Variable name representing the speed component of the vector		</documentation>
-        	</parameter> 
-         	<parameter member="direction" to="string" default="" from="string" name="netcdf_direction_component_variable">
-             		<release>Magics++2.6		</release>
-            		<documentation>Variable name representing the direction component of the vector		</documentation>
-        	</parameter>
-        	<parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
-              
-              		<documentation>Variable name representing the latitude dimension		</documentation>
-        	</parameter> 
-         	<parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
-            
-            		<documentation>Variable name representing the longitude dimension		</documentation>
-        	</parameter>
+        	
 </class></magics>
diff --git a/src/params/NetcdfGeoVectorInterpretor.xml b/src/params/NetcdfGeoVectorInterpretor.xml
index 11b8368..486543c 100644
--- a/src/params/NetcdfGeoVectorInterpretor.xml
+++ b/src/params/NetcdfGeoVectorInterpretor.xml
@@ -1,5 +1,6 @@
 <magics>
-<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfGeoVectorInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf" include="NetcdfVectorInterpretor.h">
+<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfGeoVectorInterpretor" directory="decoders" prefix="netcdf" 
+	action="pnetcdf" include="NetcdfVectorInterpretor.h">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -10,21 +11,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-        	<parameter member="x_component" to="string" default="" from="string" name="netcdf_x_component_variable">
-              		<release>Magics++2.6		</release>
-              		<documentation>Variable name representing the x component of the vector		</documentation>
-        	</parameter> 
-         	<parameter member="y_component" to="string" default="" from="string" name="netcdf_y_component_variable">
-             		<release>Magics++2.6		</release>
-            		<documentation>Variable name representing the y component of the vector		</documentation>
-        	</parameter>
-        	<parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name representing the latitude dimension		</documentation>
-        	</parameter> 
-         	<parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name representing the longitude dimension		</documentation>
-        	</parameter>
+    
 </class></magics>
diff --git a/src/params/NetcdfGeopointsInterpretor.xml b/src/params/NetcdfGeopointsInterpretor.xml
index 0715c93..bc06de5 100644
--- a/src/params/NetcdfGeopointsInterpretor.xml
+++ b/src/params/NetcdfGeopointsInterpretor.xml
@@ -10,12 +10,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-  	<parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
-             
-              		<documentation>Variable name representing the x dimension		</documentation>
-        	</parameter> 
-         	<parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
-            
-            		<documentation>Variable name representing the y dimension		</documentation>
-        	</parameter>
- </class></magics>
+    
+</class></magics>
diff --git a/src/params/ObsCloud.xml b/src/params/NetcdfGuessInterpretor.xml
similarity index 69%
copy from src/params/ObsCloud.xml
copy to src/params/NetcdfGuessInterpretor.xml
index 879d3a1..138db24 100644
--- a/src/params/ObsCloud.xml
+++ b/src/params/NetcdfGuessInterpretor.xml
@@ -1,5 +1,6 @@
 <magics>
-<class directory="visualisers" action_routine="pobs" prefix="obs" xmltag="cloud" name="ObsCloud">
+<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfGuessInterpretor" directory="decoders" 
+    prefix="netcdf" action="pnetcdf" include="NetcdfInterpretor.h">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -10,7 +11,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-
-    	
-    	</parameter>    
+    
 </class></magics>
diff --git a/src/params/NetcdfInterpretor.xml b/src/params/NetcdfInterpretor.xml
index 7cee4e9..3150293 100644
--- a/src/params/NetcdfInterpretor.xml
+++ b/src/params/NetcdfInterpretor.xml
@@ -10,49 +10,118 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-		<documentation>
-		This object contains this attributes to set how to load the data from the file.
+        <documentation>
+        This object contains this attributes to set how to load the data from the file.
         It is possible to load only a subarray of the data, by setting the dimensions.
-		</documentation>
-        	<parameter member="path" to="string" default="" from="string" name="netcdf_filename">
-            		<documentation>Path of the file to be read		</documentation>
-        	</parameter>
+        </documentation>
+            <parameter member="path" to="string" default="" from="string" name="netcdf_filename">
+                    <documentation>Path of the file to be read      </documentation>
+            </parameter>
 
-        	<parameter member="dimension" to="stringarray" default="stringarray()" from="stringarray" name="netcdf_dimension_setting">
-            		<metview default="" class="">  		</metview>
-            		<documentation> Extract only of a subset of variables [ex: level:100:500]	</documentation>
-        	</parameter>
-        	<parameter from="string" name="netcdf_dimension_setting_method" default="value" member="dimension_method" to="string" values="index/value">
-            		 <documentation>Method used to specify how to interpret the extraction of a subset, the range can by specified by value or by index 		</documentation>
-        	</parameter>
+            <parameter member="dimension" to="stringarray" default="stringarray()" from="stringarray" name="netcdf_dimension_setting">
+                    <metview default="" class="">       </metview>
+                    <documentation> Extract only of a subset of variables [ex: level:100:500]   </documentation>
+            </parameter>
+            <parameter member="time_dimension" to="string" default="" from="string" name="netcdf_time_dimension_setting">
+                    <documentation> Extract only the specified times : date specified in Human readable format YYY-MM-DD HH:MM:00   </documentation>
+            </parameter>
+            <parameter member="level_dimension" to="string" default="" from="string" name="netcdf_level_dimension_setting">
+                    <documentation> Extract only the specified level   </documentation>
+            </parameter>
+              <parameter member="number_dimension" to="string" default="" from="string" name="netcdf_number_dimension_setting">
+                    <documentation> Extract only the specified number   </documentation>
+            </parameter>
+            <parameter from="string" name="netcdf_dimension_setting_method" default="value" member="dimension_method" to="string" values="index/value">
+                     <documentation>Method used to specify how to interpret the extraction of a subset, the range can by specified by value or by index         </documentation>
+            </parameter>
+            <parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
+                  <release>Magics++0.1    </release>
+                  <documentation>Variable name representing the latitude dimension    </documentation>
+          </parameter> 
+          <parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
+                <metview default="" class="">       </metview>
+                <release>Magics++0.1    </release>
+                <documentation>Variable name representing the longitude dimension   </documentation>
+          </parameter>
+          <parameter member="speed" to="string" default="" from="string" name="netcdf_speed_component_variable">
+                  <release>Magics++2.6    </release>
+                  <documentation>Variable name representing the speed component of the vector   </documentation>
+          </parameter> 
+          <parameter member="direction" to="string" default="" from="string" name="netcdf_direction_component_variable">
+                <release>Magics++2.6    </release>
+                <documentation>Variable name representing the direction component of the vector   </documentation>
+          </parameter>
         
-         	<parameter member="field" to="string" default="" from="string" name="netcdf_value_variable">
-              		<documentation>Variable to plot</documentation>
-        	</parameter> 	
-        	<parameter member="u_component" to="string" default="" from="string" name="netcdf_x_component_variable">
-              		<documentation>x_component for vector plotting</documentation>
-        	</parameter> 
-       		<parameter member="v_component" to="string" default="" from="string" name="netcdf_y_component_variable">
-              		<documentation>y_component for vector plotting</documentation>
-        	</parameter> 
+            <parameter member="field" to="string" default="" from="string" name="netcdf_value_variable">
+                    <documentation>Variable to plot</documentation>
+            </parameter>    
+            <parameter member="x_component" to="string" default="" from="string" name="netcdf_x_component_variable">
+                    <documentation>x_component for vector plotting</documentation>
+            </parameter> 
+            <parameter member="y_component" to="string" default="" from="string" name="netcdf_y_component_variable">
+                    <documentation>y_component for vector plotting</documentation>
+            </parameter> 
+            <parameter member="colour_component" to="string" default="" from="string" name="netcdf_colour_component_variable">
+                <release>Magics++2.6    </release>
+                <documentation>Variable name representing the colour component of the vector ( in case of coloured wind)    </documentation>
+          </parameter>
        
-          	<parameter member="scaling" to="float" default="1" from="float" name="netcdf_field_scaling_factor">
-            		<documentation>Scaling factor to multiply the field value by		</documentation>
-        	</parameter>
-         	<parameter member="offset" to="float" default="0" from="float" name="netcdf_field_add_offset">
-            		<documentation>Offset added to the field values		</documentation>
-           	</parameter>
-           	<parameter member="missing_attribute" to="string" default="_FillValue" from="string" name="netcdf_missing_attribute">
-            		<documentation>Attribute indicating the value used to indicate a missing value in the data		</documentation>
-           	</parameter>  
-            	<parameter member="reference" to="string" default="0" from="string" name="netcdf_reference_date" visible="false">
-            		<documentation>attribute indicating  the reference date		</documentation>
-           	</parameter> 
-           	<parameter member="suppress_below" to="float" default="-1.0e+21" from="float" name="netcdf_field_suppress_below">
-         		<documentation> Values in the input field(s) below this value are to be suppressed, i.e. not to be taken into consideration for plotting purposes 		</documentation>
-  	</parameter>
+            <parameter member="scaling" to="float" default="1" from="float" name="netcdf_field_scaling_factor">
+                    <documentation>Scaling factor to multiply the field value by        </documentation>
+            </parameter>
+            <parameter member="offset" to="float" default="0" from="float" name="netcdf_field_add_offset">
+                    <documentation>Offset added to the field values     </documentation>
+            </parameter>
+            <parameter member="missing_attribute" to="string" default="_FillValue" from="string" name="netcdf_missing_attribute">
+                    <documentation>Attribute indicating the value used to indicate a missing value in the data      </documentation>
+            </parameter>  
+                <parameter member="reference" to="string" default="0" from="string" name="netcdf_reference_date" visible="false">
+                    <documentation>attribute indicating  the reference date     </documentation>
+            </parameter> 
+            <parameter member="suppress_below" to="float" default="-1.0e+21" from="float" name="netcdf_field_suppress_below">
+                <documentation> Values in the input field(s) below this value are to be suppressed, i.e. not to be taken into consideration for plotting purposes       </documentation>
+    </parameter>
 
-  	<parameter member="suppress_above" to="float" default="1.0e+21" from="float" name="netcdf_field_suppress_above">
-         		<documentation> Values in the input field(s) above this value are to be suppressed, i.e not to be taken into consideration for plotting purposes 		</documentation>
-  	</parameter>
+    <parameter member="suppress_above" to="float" default="1.0e+21" from="float" name="netcdf_field_suppress_above">
+                <documentation> Values in the input field(s) above this value are to be suppressed, i.e not to be taken into consideration for plotting purposes        </documentation>
+    </parameter>
+   	
+    <parameter member="x" to="string" default="x" from="string" name="netcdf_x_variable">
+                    <release>Magics++0.1        </release>
+                    <documentation>Variable name for the x values       </documentation>
+            </parameter> 
+            <parameter member="x2" to="string" default="x2" from="string" name="netcdf_x2_variable">
+                    <release>Magics++0.1        </release>
+                    <documentation>Variable name for the auxiliary x values (used in CurveArea)     </documentation>
+            </parameter> 
+            <parameter member="y" to="string" default="y" from="string" name="netcdf_y_variable">
+            
+                    <release>Magics++0.1        </release>
+                    <documentation>Variable name for the y values       </documentation>
+            </parameter> 
+            <parameter member="y2" to="string" default="y2" from="string" name="netcdf_y2_variable">
+            
+                    <release>Magics++0.1        </release>
+                    <documentation>Variable name for the auxiliary y values (used in CurveArea)     </documentation>
+            </parameter>
+            <parameter member="aux_x" to="string" default="" from="string" name="netcdf_x_auxiliary_variable">
+             		<release>Magics++0.1		</release>
+        		<documentation>variable can used to define geoline definition.		</documentation>
+        	</parameter>  
+         	<parameter member="geo_x_convention" to="string" default="lonlat" from="string" name="netcdf_x_geoline_convention">
+        
+        		<documentation>Geoline Convention used lonlat or latlon		</documentation>
+        	</parameter>  
+          	<parameter member="geo_y_convention" to="string" default="lonlat" from="string" name="netcdf_y_geoline_convention">
+        
+        		<documentation>Geoline Convention used lonlat or latlon		</documentation>
+        	</parameter>  
+        	<parameter member="aux_y" to="string" default="" from="string" name="netcdf_y_auxiliary_variable">
+             		<release>Magics++0.1		</release>
+        		<documentation>variable can used to define geoline definition.		</documentation>
+        	</parameter>
+            	<parameter member="primary_index" to="string" default="longitude" from="string" name="netcdf_matrix_primary_index">
+             		<release>Magics++2.4		</release>
+            		<documentation> Primary index latitude/longitude		</documentation>
+        	</parameter>
 </class></magics>
diff --git a/src/params/NetcdfMatrixInterpretor.xml b/src/params/NetcdfMatrixInterpretor.xml
index 0bfbccd..8069dfe 100644
--- a/src/params/NetcdfMatrixInterpretor.xml
+++ b/src/params/NetcdfMatrixInterpretor.xml
@@ -1,5 +1,5 @@
 <magics>
-<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfMatrixInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
+<class inherits="NetcdfInterpretor" xmltag="xtmatrix" name="NetcdfMatrixInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -11,32 +11,5 @@ does it submit to any jurisdiction.
 -->
 
         
-         	<parameter member="y" to="string" default="y" from="string" name="netcdf_y_variable">
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name representing the y dimension		</documentation>
-        	</parameter>
-        	<parameter member="x" to="string" default="x" from="string" name="netcdf_x_variable">
-             		<release>Magics++0.1		</release>
-        		<documentation>Variable name representing the x dimension		</documentation>
-        	</parameter> 
-        	<parameter member="aux_x" to="string" default="" from="string" name="netcdf_x_auxiliary_variable">
-             		<release>Magics++0.1		</release>
-        		<documentation>variable can used to define geoline definition.		</documentation>
-        	</parameter>  
-         	<parameter member="geo_x_convention" to="string" default="lonlat" from="string" name="netcdf_x_geoline_convention">
-        
-        		<documentation>Geoline Convention used lonlat or latlon		</documentation>
-        	</parameter>  
-          	<parameter member="geo_y_convention" to="string" default="lonlat" from="string" name="netcdf_y_geoline_convention">
-        
-        		<documentation>Geoline Convention used lonlat or latlon		</documentation>
-        	</parameter>  
-        	<parameter member="aux_y" to="string" default="" from="string" name="netcdf_y_auxiliary_variable">
-             		<release>Magics++0.1		</release>
-        		<documentation>variable can used to define geoline definition.		</documentation>
-        	</parameter>
-            	<parameter member="primary_index" to="string" default="longitude" from="string" name="netcdf_matrix_primary_index">
-             		<release>Magics++2.4		</release>
-            		<documentation> Primary index latitude/longitude		</documentation>
-        	</parameter>
+         
 </class></magics>
diff --git a/src/params/NetcdfOrcaInterpretor.xml b/src/params/NetcdfOrcaInterpretor.xml
index f64628b..379d106 100644
--- a/src/params/NetcdfOrcaInterpretor.xml
+++ b/src/params/NetcdfOrcaInterpretor.xml
@@ -10,28 +10,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-        	<parameter member="latitude" to="string" default="latitude" from="string" name="netcdf_latitude_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name representing the latitude dimension		</documentation>
-        	</parameter> 
-         	<parameter member="longitude" to="string" default="longitude" from="string" name="netcdf_longitude_variable">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name representing the longitude dimension		</documentation>
-        	</parameter>
-         	<parameter member="longitude_sample" to="int" default="1" from="int" name="netcdf_longitude_sample">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>sample the input data by taking aa longitude every nth longitude		</documentation>
-        	</parameter>
-         	<parameter member="latitude_sample" to="int" default="1" from="int" name="netcdf_latitude_sample">
-            		<metview default="" class="">   		</metview>
-             		<release>Magics++0.1		</release>
-            		<documentation>sample the input data by taking a latitude every nth latitude		</documentation>
-        	</parameter>
-       
-            	<parameter member="primary_index" to="string" default="longitude" from="string" name="netcdf_matrix_primary_index">
-             		<release>Magics++2.4		</release>
-            		<documentation> Primary index latitude/longitude		</documentation>
-        	</parameter>
+        	
 </class></magics>
diff --git a/src/params/NetcdfVectorInterpretor.xml b/src/params/NetcdfVectorInterpretor.xml
index dd34de1..14cd850 100644
--- a/src/params/NetcdfVectorInterpretor.xml
+++ b/src/params/NetcdfVectorInterpretor.xml
@@ -1,5 +1,5 @@
 <magics>
-<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfVectorInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
+<class inherits="NetcdfInterpretor" xmltag="vector" name="NetcdfVectorInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -10,21 +10,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-        	<parameter member="x_component" to="string" default="" from="string" name="netcdf_x_component_variable">
-              		<release>Magics++2.6		</release>
-              		<documentation>Variable name representing the x component of the vector		</documentation>
-        	</parameter> 
-         	<parameter member="y_component" to="string" default="" from="string" name="netcdf_y_component_variable">
-             		<release>Magics++2.6		</release>
-            		<documentation>Variable name representing the y component of the vector		</documentation>
-        	</parameter>
-        	<parameter member="y" to="string" default="y" from="string" name="netcdf_y_position_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name representing the x dimension		</documentation>
-        	</parameter> 
-         	<parameter member="x" to="string" default="x" from="string" name="netcdf_x_position_variable">
-            		<metview default="" class="">   		</metview>
-            
-            		<documentation>Variable name representing the y dimension		</documentation>
-        	</parameter>
+    
 </class></magics>
diff --git a/src/params/NetcdfXYpointsInterpretor.xml b/src/params/NetcdfXYpointsInterpretor.xml
index afe96da..2eaaeb9 100644
--- a/src/params/NetcdfXYpointsInterpretor.xml
+++ b/src/params/NetcdfXYpointsInterpretor.xml
@@ -1,5 +1,6 @@
 <magics>
-<class inherits="NetcdfInterpretor" xmltag="xypoints" name="NetcdfXYpointsInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf" include="NetcdfGeopointsInterpretor.h">
+<class inherits="NetcdfInterpretor" xmltag="geopoints" name="NetcdfXYpointsInterpretor" directory="decoders" prefix="netcdf" action="pnetcdf"
+		include="NetcdfGeopointsInterpretor.h">
 <!--
 (C) Copyright 1996-2016 ECMWF.
 
@@ -10,22 +11,5 @@ granted to it by virtue of its status as an intergovernmental organisation nor
 does it submit to any jurisdiction.
 -->
 
-  	<parameter member="x" to="string" default="x" from="string" name="netcdf_x_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name for the x values		</documentation>
-        	</parameter> 
-        	<parameter member="x2" to="string" default="x2" from="string" name="netcdf_x2_variable">
-              		<release>Magics++0.1		</release>
-              		<documentation>Variable name for the auxiliary x values (used in CurveArea)		</documentation>
-        	</parameter> 
-         	<parameter member="y" to="string" default="y" from="string" name="netcdf_y_variable">
-            
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name for the y values		</documentation>
-        	</parameter> 
-        	<parameter member="y2" to="string" default="y2" from="string" name="netcdf_y2_variable">
-            
-             		<release>Magics++0.1		</release>
-            		<documentation>Variable name for the auxiliary y values (used in CurveArea)		</documentation>
-        	</parameter>
- </class></magics>
+    
+</class></magics>
diff --git a/src/params/ObsCloud.xml b/src/params/ObsCloud.xml
index 879d3a1..e6833f8 100644
--- a/src/params/ObsCloud.xml
+++ b/src/params/ObsCloud.xml
@@ -12,5 +12,4 @@ does it submit to any jurisdiction.
 
 
     	
-    	</parameter>    
 </class></magics>
diff --git a/src/params/PaletteColourTechnique.xml b/src/params/PaletteColourTechnique.xml
new file mode 100644
index 0000000..12d7c84
--- /dev/null
+++ b/src/params/PaletteColourTechnique.xml
@@ -0,0 +1,37 @@
+<magics>
+  <class inherits="ColourTechnique" include="ColourTechnique.h" name="PaletteColourTechnique" directory="visualisers" action="pcont">
+<!--
+(C) Copyright 1996-2016 ECMWF.
+
+This software is licensed under the terms of the Apache Licence Version 2.0
+which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+In applying this licence, ECMWF does not waive the privileges and immunities 
+granted to it by virtue of its status as an intergovernmental organisation nor
+does it submit to any jurisdiction.
+-->
+
+	
+  	<parameter member="palette" to="string" default="string" from="string" name="contour_palette_name">
+         		<documentation>  Colour used at the stops : the gradeint will be calculated between 2 consecutive ones.		</documentation>
+         
+  	</parameter>
+
+    <parameter from="string" name="contour_palette_policy" default="lastone" member="palette_policy" to="ListPolicy">
+                <documentation> What to do if the list of colours is smaller that the list of levels: lastone/cycle   </documentation>
+    </parameter>
+
+    <parameter from="string" name="contour_palette_levels_setting" default="off" member="levels_setting" to="bool">
+                <documentation> What to do if the list of colours is smaller that the list of levels: lastone/cycle   </documentation>
+    </parameter>
+
+    <parameter from="float" name="contour_palette_min_level" default="INT_MAX" member="min" to="float">
+                <documentation> What to do if the list of colours is smaller that the list of levels: lastone/cycle   </documentation>
+    </parameter>
+
+    <parameter from="float" name="contour_palette_max_level" default="INT_MAX" member="max" to="float">
+                <documentation> What to do if the list of colours is smaller that the list of levels: lastone/cycle   </documentation>
+    </parameter>
+
+  
+  </class>
+</magics>
diff --git a/src/params/ValuePlotMethod.xml b/src/params/ValuePlotMethod.xml
index 1420c10..3aaae3c 100644
--- a/src/params/ValuePlotMethod.xml
+++ b/src/params/ValuePlotMethod.xml
@@ -52,4 +52,13 @@ does it submit to any jurisdiction.
          		<release>0.2		</release>
          		<release>Quality is not yet implemented. Expected Magics++0.3		</release>
   	</parameter>
+
+	<parameter member="justification" to="Justification" default="centre" from="string" name="contour_grid_value_justification">
+         		<documentation>  (LEFT/CENTRE/RIGHT) </documentation>
+	</parameter>
+
+	<parameter member="vertical_align" to="string" default="base" from="string" name="contour_grid_value_vertical_align"
+         			values="normal/top/cap/half/base/bottom">
+         		<documentation> (NORMAL/TOP/CAP/HALF/BASE/BOTTOM) </documentation>
+	</parameter>
 </class></magics>
diff --git a/src/visualisers/ArrowPlotting.cc b/src/visualisers/ArrowPlotting.cc
index abb0205..e0269b5 100644
--- a/src/visualisers/ArrowPlotting.cc
+++ b/src/visualisers/ArrowPlotting.cc
@@ -39,6 +39,13 @@ void ArrowPlotting::operator()(bool north, const PaperPoint& point, double x, do
 
 
    Colour colour = this->colour(*colour_, x, y, val);
+   //// RV Ajout support fleches a taille fixe ////
+   if ( fixed_velocity_ > 0 && !(zero(fixed_velocity_)) && !(zero(speed)) ) {
+	   double ratio = fixed_velocity_ / speed;
+	   x *= ratio;
+	   y *= ratio;
+   }
+   //// RV ////
    if ( north )
 	   northArrow(colour)->push_back(ArrowPoint(x, y, point));
    else 
diff --git a/src/visualisers/AutomaticContourMethod.h b/src/visualisers/AutomaticContourMethod.h
index b3c937a..62a00a0 100644
--- a/src/visualisers/AutomaticContourMethod.h
+++ b/src/visualisers/AutomaticContourMethod.h
@@ -64,17 +64,14 @@ public:
         MatrixHandler data(matrix);
         MatrixHandler* pMatrixHandler;
         if ( matrix.akimaEnable() == false ) {
-                    if  ( matrix.delegate() ) {
-                        return new DelegateMatrixHandler(matrix);
-                    }
-        	        ContourMethod * pContourMethod =new  ContourMethod();
+        	
+            ContourMethod * pContourMethod =new  ContourMethod();
 
                     pMatrixHandler = pContourMethod->handler(matrix, owner);
 
                     MagLog::debug() << "Linear contouring, "    << "\n";
-                    return pMatrixHandler;
-
-                   
+                    //return pMatrixHandler;
+                    return new DelegateMatrixHandler(matrix);
         }
 
         double fGeoAreaWidth;
diff --git a/src/visualisers/Axis.cc b/src/visualisers/Axis.cc
index 9cd3629..91fd827 100644
--- a/src/visualisers/Axis.cc
+++ b/src/visualisers/Axis.cc
@@ -91,8 +91,10 @@ void Axis::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
 	// First we create the layer!
 	// and push It to the parent layer!
 	StaticLayer* axis = new NoDataLayer(this);
-	axis->id(iconName_);
-	axis->name(iconName_);
+
+	
+	axis->icon(*this);
+	
 	layer.add(axis);
 
 	for  (vector<LayoutVisitor*>::iterator visitor = visitors.begin(); visitor != visitors.end(); ++visitor) {
diff --git a/src/visualisers/Bar.cc b/src/visualisers/Bar.cc
index 0db3f52..4ae756a 100644
--- a/src/visualisers/Bar.cc
+++ b/src/visualisers/Bar.cc
@@ -96,7 +96,7 @@ void Bar::vertical(CustomisedPointsList& points, BasicGraphicsObjectContainer& o
 	double next =  (**points.begin())["x"];
 	double x, top, bottom, left, right;
 	
-	if (width_ == INT_MAX) {
+	if (width_ == -1) {
 		if ( points.size() > 1 ) 
 			width_ = abs((*points[0])["x"] - (*points[1])["x"])*0.8;
 		else 
@@ -155,7 +155,7 @@ void Bar::horizontal(CustomisedPointsList& points, BasicGraphicsObjectContainer&
 	double next =  (**points.begin())["y"];
 	double y, top, bottom, left, right;
 	
-	if (width_ == INT_MAX) {
+	if (width_ == -1) {
 		if ( points.size() > 1 ) 
 			width_ = abs((*points[0])["y"] - (*points[1])["y"])*0.8;
 		else 
diff --git a/src/visualisers/BothValuePlotMethod.h b/src/visualisers/BothValuePlotMethod.h
index 4062bbd..1d1a7ac 100644
--- a/src/visualisers/BothValuePlotMethod.h
+++ b/src/visualisers/BothValuePlotMethod.h
@@ -72,12 +72,26 @@ protected:
 	 void reset() { marker_ = 0; }
  
     virtual void add(const PaperPoint& xy) {    
+        static map<string, TextSymbol::TextPosition> poshandlers;
+        if ( poshandlers.empty() ) {
+            poshandlers["none"] = TextSymbol::M_NONE;
+            poshandlers["left"] = TextSymbol::M_LEFT;
+            poshandlers["top"] = TextSymbol::M_ABOVE;
+            poshandlers["bottom"] = TextSymbol::M_BELOW;
+            poshandlers["right"] = TextSymbol::M_RIGHT;
+            poshandlers["centre"] = TextSymbol::M_CENTRE;
+        }
         if (!marker_) {
             marker_ = new TextSymbol();
-            marker_->position(Symbol::M_ABOVE);
+            map<string, TextSymbol::TextPosition>::iterator pos =
+                    poshandlers.find(lowerCase(position_));
+            TextSymbol::TextPosition position =
+                    ( pos != poshandlers.end()) ? pos->second : TextSymbol::M_ABOVE;
+            marker_->position(position);
             marker_->setMarker(markerIndex_);
             marker_->setColour(*markerColour_);
             marker_->setHeight(markerHeight_);
+            marker_->blanking(false);
             MagFont font;
             font.size(this->height_);
             font.colour(*this->colour_);
diff --git a/src/visualisers/CalcStreamlines.cc b/src/visualisers/CalcStreamlines.cc
index f3f9254..51cd626 100644
--- a/src/visualisers/CalcStreamlines.cc
+++ b/src/visualisers/CalcStreamlines.cc
@@ -114,9 +114,9 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 	if( str_lines )
 		{
 			for(int ii=0; ii<linenum; ii++)
-				delete str_lines[ii]; 
+				delete str_lines[ii];
 			delete [] str_lines;
-			str_lines = 0x0; 
+			str_lines = 0x0;
 		}
 	linenum = 0;
 
@@ -154,7 +154,9 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 
 
 	// x_min and x_per are used for ShiftPeriod function
-	float x_min = 0.f, x_per = 360.f; // for grids on the Earth
+//	float x_min = 0.f, x_per = 360.f; // for grids on the Earth
+	float x_min = startx, x_per = 360.f; // RV for grids on the Earth
+
 	if( !gs_geo )
 		{
 			// for grids not on the Earth
@@ -180,7 +182,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 
 	// The ordinal number of the current line we follow
 	int act_line = 0;
-	
+
 	// Coordinates of a streamline
 	float *x = new float[ gridsize ];
 	float *y = new float[ gridsize ];
@@ -191,8 +193,8 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 	// Active cell and side in the cell
 	int act_cell;
 	int act_side;
-	float side_shift_x[4] = { 0, 0.5*dx, 0, -0.5*dx};
-	float side_shift_y[4] = { 0.5*dy, 0, -0.5*dy, 0};
+	float side_shift_x[4] = { 0, 0.5f*dx, 0, -0.5f*dx};
+	float side_shift_y[4] = { 0.5f*dy, 0, -0.5f*dy, 0};
 
 	// Coordinate of center of the active cell
 	float cell_x, cell_y;
@@ -381,7 +383,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 											break;
 										stop_need = 2; // Let's give an other chance!
 									}
-    
+
 								// act_dir is in [0;2*M__PI)
 								if( direction == 1 )
 									act_dir = ShiftPeriod_(dir[act_cell]+M__PI, 0, 2*M__PI);
@@ -400,12 +402,12 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 								if( gs_geo )
 									if( cell_y >= 90 || cell_y <= -90 )
 										break;
-    
+
 								float cos_cell_y = 1.f;
 								if( gs_geo )
 									cos_cell_y = cos(cell_y*M_PI_180);
 								int cell_shift = 0;
-    
+
 								// Check which side we are on
 								if( act_side == 1 )
 									{
@@ -420,13 +422,13 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												else
 													break;
 											}
-    
+
 										if( act_dir == 0 )
 											{
 												// Northward
 												x[pos] = x[pos-direction];
 												y[pos] = cell_y + dy_2;
-												
+
 												cell_shift = ys*nx;
 												act_side = 2;
 											}
@@ -451,7 +453,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 														// Westward
 														x[pos] = ShiftPeriod(cell_x - dx_2, x_min, x_per);
 														y[pos] = new_y;
-    
+
 														cell_shift = - xs;
 														act_side = 1;
 													}
@@ -462,7 +464,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																// Northward
 																x[pos] = ShiftPeriod(x[pos-direction] + (cell_y + dy_2 - y[pos-direction]) * tan_dir / cos_cell_y, x_min, x_per);
 																y[pos] = cell_y + dy_2;
-																
+
 																cell_shift = ys*nx;
 																act_side = 2;
 															}
@@ -471,7 +473,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																// Southward
 																x[pos] = ShiftPeriod(x[pos-direction] - (y[pos-direction] - cell_y + dy_2) * tan_dir / cos_cell_y, x_min, x_per);
 																y[pos] = cell_y - dy_2;
-																
+
 																cell_shift = - ys*nx;
 																act_side = 0;
 															}
@@ -491,13 +493,13 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												else
 													break;
 											}
-    
+
 										if( act_dir == 0 )
 											{
 												// Northward
 												x[pos] = x[pos-direction];
 												y[pos] = cell_y + dy_2;
-												
+
 												cell_shift = ys*nx;
 												act_side = 2;
 											}
@@ -506,7 +508,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												// Southward
 												x[pos] = x[pos-direction];
 												y[pos] = cell_y - dy_2;
-    
+
 												cell_shift = - ys*nx;
 												act_side = 0;
 											}
@@ -522,7 +524,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 														// Eastward
 														x[pos] = ShiftPeriod(cell_x + dx_2, x_min, x_per);
 														y[pos] = new_y;
-    
+
 														cell_shift = xs;
 														act_side = 3;
 													}
@@ -533,7 +535,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																// Northward
 																x[pos] = ShiftPeriod(x[pos-direction] + (cell_y + dy_2 - y[pos-direction]) * tan_dir / cos_cell_y, x_min, x_per);
 																y[pos] = cell_y + dy_2;
-																
+
 																cell_shift = ys*nx;
 																act_side = 2;
 															}
@@ -542,7 +544,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																// Southward
 																x[pos] = ShiftPeriod(x[pos-direction] - (y[pos-direction] - cell_y + dy_2) * tan_dir / cos_cell_y, x_min, x_per);
 																y[pos] = cell_y - dy_2;
-																
+
 																cell_shift = - ys*nx;
 																act_side = 0;
 															}
@@ -562,13 +564,13 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												else
 													break;
 											}
-    
+
 										if( act_dir == M__PI_2 )
 											{
 												// Eastward
 												x[pos] = ShiftPeriod(cell_x + dx_2, x_min, x_per);
 												y[pos] = y[pos-direction];
-												
+
 												cell_shift = xs;
 												act_side = 3;
 											}
@@ -577,7 +579,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												// Westward
 												x[pos] = ShiftPeriod(cell_x - dx_2, x_min, x_per);
 												y[pos] = y[pos-direction];
-    
+
 												cell_shift = - xs;
 												act_side = 1;
 											}
@@ -593,7 +595,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 														// Southward
 														x[pos] = ShiftPeriod(new_x, x_min, x_per);
 														y[pos] = cell_y - dy_2;
-    
+
 														cell_shift = - ys*nx;
 														act_side = 0;
 													}
@@ -607,7 +609,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																	y[pos] = y[pos-direction] + CalcLonDist(cell_x + dx_2,x[pos-direction]) / tan_dir * cos_cell_y;
 																else
 																	y[pos] = y[pos-direction] + fabs(cell_x + dx_2 - x[pos-direction]) / tan_dir * cos_cell_y;
-																
+
 																cell_shift = xs;
 																act_side = 3;
 															}
@@ -619,7 +621,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																	y[pos] = y[pos-direction] - CalcLonDist(x[pos-direction], cell_x - dx_2) / tan_dir * cos_cell_y;
 																else
 																	y[pos] = y[pos-direction] - fabs(x[pos-direction] - cell_x + dx_2) / tan_dir * cos_cell_y;
-																
+
 																cell_shift = - xs;
 																act_side = 1;
 															}
@@ -639,13 +641,13 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												else
 													break;
 											}
-    
+
 										if( act_dir == (float)M__PI_2 )
 											{
 												// Eastward
 												x[pos] = ShiftPeriod(cell_x + dx_2, x_min, x_per);
 												y[pos] = y[pos-direction];
-												
+
 												cell_shift = xs;
 												act_side = 3;
 											}
@@ -654,7 +656,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 												// Westward
 												x[pos] = ShiftPeriod(cell_x - dx_2, x_min, x_per);
 												y[pos] = y[pos-direction];
-    
+
 												cell_shift = - xs;
 												act_side = 1;
 											}
@@ -670,7 +672,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 														// Northward
 														x[pos] = ShiftPeriod(new_x, x_min, x_per);
 														y[pos] = cell_y + dy_2;
-    
+
 														cell_shift = ys*nx;
 														act_side = 2;
 													}
@@ -684,7 +686,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																	y[pos] = y[pos-direction] + CalcLonDist(cell_x + dx_2, x[pos-direction]) / tan_dir * cos_cell_y;
 																else
 																	y[pos] = y[pos-direction] + fabs(cell_x + dx_2 - x[pos-direction]) / tan_dir * cos_cell_y;
-																
+
 																cell_shift = xs;
 																act_side = 3;
 															}
@@ -696,7 +698,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 																	y[pos] = y[pos-direction] - CalcLonDist(x[pos-direction], cell_x - dx_2) / tan_dir * cos_cell_y;
 																else
 																	y[pos] = y[pos-direction] - fabs(x[pos-direction] - cell_x + dx_2) / tan_dir * cos_cell_y;
-																
+
 																cell_shift = - xs;
 																act_side = 1;
 															}
@@ -801,7 +803,7 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 							}
 
 					} // for(direction = forward, backward)
-				
+
 				// Add a new line section with 'len' length
 				if( len > 3 )
 					{
@@ -834,11 +836,11 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
                               	linenum++;
 								OneLineClass** new_str_lines = new OneLineClass*[linenum];
 								for(int ii=0; ii<linenum-1; ii++)
-									new_str_lines[ii] = str_lines[ii]; 
+									new_str_lines[ii] = str_lines[ii];
 								new_str_lines[linenum-1] = line;
-													    
+
 								delete [] str_lines;
-								str_lines = new_str_lines; 
+								str_lines = new_str_lines;
 							}
 					}
 
@@ -859,4 +861,3 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
 
 	return 1;
 }
-
diff --git a/src/visualisers/CalmIndicator.h b/src/visualisers/CalmIndicator.h
index 8abcca8..7356b8d 100644
--- a/src/visualisers/CalmIndicator.h
+++ b/src/visualisers/CalmIndicator.h
@@ -56,7 +56,7 @@ public:
 	    dot_ = new Symbol();
 		dot_->setColour(colour_);
 	    dot_->setMarker(15);
-	    dot_->setHeight(0.1);
+	    dot_->setHeight(height_/3.0);
 		task.push_back(dot_);	
 	}
 		
diff --git a/src/visualisers/CellShading.cc b/src/visualisers/CellShading.cc
index 8d6ead5..84f3d84 100644
--- a/src/visualisers/CellShading.cc
+++ b/src/visualisers/CellShading.cc
@@ -29,7 +29,7 @@
 using namespace magics;
 
 
-CellShading::CellShading() : shading_("grid")
+CellShading::CellShading() : shading_("grid"), adaptive_(false)
 {
 }
 
@@ -109,7 +109,6 @@ void CellShading::operator()(IsoPlot* iso, MatrixHandler& data, BasicGraphicsObj
 
 		if (   distance_plot < distance_data ) {
 			iso->isoline(data, parent);
-			//cout << "Grid Shading" << endl;
 			MagLog::info() << "Magics will use grid shading" << endl;
 			adaptive_ = true;
 			return;
@@ -118,18 +117,26 @@ void CellShading::operator()(IsoPlot* iso, MatrixHandler& data, BasicGraphicsObj
 	
 	Image* image = new Image();
 	image->set(rows, columns);
-	
+	MagLog::debug() << "Creation of a bitmap [rows, columns] --> [" << rows << ", " << columns << "]" << endl;  
+
 	double lat = maxr;
 	double lon = minc;
 	for ( int row = 0; row < rows; row++) {
 		lon = minc;
 		for ( int column = 0; column < columns; column++) {
-			projection.revert(PaperPoint(lon, lat), point);			
+			projection.revert(PaperPoint(lon, lat), point);		
+			lon += stepc;
+			if (point.x_ == -1000 && point.x_ == -1000)  {
+				
+				image->push_back(0);
+				continue;
+			}
+
 			value = (magCompare(method_, "nearest") ) ?
 					data.nearest(point.y(), point.x()) :  data.interpolate(point.y(), point.x());
 		
 			image->push_back(map_.find(value,0));
-			lon += stepc;
+			
 		}
 		lat -= stepr;
 	}
@@ -264,8 +271,13 @@ CellArray* CellShading::array(MatrixHandler& matrix, IntervalMap<int>& range,
 		const Transformation& transformation, int width, int height,
 		float resolution, const string& technique)
 {
-		if  ( adaptive_ )
+		if  ( adaptive_ ) {
+			shading_ = "grid";
 			return new GridArray(matrix, range, transformation, width, height, resolution, "middle");
-		else 
-			return 0;
+			
+		}
+		else  {
+			shading_ = "cell";
+			return new CellArray(matrix, range, transformation, width, height, resolution, technique);
+		}
 }
diff --git a/src/visualisers/Cities.cc b/src/visualisers/Cities.cc
index 24d712a..80ca5db 100644
--- a/src/visualisers/Cities.cc
+++ b/src/visualisers/Cities.cc
@@ -122,7 +122,8 @@ void Cities::operator()(const map<string, string>&, BasicGraphicsObjectContainer
      text->setColour(*marker_colour_);
      MagFont font(font_name_, font_style_, font_size_);
      font.colour(*font_colour_);
-     text->font(font);
+     text->font(font); 
+     text->blanking(blanking_);
     decoder.customisedPoints(need, points);
     vector<CustomisedPoint*> filter;
     for (CustomisedPointsList::iterator point = points.begin(); point != points.end(); ++point)
@@ -135,25 +136,9 @@ void Cities::operator()(const map<string, string>&, BasicGraphicsObjectContainer
     			(**point)["y"] = xy.y();
     			filter.push_back(*point);
     		}
-    		//if ( transformation.in(geo) && !(*point)->identifier().empty()) {
-    			//text->push_back(transformation(geo), (*point)->identifier());
-    		//}
-    }
-
-    /*
-    for (CustomisedPointsList::iterator p1 = filter.begin(); p1 != filter.end(); ++p1) {
-    	if ( (**p1)["plot"] == -1 ) {
-    		(**p1)["plot"] = 1;
-    		for (CustomisedPointsList::iterator p2  = p1; p2 != filter.end(); ++p2) {
     		
-    			if ( distance(*p1, *p2) < 1) {
-    				(**p2)["plot"] = 0;
-    			}
-    			
-    		}
-    	}
     }
-    */
+
     
     for (vector<CustomisedPoint*>::iterator point = filter.begin(); point != filter.end(); ++point) {
     	vector<CustomisedPoint*>::iterator last = std::remove_if(filter.begin(), filter.end(), Radius(radius, **point));
diff --git a/src/visualisers/Coastlines.cc b/src/visualisers/Coastlines.cc
index 2806189..42413b5 100644
--- a/src/visualisers/Coastlines.cc
+++ b/src/visualisers/Coastlines.cc
@@ -52,8 +52,9 @@ void Coastlines::visit(DrawingVisitor& parent)
 	// if needed Find the Style, according to the theme ..
 	if ( style_.size() ) {
 		StyleLibrary styles(theme(), "coastlines");
-		const map<string, string>& style = styles.get(style_);
-		set(style);
+		Style::Definition style;
+		if ( styles.find(style_, style) )
+			set(style);
 		
 	}
 	(*coastlines_)(parent);
@@ -116,8 +117,9 @@ void Coastlines::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
     // First we create the layer!
 	// and push It to the parent layer! 
 		layer_ = new NoDataLayer(this);
-		layer_->id(iconName_);
-		layer_->name(iconName_);
+		
+		layer_->icon(*this);
+		
 		layer.add(layer_);
 	}
 	for  (vector<LayoutVisitor*>::iterator visitor = visitors.begin(); visitor != visitors.end(); ++visitor) {
diff --git a/src/visualisers/ColourTechnique.cc b/src/visualisers/ColourTechnique.cc
index 0cb053b..1941919 100644
--- a/src/visualisers/ColourTechnique.cc
+++ b/src/visualisers/ColourTechnique.cc
@@ -193,5 +193,32 @@ void ColourTechnique::visit(LegendVisitor& legend)
 	}
 
 }
+PaletteColourTechnique::PaletteColourTechnique() 
+{
+// bnbnZZ
+}
+
+PaletteColourTechnique::~PaletteColourTechnique() 
+{
+
+}
+
+void PaletteColourTechnique::set(LevelSelection& out, LevelSelection& in, ColourTable& table, int nb) const
+{
+
+}
+
+
+void PaletteColourTechnique::print(ostream& out)  const
+{
+    out << "GradientsColourTechnique[";
+    out << "]";
+}
+
+void PaletteColourTechnique::set(const ColourTechniqueInterface& attributes)
+{
+   
+}
+
 
 
diff --git a/src/visualisers/ColourTechnique.h b/src/visualisers/ColourTechnique.h
index a849b58..930546c 100644
--- a/src/visualisers/ColourTechnique.h
+++ b/src/visualisers/ColourTechnique.h
@@ -28,7 +28,7 @@
 #include "ColourTable.h"
 #include "IntervalMap.h"
 
-
+#include "PaletteColourTechniqueAttributes.h"
 namespace magics {
 
 class LevelSelection;
@@ -117,6 +117,49 @@ private:
 
 };
 
+
+class PaletteColourTechnique: public ColourTechnique, public PaletteColourTechniqueAttributes {
+
+public:
+    PaletteColourTechnique();
+    virtual ~PaletteColourTechnique();
+    void set(const map<string, string>& map) { 
+        PaletteColourTechniqueAttributes::set(map);
+        }
+    void set(const XmlNode& node) { 
+        PaletteColourTechniqueAttributes::set(node);
+    }
+     bool accept(const string& node) { return PaletteColourTechniqueAttributes::accept(node); }
+    
+    void set(const ColourTechniqueInterface&);
+    
+    
+    virtual ColourTechnique* clone() const {
+        PaletteColourTechnique* object = new PaletteColourTechnique();
+        object->copy(*this);
+        return object;
+    }
+    
+protected:
+     void set(LevelSelection&, LevelSelection&, ColourTable&, int) const;
+     //! Method to print string about this class on to a stream of type ostream (virtual).
+     virtual void print(ostream&) const; 
+
+private:
+    //! Copy constructor - No copy allowed
+    PaletteColourTechnique(const PaletteColourTechnique&);
+    //! Overloaded << operator to copy - No copy allowed
+    PaletteColourTechnique& operator=(const PaletteColourTechnique&);
+
+// -- Friends
+    //! Overloaded << operator to call print().
+    friend ostream& operator<<(ostream& s,const PaletteColourTechnique& p)
+        { p.print(s); return s; }
+
+};
+
+
+
 template<>
 class MagTranslator<string, ColourTechnique> { 
 public:
diff --git a/src/visualisers/Contour.cc b/src/visualisers/Contour.cc
index 2184841..35b6c4a 100644
--- a/src/visualisers/Contour.cc
+++ b/src/visualisers/Contour.cc
@@ -79,37 +79,41 @@ void Contour::operator()(Data& data, BasicGraphicsObjectContainer& parent)
     	ContourLibrary* library = MagTranslator<string, ContourLibrary>()(setting_);
 
     		// Here we try call the Contour libry to set up visual properties...
-    		MetaDataCollector needId,needAttributes;
+    		MetaDataCollector request,needAttributes;
     		map<string, string> attributes;
     		
 
-		library->askId(needId);
-		data.visit(needId);
+		library->askId(request);
+		data.visit(request);
 
 
-		if(library->checkId(needId,needAttributes))
+		if(library->checkId(request,needAttributes))
 		{			
     			data.visit(needAttributes);
     			needAttributes["theme"] = theme_;
     			library->getAttributes(needAttributes,attributes);
-
-    			this->set(attributes);
+    			if ( !legend_ ) 
+    				attributes["legend"] ="off";
+    			set(attributes);
     	}
 		else {
-			library->getAttributes(needId,attributes);
+			request["theme"] = theme_;
+			library->getAttributes(request,attributes);
+			if ( !legend_ ) 
+				attributes["legend"] ="off";
+			set(attributes);
 		}
 		delete library;
 
 
     data.getReady(parent.transformation());
     if ( !data.valid() ) {
-		MagLog::error() << "Invalid data for contouring" << endl;
-		return;
-    }
+		throw MagicsException("Invalid data for contouring");
+	}
 	MatrixHandler* box =  data.matrix().getReady(parent.transformation());
 	if (!box  ){
-		MagLog::error() << "Invalid data for contouring" << endl;
-		return;
+		throw MagicsException("Invalid data for contouring");
+		
 	}
 	if ( !box->rows() ||  !box->columns() ) {
 		(*this->contour_)(data, parent);
@@ -161,7 +165,7 @@ void Contour::operator()(Data& data, BasicGraphicsObjectContainer& parent)
     }
     catch (MagicsException& e) 
     {
-    	// Do nothing! 
+    	throw e ; // forwarding exception
     }
 }
 
diff --git a/src/visualisers/ContourLibrary.cc b/src/visualisers/ContourLibrary.cc
index a7e10b3..18424d3 100644
--- a/src/visualisers/ContourLibrary.cc
+++ b/src/visualisers/ContourLibrary.cc
@@ -304,7 +304,10 @@ void WebLibrary::askId(MetaDataCollector& request)
 	setCriteria(request, "param");
 	setCriteria(request, "levtype");
 	setCriteria(request, "level");
-	
+
+	setCriteria(request, "standard_name");
+	setCriteria(request, "units");
+	setCriteria(request, "grid_mapping");
 	
 }
 
@@ -322,8 +325,10 @@ void WebLibrary::getAttributes(MetaDataCollector& data, map<string, string>& con
 {
 		
 		StyleLibrary styles(data["theme"], "contours");
-		const map<string, string>& style = styles.get(data["param"]);
-		contour = style;
+		map<string, string> style;
+
+		if ( styles.find(data, style) )
+			contour = style;
 	
 }
 
diff --git a/src/visualisers/ContourLibrary.h b/src/visualisers/ContourLibrary.h
index 44631ad..1638fc4 100644
--- a/src/visualisers/ContourLibrary.h
+++ b/src/visualisers/ContourLibrary.h
@@ -170,7 +170,7 @@ public:
 	// set the meta data to be collected
 	void askId(MetaDataCollector&);
 
-	bool checkId(MetaDataCollector&,MetaDataCollector&) { return true; }
+	bool checkId(MetaDataCollector&,MetaDataCollector&) { return false; }
 	void setCriteria(MetaDataCollector&, const string&);
 
 	// set the map to set the contour!
diff --git a/src/visualisers/EpsGraph.cc b/src/visualisers/EpsGraph.cc
index 68f1564..f9804f7 100644
--- a/src/visualisers/EpsGraph.cc
+++ b/src/visualisers/EpsGraph.cc
@@ -1045,10 +1045,9 @@ void EpsLight::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
 		for (vector<double>::iterator e = eps.begin(); e != eps.begin(); ++e) {
 			if ( same(*e, 0) )
 				*e = 0;
-	        MagLog::debug() << *e << " ";
 	    }
-	    MagLog::debug() << endl;
 
+	        
         double epsmin, eps10, eps25,  eps50, eps75, eps90, epsmax;
         if ( ninty != (*point)->end() ) {
         	epsmin = eps[0];
diff --git a/src/visualisers/FlagPlotting.cc b/src/visualisers/FlagPlotting.cc
index 2eaef19..4685f07 100644
--- a/src/visualisers/FlagPlotting.cc
+++ b/src/visualisers/FlagPlotting.cc
@@ -61,6 +61,7 @@ Flag* FlagPlotting::southFlag(const Colour& colour)
 	   south->setOriginHeight(origin_marker_size_);
 	   south->setHemisphere(SOUTH);
 	   south->setLength(length_);
+	   south->setConvention(KNOTS);
 	   southFlags_.insert(make_pair(colour, south));
 	   (*origin_).prepare(*south);
 	   return south;
@@ -81,6 +82,7 @@ Flag* FlagPlotting::northFlag(const Colour& colour)
 	north->setCrossBoundary(cross_boundary_);
 	north->setOriginHeight(origin_marker_size_);
 	north->setHemisphere(NORTH);
+	north->setConvention(KNOTS);
 	northFlags_.insert(make_pair(colour, north));
 	north->setLength(length_);
 	(*origin_).prepare(*north);
diff --git a/src/visualisers/GradientsColourTechnique.cc b/src/visualisers/GradientsColourTechnique.cc
index 26ab571..bee73ae 100644
--- a/src/visualisers/GradientsColourTechnique.cc
+++ b/src/visualisers/GradientsColourTechnique.cc
@@ -30,7 +30,6 @@ GradientsColourTechnique::GradientsColourTechnique()
 
 }
 
-
 GradientsColourTechnique::~GradientsColourTechnique() 
 {
 }
@@ -41,24 +40,36 @@ void GradientsColourTechnique::set(LevelSelection& out, LevelSelection& in, Colo
 	ColourTableDefinitionCompute helper;
 
 	
-	vector<double>::const_iterator val = stops_.begin();
-	vector<int>::const_iterator step = steps_.begin();
-	string stop_method = lowerCase(stop_method_);
 	
-	if ( colours_.empty() ) {
-		MagLog::warning() << " No colours given to the gradients method" << endl;
+	
+	if ( colours_.size() < 2 ) {
+		MagLog::warning() << " No enough colours given to the gradients method" << endl;
 		return;
 	}
-	if ( stops_.empty() ) {
-		MagLog::warning() << " No intervals given to the gradients method" << endl;
-		return;
+	vector<double> stops = in;
+	if ( stops.empty() ) {
+		MagLog::warning() << " No intervals given to the gradients method, guessing ..." << endl;
+		double min = in.front();
+		double max = in.back();
+		double increment = (max-min)/(colours_.size() -1);
+		for ( double i = 0; i < colours_.size(); i++)
+			stops.push_back(min + (i*increment));
 	}
+
+	vector<double>::const_iterator val = stops.begin();
+	vector<int>::const_iterator step = steps_.begin();
+	string stop_method = lowerCase(stop_method_);
 	
 	out.clear();
 	in.clear();
 	
   	//ColourTable colours;
   	int last = colours_.size() -1;
+  	
+  	vector<int> colours;
+
+
+
   	for ( int col = 1; col < colours_.size(); ++col) {
   		string left = colours_[col-1];
   		string right = colours_[col];	
@@ -67,95 +78,114 @@ void GradientsColourTechnique::set(LevelSelection& out, LevelSelection& in, Colo
   		// right
   		ColourTableDefinitionCompute helper(left, right, technique_, technique_direction_);
   		
-  		int nb;
-  		
-  		if ( stop_method == "right") 
-  			nb = (col == 1 ) ? istep + 1 : istep + 2;
-  		else if ( stop_method == "left" )
-  			nb = (col == last ) ? istep + 1 : istep + 2;
-  		else if ( stop_method == "ignore" ) 
-  			nb = (col == 1 || col == last ) ? istep + 2 : istep + 3;
-  		else
-  			nb = istep+1;
-  		
-  		helper.set(table, nb);
-
+  		int from, to, nbcols;
+
+  		if ( stop_method == "right") { 
+  			if ( col == last ) {
+  				nbcols = istep;
+  				from = 0;
+  				to = nbcols;
+  			}
+  			else {
+  				nbcols = istep + 1;
+  				from = 0;
+  				to = nbcols-1;
+  			}
+  		}
+  		else if ( stop_method == "left" ) {
+  			if ( col == 1 ) {
+  				nbcols = istep;
+  				from = 0;
+  				to = nbcols;
+  			}
+  			else {
+  				nbcols = istep + 1;
+  				from = 1;
+  				to = nbcols;
+  			}
+  		}
+  		else if ( stop_method == "ignore" ) { 
+  			if ( col == 1 ) {
+  				nbcols = istep+1;
+  				from = 0;
+  				to = nbcols-1;
+  			}
+  			else if ( col == last ) {
+  				nbcols = istep + 1;
+  				from = 1;
+  				to = nbcols;
+  			}
+  			else {
+  				nbcols = istep + 2;
+  				from = 1;
+  				to = nbcols-1;
+  			}
+  		}
+  		else 
+  			{
+  				nbcols = istep;
+  				from = 0;
+  				to = nbcols;
+  			}
+
+  		ColourTable workingtable;
+
+  		helper.set(workingtable, nbcols+1);
+
+  	
+	  	for (int c = from; c < to; ++c ) 
+	  		table.push_back(workingtable[c]);
+	  	
 		// Next block
-		if ( !steps_.empty() && step != steps_.end() ) 
+		if ( !steps_.empty()) { 
 			++step;
+			if ( step == steps_.end() )
+				--step;
+		}
 
   	}
 	
 	
+	
 	step = steps_.begin();
 	int col = 0;
 
 	// Now the interval ...
-  	for (int stop = 1; stop < stops_.size(); ++stop) { 
-  		  double from = stops_[stop-1];
-  		  double to = stops_[stop];
+  	for (int stop = 1; stop < stops.size(); ++stop) { 
+  		  double from = stops[stop-1];
+  		  double to = stops[stop];
   		  int istep = ( steps_.empty() ) ? 10 : *step;
-		  if (  stop_method == "ignore") {
-			
-		  	in.push_back(from);
-		  	out.push_back(from);
-		  	if ( stop != 1) {
-		  		in.push_back(from);
-		  		out.push_back(from);
-		  	}
-		  }
-		  else if (  stop_method == "right") {
-			
-		  	in.push_back(from);
-		  	out.push_back(from);
-		  }
-		  else if (  stop_method == "left") {
-			
-		  	in.push_back(from);
-		  	out.push_back(from);
-		  } 
-		  else {
-			
-		  	in.push_back(from);
-		  	out.push_back(from);
-		  } 
-		  nb = istep;
-		  double inc = (to - from )/(nb);
-		  for (int i = 1; i < nb; i++) {
+		  
+		  in.push_back(from);
+		  out.push_back(from); 
+		  
+		  double inc = (to - from )/(istep);
+		 
+		  for (int i = 1; i < istep; i++) {
 		  			in.push_back(from +(i*inc));
 		  			out.push_back(from +(i*inc));
-		  			
-		  		
-		  }
-		  if (  stop_method == "ignore") {
-			in.push_back(to);
-		  	out.push_back(to);
-		  	
-		  }	
-		  else if (  stop_method == "right") {
-			in.push_back(to);
-		  	out.push_back(to);
-		  	
-		  }	
-		  else if (  stop_method == "left") {
-			
-		  	in.push_back(to);
-		  	out.push_back(to);
 		  }
-		  else  if (stop == stops_.size()-1) {
-			in.push_back(to);
-		  	out.push_back(to);
-		  }
-		  
-		if ( !steps_.empty() && step != steps_.end() ) 
+		    
+		  if ( !steps_.empty()) { 
 			++step;
+			if ( step == steps_.end() )
+				--step;
+		}
+
+			
+		
 	}
+	in.push_back(stops.back());
+	out.push_back(stops.back());
 	
 
+	
+	
 
 
+
+	
 	
-	// now we compute the new levels list :
 
 
 
diff --git a/src/visualisers/IsoPlot.cc b/src/visualisers/IsoPlot.cc
index 7730630..cc85dd2 100644
--- a/src/visualisers/IsoPlot.cc
+++ b/src/visualisers/IsoPlot.cc
@@ -452,28 +452,44 @@ void CellBox::shade(const IsoPlot& owner) {
 }
 
 
-void CellBox::split(int)
+void CellBox::split(int many)
 {
+    if (many == 1) {
+        push_back(new CellBox(parent_, row1_ , row2_, column1_, column2_));
+        return;
+    }
+    
+    if (many == 4) {
+        split();
+        return;
+    }
 
-    // split in 8
+    // split in 9
 
 
     if ( row1_ == row2_ && column1_ ==  column2_ )
             return;
 
-    const int row    = (row2_   + row1_) /2;
-    const int column = (column2_+ column1_)/4;
+    const int row    = (row2_   - row1_) /3;
+    const int column = (column2_ - column1_)/3;
+
+    int row1 = row1_ + row;
+    int row2 = row1 + row;
+    int col1 = column1_ + column;
+    int col2 = col1 + column;
 
+    // Push 4 cells:
+    push_back(new CellBox(parent_, row1_, row1, column1_, col1));
+    push_back(new CellBox(parent_, row1+1, row2, column1_, col1));
+    push_back(new CellBox(parent_, row2+1, row2_, column1_, col1)); 
 
-    // Push 8 cells:
-    push_back(new CellBox(parent_, row1_, row, column1_, column));
-    push_back(new CellBox(parent_, row1_, row, column+1, 2*column));
-    push_back(new CellBox(parent_, row1_, row, (2*column)+1, 3*column));
-    push_back(new CellBox(parent_, row1_, row, (3*column)+1, column2_));
-    push_back(new CellBox(parent_, row+1, row2_, column1_, column));
-    push_back(new CellBox(parent_, row+1, row2_, column+1, 2*column));
-    push_back(new CellBox(parent_, row+1, row2_, (2*column)+1, 3*column));
-    push_back(new CellBox(parent_, row+1, row2_, (3*column)+1, column2_));
+    push_back(new CellBox(parent_, row1_, row1, col1+1, col2));
+    push_back(new CellBox(parent_, row1+1, row2, col1+1, col2));
+    push_back(new CellBox(parent_, row2+1, row2_, col1+1, col2));
+
+    push_back(new CellBox(parent_, row1_, row1, col1+1, column2_));
+    push_back(new CellBox(parent_, row1+1, row2, col1+1, column2_));
+    push_back(new CellBox(parent_, row2+1, row2_, col1+1, column2_));
 
 }
 
@@ -491,7 +507,7 @@ void CellBox::split()
        CellBox* cell = new CellBox(parent_, row1_, row2_, column1_, column);
        RangeType def = cell->range();
 
-       if ( def != multipleRange ) {
+       if ( def != multipleRange ) {  
              push_back(cell);
        }
        else {
@@ -1188,6 +1204,14 @@ void IsoPlot::isoline(Cell& cell, CellBox* parent) const
 }
 
 
+inline bool getEnv(const string& name, bool def)
+{
+    string value = getEnvVariable(name);
+    value = lowerCase(value);
+    if (value == "no" || value == "off" || value == "false") return false;
+    if (value == "yes"|| value == "on"  || value == "true")  return true;
+    return def;
+}
 
 
 void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
@@ -1247,16 +1271,29 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
        if (level+1!= levels_.end() )
           range.insert(make_pair(Interval(*level, *(level+1)), r++));
        }
-       if ( shading_->shadingMode() )
-           range.insert(make_pair(Interval(levels_.back(), levels_.back()+EPSILON), r-1));
+       
        CellArray* array = shading_->array(data, range, transformation, parent.widthResolution(), parent.heightResolution(),
             resolution_, technique_);
        if (!array)
             return;
+       if ( shading_->shadingMode() )
+           range.insert(make_pair(Interval(levels_.back(), levels_.back()+EPSILON), r-1));
+       
        CellBox view(array);
 
+
        threads_ = (needIsolines())  ? 4: 0;
-       //threads_ = 1;
+       
+       if ( threads_ ) {
+            if ( user_thread_ == 1 ) 
+                threads_ = 1;
+            else if ( user_thread_ == 9 ) 
+                threads_ = 9;
+            else 
+                threads_ = 4;
+       }
+
+      
        vector<IsoHelper*> consumers_;
        vector<IsoProducer* >  producers_;
 
@@ -1277,9 +1314,11 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
             consumers.back()->start();
         }
 
-        view.split();
-
-        // let's start 4 producers...
+        view.split(threads_);
+       
+        
+        
+        
         int c = 0;
         VectorOfPointers<vector<IsoProducerData*> > datas;
         for ( int i = 0; i < view.size(); i++)
@@ -1314,10 +1353,12 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
         }
        }
 
+      
+       
        for (CellBox::iterator cell = view.begin(); cell != view.end(); ++cell) {
-           (*cell)->feed(*this,parent);
-
-       }
+                (*cell)->feed(*this,parent);
+            }
+       
 
        delete array;
        for ( vector<IsoData*>::iterator segment = segments_.begin(); segment != segments_.end(); ++segment)  {
@@ -1339,6 +1380,7 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
     (*levelSelection_).clear();
     (*levelSelection_).calculate(min , max , true);
     bool need_isolines = (*shading_)(*levelSelection_);
+    shading_->reset();
     (*label_).prepare(*levelSelection_,  (*colour_).name());
     return need_isolines;
 }
@@ -1350,6 +1392,7 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
  */
  void IsoPlot::operator()(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
 {
+
     prepare(data);
     if ( legend_only_ ) {
         if ( rainbow_ ) {
@@ -1434,9 +1477,8 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
     prepare(data);
 
     if ( legend_only_ ) return;
-    // The shading needs the isolines..
-
 
+    // The shading needs the isolines..
     (*shading_)(this, data, parent);
 
     // Now we feed the task...
@@ -1637,80 +1679,87 @@ CellArray::CellArray(MatrixHandler& data,
 {
     Timer timer("CellArray", "CellArray");
     int r = height/resol;
-    int c = (int) width/resol;
+    int c = width/resol;
 
     rows_ = r;
     columns_ = c;
 
-
     points_.set(rows_+1, columns_+1);
     reserve(rows_* columns_);
 
-//  int i = 0;
-
     missing_ = data.missing();
+
     double firstx = transformation.getMinPCX();
     double firsty = transformation.getMinPCY();
 
     double stepx =  ( transformation.getMaxPCX() -  transformation.getMinPCX() )/ (columns_);
     double stepy =  ( transformation.getMaxPCY() -  transformation.getMinPCY() )/ (rows_);
-
     {
-        Timer timer("matrix", "prepare");
+        Timer timer("compute matrix", "prepare");
 
         vector< std::pair<double, double> > xypoints;
         vector< std::pair<double, double> > geopoints;
         double x = firstx, y = firsty;
         xypoints.reserve(rows_+1 * columns_+1);
-        for (int row = 0; row <= rows_; row++) {
+        for (int row = 0; row < rows_+1; row++) {
                 x = firstx;
-                y = firsty + (row*stepy);    // multiplication here avoids accumulation of errors
+                y = firsty + (row*stepy);
                 points_.rowsAxis().push_back(y);
-                for (int column = 0; column <= columns_; column++) {
-                    x = firstx + (column*stepx);  // multiplication here avoids accumulation of errors
+                for (int column = 0; column < columns_+1; column++) {
+                    x = firstx + (column*stepx);
                     xypoints.push_back(make_pair(x, y));
                     if ( row == 0) {
                         points_.columnsAxis().push_back(x);
                     }
+                   
                 }
+
+
         }
+        points_.setMapsAxis();
+
         transformation.revert(xypoints, geopoints);
+        //data.interpolate(points_, geopoints);
+        
         vector< std::pair<double, double> >::iterator geo= geopoints.begin();
         double min =  data.min();
         double max =  data.max();
         double missing =  data.missing();
 
-        double newmax =  data.min();
-        double newmin =  data.max();
+        
+
+
+        int i = 0;
 
         MagLog::dev() << "min = " << data.min() << "  max = " << data.max() << endl;
         for (vector< std::pair<double, double> >::iterator xy = xypoints.begin(); xy != xypoints.end(); ++xy) {
 
                     double value;
                     if  ( geo->second == -1000) {
-
                         value = missing;
+                        //cout << "MISSING AREA" << endl;
                     }
                     else {
                         value = (magCompare(technique, "nearest")) ?
                             data.nearest(geo->second, geo->first):data.interpolate(geo->second, geo->first);
-                        //value =data.nearest(geo->second, geo->first);
+                        //value = data.interpolate(geo->second, geo->first);
                     }
                     if (value != missing) {
                         if (value < min)
                             value = min;
-                        if (value < newmin)
-                            newmin = value;
+                       
                         if (value > max)
                             value=max; 
-                        if (value > newmax)
-                            newmax = value;
-
-                    }                    
-                    points_.push_back(value);
+                        
+                    }   
+                    else {
+                        //cout << "MISSING VALUE-->" << geo->second << ", " << geo->first << endl;
+                    }                 
+                    points_[i] = value;
+                    i++;
                     ++geo;
         }
-        points_.setMapsAxis();
+       
 
     }
 
diff --git a/src/visualisers/IsoShading.cc b/src/visualisers/IsoShading.cc
index c45b933..d47fe07 100644
--- a/src/visualisers/IsoShading.cc
+++ b/src/visualisers/IsoShading.cc
@@ -32,7 +32,7 @@
 using namespace magics;
 
 
-IsoShading::IsoShading()
+IsoShading::IsoShading() 
 {
  
   
diff --git a/src/visualisers/IsoShading.h b/src/visualisers/IsoShading.h
index c6bdf0f..ee0cece 100644
--- a/src/visualisers/IsoShading.h
+++ b/src/visualisers/IsoShading.h
@@ -47,7 +47,11 @@ public:
 	virtual bool accept(const string&) { return true;}
     
 	virtual void operator()(IsoPlot*, MatrixHandler&, BasicGraphicsObjectContainer&)
-			{  }
+			{   // Should return 
+				//CellArray* array = technique_->array(matrix, range, transformation, width, height, resolution, technique);
+		 
+		 		//return array;
+			}
 	virtual void operator()(Data&, BasicGraphicsObjectContainer&)
 			{  }
  
@@ -73,6 +77,7 @@ public:
 	virtual void colour(double, Colour&) {};
 	virtual bool needClipping() { return false;}
 	virtual bool method(ContourMethod*) { return false; }
+	virtual void reset() {}
 	
 protected:
      //! Method to print string about this class on to a stream of type ostream (virtual).
@@ -106,17 +111,24 @@ public:
 		object->copy(*this);
 	    return object;
 	}
-	 CellArray* array(MatrixHandler& matrix, IntervalMap<int>& range,
+	
+	CellArray* array(MatrixHandler& matrix, IntervalMap<int>& range,
 	        	    		const Transformation& transformation, int width, int height,
 	        	    		float resolution, const string& technique) {
-		 return technique_->array(matrix, range, transformation, width, height, resolution, technique); }
+		 CellArray* array = technique_->array(matrix, range, transformation, width, height, resolution, technique);
+		 
+		 return array;
+	}
 	virtual void operator()(IsoPlot* iso, MatrixHandler& data, BasicGraphicsObjectContainer& parent)
-		{ (*this->technique_)(iso, data, parent); }
+		{  
+			(*this->technique_)(iso, data, parent); 
+		}
 	virtual void operator()(Data& data, BasicGraphicsObjectContainer& parent)
 			{ (*this->technique_)(data, parent); }
 	virtual int     shadingIndex(double);
 	virtual int  leftIndex(double);
 	virtual int  rightIndex(double);
+	void reset() { technique_->reset(); }
 
 	virtual bool needClipping() { return (*this->technique_).needClipping(); }
 	virtual bool operator()(LevelSelection& list)
@@ -154,6 +166,7 @@ protected:
 	 virtual void print(ostream&) const; 
 	vector<Colour> colours_;
 	vector<Colour>::iterator colour_;
+	
 
 private:
 	//! Copy constructor - No copy allowed
diff --git a/src/visualisers/LevelListSelectionType.cc b/src/visualisers/LevelListSelectionType.cc
index 1003790..28328ab 100644
--- a/src/visualisers/LevelListSelectionType.cc
+++ b/src/visualisers/LevelListSelectionType.cc
@@ -77,3 +77,4 @@ void LevelListSelectionType::calculate(double , double, bool)
 	MagLog::dev() << print.str() << endl;
 }
 
+
diff --git a/src/visualisers/LevelListSelectionType.h b/src/visualisers/LevelListSelectionType.h
index 892caa3..d78dd0d 100644
--- a/src/visualisers/LevelListSelectionType.h
+++ b/src/visualisers/LevelListSelectionType.h
@@ -81,5 +81,6 @@ private:
 
 
 
+
 } // namespace magics
 #endif
diff --git a/src/visualisers/OriginMarker.h b/src/visualisers/OriginMarker.h
index f2f2dfc..a72f337 100644
--- a/src/visualisers/OriginMarker.h
+++ b/src/visualisers/OriginMarker.h
@@ -50,6 +50,7 @@ public:
   
 	void marker(const string& marker)      { marker_ = marker; }
 	void height(double height)      { height_ = height; }
+	virtual double height() { return height_; }
 	void set(const OriginMarker& from)
 	{
 		marker_ = from.marker_;
@@ -58,7 +59,7 @@ public:
 	virtual void prepare(ArrowProperties& object)
 	{
 		object.setOriginMarker(marker_);
-		//object.setOriginHeight(height_);
+		object.setOriginHeight(height());
 	}
 
 protected:
@@ -86,9 +87,14 @@ public:
 	NoOriginMarker() {}
 	~NoOriginMarker() {}
 	virtual OriginMarker* clone()  { return new NoOriginMarker(); }
-	virtual void prepare(ArrowProperties&) {}
+	virtual void prepare(ArrowProperties& object) {
+		object.setOriginHeight(0);
+	}
+	
+	
 	void operator()(const PaperPoint&) {}
     virtual bool accept(const string& node) { return magCompare(node, "nomarker"); }
+    double height() { return 0.; }
 
 };
 
diff --git a/src/visualisers/PolyShadingTechnique.cc b/src/visualisers/PolyShadingTechnique.cc
index 247b8dc..88dcdb8 100644
--- a/src/visualisers/PolyShadingTechnique.cc
+++ b/src/visualisers/PolyShadingTechnique.cc
@@ -26,14 +26,15 @@
 using namespace magics;
 void ShadingTechnique::operator()(IsoPlot* iso, MatrixHandler& data, BasicGraphicsObjectContainer& parent)
 {
-	iso->isoline(data, parent);
+	if ( !done_ ) 
+		iso->isoline(data, parent);
 }
 
 CellArray* PolyShadingTechnique::array(MatrixHandler& matrix, IntervalMap<int>& range,
   	    		const Transformation& transformation, int width, int height,
   	    		float resolution, const string& technique)
 {
-
+	done_ = true;
 	return new CellArray(matrix, range, transformation, width, height, resolution, technique);
 
 }
@@ -55,7 +56,7 @@ CellArray* GridShading::array(MatrixHandler& matrix, IntervalMap<int>& range,
 		const Transformation& transformation, int width, int height,
 		float resolution, const string& technique)
 {
-
+	done_ = true;
 	return new GridArray(matrix, range, transformation, width, height, resolution, position_);
 
 }
diff --git a/src/visualisers/ShadingTechnique.h b/src/visualisers/ShadingTechnique.h
index a2d63aa..b0372c2 100644
--- a/src/visualisers/ShadingTechnique.h
+++ b/src/visualisers/ShadingTechnique.h
@@ -45,7 +45,7 @@ class ShadingTechnique  {
 
 
 public:
-	ShadingTechnique() {}
+	ShadingTechnique(): done_(false) {}
 	virtual ~ShadingTechnique() {}
     virtual void set(const map<string, string>&) {}
     virtual void set(const XmlNode&) {}
@@ -69,9 +69,11 @@ public:
        		float resolution, const string& technique) { ASSERT(0); return 0;}
     virtual bool needClipping() { return false; }
     virtual bool method(ContourMethod*) { return false; }
+    void reset()  { done_ = false; }
 protected:
      //! Method to print string about this class on to a stream of type ostream (virtual).
 	 virtual void print(ostream&) const {}
+     bool done_;
 
 private:
     //! Copy constructor - No copy allowed
diff --git a/src/visualisers/Streamlines.cc b/src/visualisers/Streamlines.cc
index 925fd96..6ec5614 100644
--- a/src/visualisers/Streamlines.cc
+++ b/src/visualisers/Streamlines.cc
@@ -31,30 +31,137 @@ bool Streamlines::operator()(Data& data, BasicGraphicsObjectContainer& parent)
 {
     Timer timer("Streamlines", "Streamlines");
 
+    // Il faudrait tout revoir, pour calculer les isolignes dans le plan projeté
+    // et non en latlon ( Cela éviterait les problemes de densité d'isolignes
+    // pres des poles et de jointure moche pour les projections 'proj4 (overlapped)'
+
+    // Mais attention a toute modif de simplification:
+    // => Plus d'1 journée de mise au point
 
     const Transformation& transformation = parent.transformation();
 
+    double x1,  y1,  x2,  y2;
+    transformation.boundingBox(x1, y1, x2, y2);
+    PaperPoint pt1 = transformation(UserPoint((x1+x2)/2, (y1+y2)/2));
+    PaperPoint pt2 = transformation(UserPoint((x1+x2)/2 + 360.0, (y1+y2)/2));
+    bool overlapping = same(pt1.x(), pt2.x()) && same(pt1.y(), pt2.y());
+
     GeoRectangularProjection geo;
 
     MatrixHandler& dir = data.direction();
 
     //Make sure that the data are prepared correcly for the Streamlines..
 
-    if (dir.right() -  dir.left() < 350) {
-		geo.setMinX(dir.left()+1);
-		geo.setMaxX(dir.right()-1);
-		geo.setMinY(dir.bottom()+1);
-		geo.setMaxY(dir.top()-1);
-	}
+    double minpcx = transformation.getAbsoluteMinPCX();
+    double maxpcx = transformation.getAbsoluteMaxPCX();
+
+    double minpcy = transformation.getAbsoluteMinPCY();
+    double maxpcy = transformation.getAbsoluteMaxPCY();
+
+    double minx = geo.getMinX();
+    double maxx = geo.getMaxX();
+    const double LONMIN = -3.0 * 360.0;
+    const double LONMAX = 3.0 * 360.0;
+    if (minx < LONMIN || minx > LONMAX || maxx < LONMIN || maxx > LONMAX) {
+        // geo a recupéré les min max directement dans les clefs
+        // 'subpage_lower_left_latitude', ., 'subpage_upper_right_longitude'
+        // MAIS selon la projection et son mode de définition, ces clefs
+        // ne sont pas forcement renseignées, ou alors exprimées en
+        // coordonnées projetées au lieu de latlon (Stereopol, ou proj4 si
+        //     subpage_map_area_coordinate_system == 'projection')
+
+        minx = NAN;
+        UserPoint leftpt;
+        transformation.revert(PaperPoint(minpcx, minpcy), leftpt);
+        double x = leftpt.x();
+        if (x == x && x >= LONMIN && x <= LONMAX) // x == x => !NAN
+            minx = x;
+        transformation.revert(PaperPoint(minpcx, maxpcy), leftpt);
+        x = leftpt.x();
+        if (x == x && x >= LONMIN && x <= LONMAX) { // x == x => !NAN
+            if( minx != minx || x < minx ) // minx != minx => NAN
+                minx = x;
+        }
+        if(minx != minx)
+            minx = -180.0;
+
+        maxx = minx+360.0;
+    }
+
+    // Il reste encore un pb de "jointure moche" avec les proj "overlapped"
+    // ( on s'arrange pour qu'elle soit la moins visible possible => on
+    // la cale sur minx )
+
+    double left = dir.left();
+    double right = dir.right();
+
+    if (right -  left < 350) {
+        if( !overlapping ) {
+            // Cas rencontré: Ex Mercator "Historique" (pas d'overlap)
+            // si minx = -180, maxx = -135   et  donnees (left 173 -> right 230)
+            // => Aucun tracé ( il faut ajuster les longitudes des données )
+
+            // la meilleure solution mais potentiellement couteuse
+            // ( ex: maille 0.01 de -1440 -> 1440 -> points en longitude )
+            //     geo.setMinX(minx);
+            //     geo.setMaxX(maxx);
+
+            // A priori moins couteux, mais la grille n'est tracée qu'une seule fois si
+            // maxx - minxx > 360.0. Mais c'est déja le cas pour les "overlapped"
+            while(left > maxx) {
+                left -= 360.0;
+                right -= 360.0;
+            }
+            while(right < minx) {
+                left += 360.0;
+                right += 360.0;
+            }
+            geo.setMinX(left-1);
+            geo.setMaxX(right+1);
+        }
+        else {
+            geo.setMinX(left-1);
+            geo.setMaxX(right+1);
+        }
+    }
+
+    else {
+        // grilles globales
+        maxx = std::max(minx+360.0, maxx);	// max-min >= 360 nécessaire pour
+        geo.setMinX(minx);					// les proj non rectangulaires
+        geo.setMaxX(maxx);
+    }
+
+    // nécessaire pour proj non rectangulaires (Ex: stereopolaire)
+    // sinon il manque une partie du tracé
+    // ( Pas terrible, On doit pouvoir faire mieux !)
+    const double LATMAX = 89.0;
+    // top()/bottom() inversés ?
+    geo.setMinY(std::max(-LATMAX, std::min(dir.bottom(), dir.top())-1));
+    geo.setMaxY(std::min(LATMAX, std::max(dir.bottom(), dir.top())+1));
 
     MatrixHandler& handler = *geo.prepareData(data.direction());
 
     
 
-    float* direction = new float[handler.rows()*handler.columns()];
+    int nbcolumns = handler.columns();
+    if (overlapping) {
+        // Même avec -180.0, 180.0, il y a un overlap (cf Matrix.cc)
+        double minlon;
+        int column = 0;
+        for (; column < handler.columns(); column++ ) {
+            if (!column)
+                minlon = handler.column(0,0);
+            else if (handler.column(0, column) >= (minlon + 360.0))
+                break;
+        }
+        nbcolumns = column;
+    }
+
+    float* direction = new float[handler.rows()*nbcolumns];
     int i = 0;
     for (int row = 0; row < handler.rows(); row++ )
-        for (int column = 0; column < handler.columns(); column++ ) {
+        for (int column = 0; column < nbcolumns; column++ ) {
 // ************ MF RV ***************
 // CalcStreamlines.cc (line 281) -> only check NAN as missingValue
 //    and shiftPeriod(missingValue) (lines 31,44) -> catastrophic!
@@ -67,7 +174,7 @@ bool Streamlines::operator()(Data& data, BasicGraphicsObjectContainer& parent)
 
 
     GSStruct *gs = new GSStruct();
-    gs->nx = handler.columns();
+    gs->nx = nbcolumns;
     gs->ny = handler.rows();
 
 
@@ -77,9 +184,11 @@ bool Streamlines::operator()(Data& data, BasicGraphicsObjectContainer& parent)
     // Distance between the gridpoints
     gs->dx = handler.XResolution();
     gs->dy = -handler.YResolution();
+    if (gs->dy < 0)		//reversed lat scan
+        gs->dy = -gs->dy;
     gs->period_x = 0.;
     transformation.geoProjection(gs->gs_geo);
-
+    gs->gs_geo = 0;  // RV
     OneLineClass ** result = 0;
     int size;
 
@@ -94,19 +203,78 @@ bool Streamlines::operator()(Data& data, BasicGraphicsObjectContainer& parent)
         poly.setThickness(thickness_);
         poly.setLineStyle(style_);
 
+        if (ratio_ > 0) { // si ratio_ == 0, il reste quand même une "trace"
+            ArrowProperties* arrow = new ArrowProperties();
+            arrow->setHeadIndex(head_);
+            arrow->setHeadRatio(ratio_);
+            poly.setArrow(arrow);
+        }
 
-        ArrowProperties* arrow = new ArrowProperties();
-        arrow->setHeadIndex(head_);
-        arrow->setHeadRatio(ratio_);
-        poly.setArrow(arrow);
-        for(int i = 0; i < result[l]->Len; i++)
-        {
-
-                poly.push_back(transformation(UserPoint(result[l]->X[i], result[l]->Y[i])));
-
+        static const PaperPoint NOPT(1.0e50, 1.0e50);
+        static const double MARGIN = 0.05;
+
+        double width = maxpcx - minpcx;
+        double xmin = minpcx - width * MARGIN;
+        double xmax = maxpcx + width * MARGIN;
+
+        double height = maxpcy - minpcy;
+        double ymin = minpcy - height * MARGIN;
+        double ymax = maxpcy + height * MARGIN;
+
+        // MOUAIS .... C'est moche ( => à améliorer )
+        // Il est difficile de calculer une distmax qui marche avec toutes les projections
+        // => Stereopolaire (pas vraiment de distance max) car pas de saut de
+        // longitude contrairement à une proj rectangulaire (type EPSG:3832) ou
+        // encore une projection inclinée type skewmercator
+        // Il faudrait balayer (par exemple de ° en °) toutes les longitudes par
+        // rapport à un pt de ref et prendre la valeur max avec une marge mais
+        // à quelle latitude le faire pour une projection conique type
+        // stereopolaire
+        double distmax = -1.0, distmax2 = -1.0;
+
+        if (overlapping) {
+            distmax = width * 95.0/100.0; // <= .... Bof
+            distmax2 = distmax * distmax;
         }
-        transformation(poly, parent);
 
+        for (int i = 0; i < result[l]->Len;) {
+            PaperPoint prevpt = NOPT;
+            while(i < result[l]->Len)
+            {
+                PaperPoint pt = transformation(UserPoint(result[l]->X[i], result[l]->Y[i]));
+                i++;
+                // On elimine ainsi les points invalides
+                // ( Pour lesquels la projection a "échoué" )
+                // if (!transformation.in(pt) || => NON il peut manquer un segment sur les bords
+                if (!pt.in(xmin, xmax, ymin, ymax) ||
+                        pt.x() != pt.x() || pt.y() != pt.y() ) { // x != x => NAN (Cf mercator)
+                    // Vire aussi les points valides vraiment hors domaine par
+                    // effet induit. Mais ils auraient eté virés par le clipping
+                    // effectué ci-dessous par transformation(poly, parent)
+                    break;
+                }
+                // gestion "overlapping" proj4 => x(ll) = x(ll%360)
+                // Pour éviter un trait "horizontal" entre 2 points valides
+                // rapprochés en latlon mais près de 2 bords opposés plan
+                // projeté suite au modulo 360 (ex EPSG::3832 (-30.5W, -29.5W))
+                // Il manquera le segment (d'entrée ou sortie du domaine ),
+                // mais on ne peut pas faire autrement.
+                if(distmax > 0 && !(prevpt == NOPT)) {
+//              if( pt.distance(prevpt) > distmax ) { NON -> distance() très couteux
+                    double dist2 = (pt.x()-prevpt.x())*(pt.x()-prevpt.x()) +
+                                (pt.y()-prevpt.y())*(pt.y()-prevpt.y());
+                    if (dist2 > distmax2) {
+                        i--;
+                        break;
+                    }
+                }
+                poly.push_back(pt);
+                prevpt = pt;
+            }
+            if (poly.size() >= 2)
+                transformation(poly, parent);
+            poly.clear();
+        }
     }
 // ************ MF RV ***************
 // Leak ;-)
diff --git a/src/visualisers/SymbolAdvancedTableMode.cc b/src/visualisers/SymbolAdvancedTableMode.cc
index 1b55afa..fad43bf 100644
--- a/src/visualisers/SymbolAdvancedTableMode.cc
+++ b/src/visualisers/SymbolAdvancedTableMode.cc
@@ -84,7 +84,9 @@ void SymbolAdvancedTableMode::prepare()
 
 } 
 
-void SymbolAdvancedTableMode::adjust(double min, double max)
+        
+        
+void SymbolAdvancedTableMode::adjust(double min, double max, bool  scale, const Transformation& transformation, double scaling)
 {
 	static map<string, TextSymbol::TextPosition> texthandlers;
 	if ( texthandlers.empty() ) {
@@ -146,12 +148,14 @@ void SymbolAdvancedTableMode::adjust(double min, double max)
     	if (level+1 == levels_->end() ) break;
 
     	MagLog::debug() << "[" << *level << ", " << *(level+1) << "]=" << *marker << "(marker)" << *text << "(text)"<< endl;
-
+    	double height = height_method_->height(*level);
+    	if ( scale ) 
+			height = transformation.ratio() * height * scaling;
     	SymbolProperties properties;
-    	if ( index )
-    		properties = SymbolProperties(colourMethod_->right(*level), height_method_->height(*level), *marker     , *text);
+    	if ( index ) 
+    		properties = SymbolProperties(colourMethod_->right(*level), height, *marker, *text);
     	else
-    		properties = SymbolProperties(colourMethod_->right(*level), height_method_->height(*level), *marker_name, *text);
+    		properties = SymbolProperties(colourMethod_->right(*level), height,*marker_name, *text);
 
     	properties.position_ = position;
     	properties.font_ = font;
diff --git a/src/visualisers/SymbolAdvancedTableMode.h b/src/visualisers/SymbolAdvancedTableMode.h
index fb884cf..675f363 100644
--- a/src/visualisers/SymbolAdvancedTableMode.h
+++ b/src/visualisers/SymbolAdvancedTableMode.h
@@ -68,25 +68,17 @@ public:
     		return SymbolAdvancedTableModeAttributes::accept(node);    
     	}
     	
-    	virtual SymbolMode* clone() const {
-    		SymbolAdvancedTableMode* object = new SymbolAdvancedTableMode();
-    		object->copy(*this);
-    		return object;
-    	}
-    	virtual void adjust(double , double );
-    
+	virtual SymbolMode* clone() const {
+		SymbolAdvancedTableMode* object = new SymbolAdvancedTableMode();
+		object->copy(*this);
+		return object;
+	}
+    void adjust(double, double, bool, const Transformation&, double);
     	 void copy(const SymbolAdvancedTableMode& other) {
     		 SymbolAdvancedTableModeAttributes::copy(other);
     		 SymbolModeAttributes::copy(other);
     	 }
         
- 
-
-
-       
-
-        
-       
         int getCount() const { return count_; }
         int getTolerance() const { return tolerance_; }
         double getReference() const { return reference_; }
diff --git a/src/visualisers/SymbolMode.cc b/src/visualisers/SymbolMode.cc
index 518da12..894d47c 100644
--- a/src/visualisers/SymbolMode.cc
+++ b/src/visualisers/SymbolMode.cc
@@ -270,7 +270,12 @@ void SymbolIndividualMode::visit(LegendVisitor& legend)
 		  symbol->setHeight(legend_height_);
 	  legend.add(new SimpleSymbolEntry(legend_text_, symbol));
 }
+void SymbolIndividualMode::adjust(double, double, bool, const Transformation&, double) {
 
+}
+void SymbolTableMode::adjust(double, double, bool, const Transformation&, double) {
+
+}
 void SymbolIndividualMode::visit(Data& data, LegendVisitor& legend)
 {
 
diff --git a/src/visualisers/SymbolMode.h b/src/visualisers/SymbolMode.h
index 4487df7..2d11a75 100644
--- a/src/visualisers/SymbolMode.h
+++ b/src/visualisers/SymbolMode.h
@@ -73,8 +73,8 @@ public:
     virtual void visit(Data&, LegendVisitor& legend) { visit(legend); }
     virtual void visit(Data&, HistoVisitor&);
 
-	//virtual void adjust(double min, double max) {}
-	virtual void adjust(double , double ) {}
+	
+	virtual void adjust(double, double, bool, const Transformation&, double) {} 
 	void set(const string& type) { type_ = type; }
 
 protected:
@@ -124,7 +124,7 @@ public:
 		return object;
 	}
    
-    
+    void adjust(double, double, bool, const Transformation&, double);
     virtual void visit(LegendVisitor&);
 	void prepare() { update(); properties();}
     void update();
@@ -194,6 +194,8 @@ public:
 		return SymbolTableModeAttributes::accept(node);
     
 	}
+
+	void adjust(double, double, bool, const Transformation&, double);
     
     void visit(LegendVisitor&); 
     void visit(Data&, LegendVisitor&);
diff --git a/src/visualisers/SymbolPlotting.cc b/src/visualisers/SymbolPlotting.cc
index 75a8bb9..3132d69 100644
--- a/src/visualisers/SymbolPlotting.cc
+++ b/src/visualisers/SymbolPlotting.cc
@@ -46,16 +46,15 @@ void SymbolPlotting::print(ostream& out)  const
 	out << "]";
 }
 
-double SymbolPlotting::height(const Transformation&, double height)
+double SymbolPlotting::height(const Transformation& transformation, double height)
 {
     if ( scaling_method_ == false ) 
         return height;
     
     // get Area !
 
-    //return transformation.ratio() * scaling_level_0_ * scaling_factor_;
-    return scaling_level_0_ * scaling_factor_;
-
+    return transformation.ratio() * scaling_level_0_ * scaling_factor_;
+   
 
 
 }
@@ -170,7 +169,7 @@ void SymbolPlotting::operator()(Data& data, BasicGraphicsObjectContainer& out)
 
     	// Some Mode need to know the min and max of the data, in order to adjust the 
     	// computation of the levels
- 		(*mode_).adjust(points.min(), points.max());
+ 		(*mode_).adjust(points.min(), points.max(), scaling_method_, transformation, scaling_factor_);
  		if ( legend_only_ )
  			return;
 
diff --git a/src/visualisers/ValuePlotMethod.h b/src/visualisers/ValuePlotMethod.h
index 12368e7..7419f83 100644
--- a/src/visualisers/ValuePlotMethod.h
+++ b/src/visualisers/ValuePlotMethod.h
@@ -94,11 +94,25 @@ protected:
 	 }
 	 virtual void reset() {} // For Metview, get ready for a second frame.
      virtual void add(const PaperPoint& xy) {
+         static map<string, VerticalAlign> alignhandlers;
+         if ( alignhandlers.empty() ) {
+             alignhandlers["normal"] = MNORMAL;
+             alignhandlers["top"] = MTOP;
+             alignhandlers["cap"] = MCAP;
+             alignhandlers["half"] = MHALF;
+             alignhandlers["base"] = MBASE;
+             alignhandlers["bottom"] = MBOTTOM;
+         }
      	 ostringstream nice;
     	 nice << MagicsFormat(format_, xy.value()); 
          Text* text = new Text(); 
          text->addText(nice.str(), *colour_, height_);
-         text->setJustification(MCENTRE);
+         text->setJustification(justification_);
+         map<string, VerticalAlign>::iterator pos =
+                 alignhandlers.find(lowerCase(vertical_align_));
+         VerticalAlign align =
+                 ( pos != alignhandlers.end()) ? pos->second : MBASE;
+         text->setVerticalAlign(align);
          text->push_back(xy);
          push_back(text);
     }
diff --git a/src/web/GeoJSon.cc b/src/web/GeoJSon.cc
index 12b535e..b20e578 100644
--- a/src/web/GeoJSon.cc
+++ b/src/web/GeoJSon.cc
@@ -64,7 +64,11 @@ public:
 				(*object)->create(out);
 			}
 		}
-
+		virtual void boundingBox(double& min, double& max) {
+			for (vector<GeoObject*>::iterator object = objects_.begin(); object != objects_.end(); ++object) {
+				(*object)->boundingBox(min, max);
+			}
+		}
 		virtual void create(const std::set<string>& needs, CustomisedPointsList& out) {
 			for (vector<GeoObject*>::iterator object = objects_.begin(); object != objects_.end(); ++object) {
 				(*object)->create(needs, out);
@@ -92,11 +96,10 @@ public:
 			}
 
 		}
-		virtual void shift(const std::set<string>& needs, CustomisedPointsList& out) {
-					if ( !shift() )
-						return;
+		virtual void shift(const std::set<string>& needs, CustomisedPointsList& out, double val = 0) {
+					
 					for (vector<GeoObject*>::iterator object = objects_.begin(); object != objects_.end(); ++object) {
-						(*object)->shift(needs, out);
+						(*object)->shift(needs, out, val);
 					}
 		}
 		vector<GeoObject*> objects_;
@@ -117,6 +120,18 @@ public:
 			out.push_back(point);
 		}
 		bool shift_;
+		virtual void print()
+		{
+			cout << name_ << "-->" << objects_.size() << endl;
+			for (vector<GeoObject*>::iterator o = objects_.begin(); o != objects_.end(); ++o) 
+				(*o)->print();
+		}
+	virtual bool detectFeature() {
+		for (vector<GeoObject*>::iterator o = objects_.begin(); o != objects_.end(); ++o) 
+				if ( (*o)->detectFeature() )
+					return true;
+		return false;
+	}
 };
 
 
@@ -130,10 +145,21 @@ public:
 		name_ = n.str();
 
 	}
-	virtual ~GeoFeature() {}
 
+	bool detectFeature() {
+		return true;
+	}
 
+	virtual ~GeoFeature() {}
+
+	void boundingBox(double& min, double& max) {
+		min = 900000;
+		max = -min;
+		GeoObject::boundingBox(min, max);
+		
+	}
 	void create(PointsList& out) {
+		
 		GeoObject::create(out);
 		out.push_back(new UserPoint(0,0,0,true));
 	}
@@ -146,11 +172,35 @@ public:
 		newline(out);
 
 	}
-	void shift(const std::set<string>& needs, CustomisedPointsList& out) {
-			GeoObject::shift(needs, out);
+	void shift(const std::set<string>& needs, CustomisedPointsList& out, double val =0) {
+			double min;
+			double max;
+			if ( GeoObject::detectFeature() ) // Dig!
+				return GeoObject::shift(needs, out);
+				
+			boundingBox(min, max);
+			//cout << min << "--->" << max << endl;
+			if (max <= -180 ) 
+				GeoObject::shift(needs, out, 360);
+			
+			else if (min >= 180 )
+				GeoObject::shift(needs, out, -360);
+
+			else if (min <= 180 && max >= 180) {
+				GeoObject::shift(needs, out, -360);
+			}
+			else if (min <= -180 && max >= -180) {
+				GeoObject::shift(needs, out, 360);
+			}
+			else if (max > 360 ) 
+				GeoObject::shift(needs, out, -360);
+			
 			newline(out);
+
 	}
 
+
+
 };
 
 class GeoPoint : public GeoObject
@@ -163,17 +213,20 @@ public:
 
 	}
 	virtual ~GeoPoint() {}
+	void boundingBox(double& min, double& max) {
+		if ( min > lon_ ) min = lon_;
+		if ( max < lon_ ) max = lon_;
+	}
 	virtual void decode(const json_spirit::Value& value) {
 
 		Array point = value.get_value< Array>();
 		lon_ = point[0].get_value<double>();
 		lat_ = point[1].get_value<double>();
-		if ( lon_ < 0 ) {
-			lon_ += 360;
-			shift_ = true;
-		}
+		
 
 	}
+	void print ()
+	{}
 	double lat_;
 	double lon_;
 
@@ -183,8 +236,8 @@ public:
 		out.push_back(point);
 
 	}
-	void shift(PointsList& out) {
-		UserPoint* point = new UserPoint(lon_-360., lat_, tonumber(getProperty("value", "0")), false, false, getProperty("name"));
+	void shift(PointsList& out, double value) {
+		UserPoint* point = new UserPoint(lon_+value, lat_, tonumber(getProperty("value", "0")), false, false, getProperty("name"));
 
 		out.push_back(point);
 	}
@@ -203,8 +256,8 @@ public:
 		set(needs, *point);
 		out.push_back(point);
 	}
-	void shift(const std::set<string>& needs, CustomisedPointsList& out) {
-		CustomisedPoint* point = new CustomisedPoint(lon_-360., lat_,  getProperty("name"));
+	void shift(const std::set<string>& needs, CustomisedPointsList& out, double val =0) {
+		CustomisedPoint* point = new CustomisedPoint(lon_+val, lat_,  getProperty("name"));
 		set(needs, *point);
 		out.push_back(point);
 	}
@@ -417,7 +470,11 @@ void GeoJSon::customisedPoints(const Transformation&, const std::set<string>& ne
 {
 	decode();
 
+
+
+	
 	if ( parent_ ) {
+			
 			parent_->create(needs, out);
 			parent_->shift(needs, out);
 	}
diff --git a/src/web/MagConfig.cc b/src/web/MagConfig.cc
index 157ee4b..58f4f85 100644
--- a/src/web/MagConfig.cc
+++ b/src/web/MagConfig.cc
@@ -27,6 +27,11 @@ MagConfigHandler::MagConfigHandler(const string& config, MagConfig& magics)
 	json_spirit::Value value;
 	try {
 		 json_spirit::read_or_throw( is, value );
+		 if (value.type() == array_type) {
+		 	Array values = value.get_value<Array>();
+		 	magics.callback(values);
+		 	return;
+		 }
 		 Object object = value.get_value< Object >();
 
 		 for (vector<Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
@@ -81,13 +86,75 @@ string MagConfig::convert(const json_spirit::Value& value)
 		return tostring(value.get_real());
 	}
 
+
 	return "";
 
 
 }
 
+void StyleLibrary::callback(const json_spirit::Array& values)
+{
+	for (unsigned int i = 0; i < values.size(); i++) {
+		library_.push_back(Style());
+
+		json_spirit::Object object = values[i].get_value< json_spirit::Object >();
+		library_.back().set(object);
+		
+	}
+		
+    	
+}
+
+void Style::criteria(const json_spirit::Value& value) 
+{
+	json_spirit::Object object =value.get_value< json_spirit::Object >();
+	for (vector<json_spirit::Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
+		criteria_.insert(make_pair(entry->name_, MagConfig::convert(entry->value_)));
+	}
+}
+void Style::style(const json_spirit::Value& value) 
+{
+	json_spirit::Object object =value.get_value< json_spirit::Object >();
+	for (vector<json_spirit::Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
+		style_.insert(make_pair(entry->name_, MagConfig::convert(entry->value_)));
+	}
+}
+void Style::more(const json_spirit::Value& value) 
+{
+	Array values = value.get_value<Array>();
+	cout << "Style::more-->" << values.size() << endl;
+	for (unsigned int i = 0; i < values.size(); i++) {
+		more_.push_back(Style());
+
+		json_spirit::Object object = values[i].get_value< json_spirit::Object >();
+		more_.back().set(object);
+		
+	}
+
+}
+void Style::set(const json_spirit::Object& object) 
+{
+	if ( methods_.empty() ) {
+		methods_["criteria"] =  &Style::criteria;
+		methods_["criterias"] =  &Style::criteria;
+		methods_["style"] =  &Style::style;
+		methods_["visdef"] =  &Style::style;
+		methods_["more"] =  &Style::more;
+	}
+
+	for (vector<json_spirit::Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
+		map<string,  SetMethod>::iterator method = methods_.find(entry->name_);
+		if ( method != methods_.end() )
+			(this->*method->second)(entry->value_);
+		else 
+			MagLog::warning() << entry->name_ << " is not a known keyword" << endl;
+    }	
+
+}
+
 void StyleLibrary::callback(const string& name, const json_spirit::Value& value)
 {
+		/*
 		library_.insert(make_pair(name, map<string, string>()));
 		if ( value.type() == json_spirit::obj_type ) {
 			json_spirit::Object object =value.get_value< json_spirit::Object >();
@@ -95,6 +162,7 @@ void StyleLibrary::callback(const string& name, const json_spirit::Value& value)
 				library_[name].insert(make_pair(entry->name_, convert(entry->value_)));
     		}
     	}
+    	*/
     	
 }
 void StyleLibrary::init()
@@ -104,16 +172,110 @@ void StyleLibrary::init()
 	MagConfigHandler(library,  *this);
 }
 
+void PaletteLibrary::init()
+{
+	string library = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_  + "/" + "palette" +".json";
+	MagLog::debug() << "Opening " << library << endl;
+	MagConfigHandler(library,  *this);
+}
+void Palette::values(const json_spirit::Value& value) 
+{
+	Array values = value.get_value<Array>();
+	cout << "Palette::values-->" << values.size() << endl;
+	for (unsigned int i = 0; i < values.size(); i++) {
+		colours_.push_back(MagConfig::convert(values[i]));	
+	}
+}
 
+void Palette::tags(const json_spirit::Value& value) 
+{
+	Array values = value.get_value<Array>();
+	cout << "Palette::values-->" << values.size() << endl;
+	for (unsigned int i = 0; i < values.size(); i++) {
+		tags_.push_back(MagConfig::convert(values[i]));	
+	}
 
-const map<string, string>& StyleLibrary::get(const string& name) const {
-		map<string, map<string, string> >::const_iterator area = library_.find(name);
-		if ( area != library_.end() ) 
-			return area->second;
-		if (theme_.empty() )
-			MagLog::warning() << "Could not find the style " << name << " for " << family_ << endl;
+}
+
+void Palette::set(const json_spirit::Object& object)
+{
+	if ( methods_.empty() ) {
+		methods_["values"] =  &Palette::values;
+		methods_["tags"] =  &Palette::tags;
+	}	
+	for (vector<json_spirit::Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
+		map<string,  SetMethod>::iterator method = methods_.find(entry->name_);
+		if ( method != methods_.end() )
+			(this->*method->second)(entry->value_);
 		else 
-			MagLog::warning() << "Could not find the style " << name << " for " << family_ << " in " << theme_ << endl;
+			MagLog::warning() << entry->name_ << " is not a known keyword" << endl;
+    }	
+}
+void PaletteLibrary::callback(const string& name, const json_spirit::Value& value)
+{
+		
+	
+	Palette palette;
+	palette.name_ = name;
+	json_spirit::Object object = value.get_value< json_spirit::Object >();
+	palette.set(object);
+
+    library_.insert(make_pair(name, palette));
+    	
+}
+
+
+
+bool Style::find(const Definition& data, Definition& visdef)
+{
+	for (Definition::const_iterator value = data.begin(); value != data.end(); ++value) {
+		Definition::iterator criteria = criteria_.find(value->first);
+		if ( criteria != criteria_.end() && criteria->second == value->second ) {
+			visdef = style_;
+			for ( vector<Style>::iterator other = more_.begin(); other != more_.end(); ++other) 
+				if ( other->find(data, visdef) )
+					return true;
+			return true;
+		}
+	}
+	return false;
+
+}
+
+bool StyleLibrary::find(const Style::Definition& data, Style::Definition& visdef)
+{
+	for (vector<Style>::iterator style = library_.begin(); style != library_.end(); ++style)
+		if ( style->find(data, visdef) ) {
+			return true;
+		}
+
+	return false;
+
+}
+
+void NetcdfGuess::init()
+{
+	string library = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ +  "/" + name_ +".json";
+	MagLog::debug() << "Opening " << library << endl;
+	MagConfigHandler(library,  *this);
+}
+
+
+
+
+void NetcdfGuess::callback(const string& name, const json_spirit::Value& value)
+{
+	guess_.insert(make_pair(name, map<string, vector<string> >()));
+	if ( value.type() == json_spirit::obj_type ) {
+		json_spirit::Object object = value.get_value< json_spirit::Object >();
+		for (vector<json_spirit::Pair>::const_iterator entry = object.begin(); entry !=  object.end(); ++entry) {
+			guess_[name].insert(make_pair(entry->name_, vector<string>()));
+			json_spirit::Array values = (entry->value_).get_value<json_spirit::Array>();
+  			for (unsigned int i = 0; i < values.size(); i++) {
+  				guess_[name][entry->name_].push_back(convert(values[i]));
+    		}
+		}
+	}
+    	
+}
 
-		return empty_;
-}
\ No newline at end of file
diff --git a/src/web/MagConfig.h b/src/web/MagConfig.h
index b8c0a1d..f25a0e0 100644
--- a/src/web/MagConfig.h
+++ b/src/web/MagConfig.h
@@ -25,9 +25,10 @@ public:
 	MagConfig();
 	~MagConfig();
 
-	string convert(const json_spirit::Value&);
+	static string convert(const json_spirit::Value& value);
 
 	virtual void callback(const string&, const json_spirit::Value&) = 0;
+	virtual void callback(const json_spirit::Array&) {}
 
 };
 
@@ -60,6 +61,22 @@ private:
 
 };
 
+struct Style 
+{
+	typedef map<string, string> Definition;
+	typedef void  (Style::*SetMethod)(const json_spirit::Value&);
+	map<string,  SetMethod> methods_;
+	
+	void criteria(const json_spirit::Value&);
+	void style(const json_spirit::Value&);
+	void more(const json_spirit::Value&); 
+
+	Definition criteria_;
+	Definition style_;
+	vector<Style> more_;
+	void set(const json_spirit::Object&);
+	bool find(const Definition& data, Definition& visdef);
+};
 
 class StyleLibrary : public MagConfig
 {
@@ -69,18 +86,90 @@ public:
 	~StyleLibrary() {}
 
 	void callback(const string& name, const json_spirit::Value& value);
+	void callback(const json_spirit::Array& values);
 	void init();
 	
-	map<string, map<string, string> > library_;
-	map<string, string> empty_;
+	vector<Style> library_;
 
 	string theme_;
 	string family_;
 
-	const map<string, string>& get(const string& name) const;
+	bool find(const Style::Definition& data, Style::Definition& visdef);
+    
+    bool find(const string& name, Style::Definition& visdef) {
+    	Style::Definition criteria;
+    	criteria["name"] = name;
+    	return find(criteria, visdef);
+    }
+
+	
+	
+};
+
+struct Palette
+{
+	typedef vector<string> Definition;
+	typedef void  (Palette::*SetMethod)(const json_spirit::Value&);
+
+	map<string,  SetMethod> methods_;
+	
+	void values(const json_spirit::Value&);
+	void tags(const json_spirit::Value&);
+	
+
+	Definition colours_;
+	Definition tags_;
+	string name_;
+	void set(const json_spirit::Object&);
+
+	
+};
+
+
+class PaletteLibrary : public MagConfig
+{
+public:
+	PaletteLibrary() { init(); }
+	PaletteLibrary(const string& family)  { init(); }
+	~PaletteLibrary() {}
+
+	void callback(const string& name, const json_spirit::Value& value);
+	
+	void init();
+	
+	map<string, Palette> library_;
+
+    bool find(const string& name, Palette::Definition& colours) {
+    	
+    	map<string, Palette>::iterator palette = library_.find(name);
+
+    	if ( palette != library_.end() ) {
+    		colours = palette->second.colours_;
+    		return true;
+    	}
+    	return false;
+    }
+
+	
 	
 };
 
+class NetcdfGuess : public MagConfig
+{
+public:
+	NetcdfGuess(const string& name): name_(name)   { init(); }
+	NetcdfGuess(): name_("netcdf-convention") { init(); }
+	~NetcdfGuess() {}
+
+	void callback(const string& name, const json_spirit::Value& value);
+	void init();
+
+	string name_;
+
+	map<string, map<string, vector<string> > > guess_;	
+	const map<string, string>& get(const string& name) const;
+	
+};
 
 
 
diff --git a/test/bufr.py b/test/bufr.py
index 65f94e4..95abcb8 100644
--- a/test/bufr.py
+++ b/test/bufr.py
@@ -54,7 +54,7 @@ title = \
 
 # To the plot
 
-print "plot"
+print("plot")
 plot( output,  europe, obs, coast, )
 tofortran(ref, output,  europe, obs, coast, )
 
diff --git a/test/cairo.py b/test/cairo.py
index 95fab25..356d637 100644
--- a/test/cairo.py
+++ b/test/cairo.py
@@ -62,7 +62,7 @@ legend = mlegend(
 
 # To the plot
 
-print "plot"
+print("plot")
 plot( output,  europe, coast, )
 tofortran(ref, output,  europe, coast, )
 
diff --git a/test/grib.py b/test/grib.py
index c647607..ab04549 100644
--- a/test/grib.py
+++ b/test/grib.py
@@ -17,7 +17,7 @@ ref = 'grib'
 
 # Setting of the output file name
 
-output = output(output_formats=['ps'],
+output = output(output_formats=['png'],
                 output_name_first_page_number='off',
                 output_name=ref)
 
@@ -46,6 +46,7 @@ data = mgrib(grib_input_file_name='data.grib',
 
 
 
+
 cont = mcont(contour_automatic_setting='ecchart')
 
 title = \
@@ -73,7 +74,7 @@ legend = mlegend(
 
 # To the plot
 
-print "plot"
-plot( output,  europe, data, cont, coast, title)
+print("plot")
+plot( output,  data, cont, mcoast(),  title)
 
 
diff --git a/tools/RPM_build_specs/EmosLib.spec b/tools/RPM_build_specs/EmosLib.spec
deleted file mode 100644
index e8ddc8f..0000000
--- a/tools/RPM_build_specs/EmosLib.spec
+++ /dev/null
@@ -1,118 +0,0 @@
-Name: emos
-Version: 000370
-Release: 17.1
-Summary: Library and tools to handle Grib 1 and BUFR files
-URL: http://www.ecmwf.int/products/data/software/interpolation.html
-BuildRoot:    %{_tmppath}/emos-%{version}-build
-Source0: emos-%{version}.tar.bz
-License: LGPLv3
-Group: Productivity/Scientific/Other
-
-BuildRequires: gcc
-
-%if 0%{?suse_version}
-BuildRequires: gcc-fortran
-%else
-BuildRequires: gcc-gfortran
-%endif
-
-# Copyright 2009 ECMWF
-
-#!BuildIgnore: post-build-checks
-
-%description
-Runtime files of the ECMWF Emoslib, an application program interface accessible developed to do meteorological interpolation and for the encoding of WMO FM-92 GRIB edition 1 and BUFR files.
-
-Please be aware that this library is build in DOUBLE PRECISION for the use in Magics++ and Metview.
-
-
-
-%prep
-#cd /usr/src/packages/BUILD
-#tar -xzvf /usr/src/packages/SOURCES/emos_%{version}.tar.gz
-#echo $PWD
-%setup -q
-
-%build
-
-#cd emos_%{version}
-echo $PWD
-
-export R64=R64
-export CNAME=_gfortran
-export target=linux
-
-%ifarch x86_64
- export A64=A64
-%endif
-
-echo $R64 > .r64
-echo %_libdir > .emos
-
-cat Makefile.in | sed s:reals:$R64: > Makefile
-
-for subdirs in gribex pbio bufrdc bufrtables crexdc interpolation fft
-do
-cat $subdirs/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:depl:emos: | sed s:comp:$CNAME: > $subdirs/Makefile
-done
-
-for subdirs in examples/gribex examples/bufr examples/crex examples/interpolation examples/fft
-do
-cat $subdirs/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:comp:$CNAME: > $subdirs/Makefile
-done
-
-cat config/config.$target$CNAME$R64$A64.in | sed s:emos:$INSTALL_DIR: > config/config.$target$CNAME$R64$A64
-
-make
-ls bufrtables/*000* > .list/bufrtables
-
-%install
-# install all files into the BuildRoot
-#./install
-echo $PWD
-echo $RPM_BUILD_ROOT
-export R64=R64
-export INSTALL_DIR=$RPM_BUILD_ROOT/%_libdir
-
-mkdir -p $RPM_BUILD_ROOT/%_libdir
-
-echo "Installing Tables, land-sea mask and EMOS library into $INSTALL_DIR ... "
-
-
-mkdir -p $INSTALL_DIR/gribtables
-mkdir -p $INSTALL_DIR/bufrtables
-mkdir -p $INSTALL_DIR/crextables
-mkdir -p $INSTALL_DIR/land_sea_mask
-mkdir -p $INSTALL_DIR/gribtemplates
-
-for i in `cat .list/gribtables` ; do
-    cp $i $INSTALL_DIR/gribtables
-done
-for i in `cat .list/bufrtables` ; do
-    cp $i $INSTALL_DIR/bufrtables
-done
-for i in `cat .list/crextables` ; do
-    cp $i $INSTALL_DIR/crextables
-done
-for i in `cat .list/land_sea_mask` ; do
-    cp $i $INSTALL_DIR/land_sea_mask
-done
-for i in `cat .list/gribtemplates` ; do
-    cp $i $INSTALL_DIR/gribtemplates
-done
-
-cp libemos$R64.a $INSTALL_DIR/
-
-%clean
-# clean up the hard disc after build
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root,-)
-%_libdir/libemosR64.a
-%_libdir/bufrtables
-%_libdir/crextables
-%_libdir/gribtables
-%_libdir/gribtemplates
-%_libdir/land_sea_mask
-
diff --git a/tools/RPM_build_specs/emoslib/EmosLib.spec b/tools/RPM_build_specs/emoslib/EmosLib.spec
deleted file mode 100644
index 153e62e..0000000
--- a/tools/RPM_build_specs/emoslib/EmosLib.spec
+++ /dev/null
@@ -1,155 +0,0 @@
-Name: emos
-Version: 000382
-Release: 1.1
-Summary: Library and tools to handle Grib 1 and BUFR files
-URL: http://www.ecmwf.int/products/data/software/interpolation.html
-BuildRoot:    %{_tmppath}/emos-%{version}-build
-Source0: emos-%{version}.tar.bz
-License: LGPLv3
-Group: Productivity/Scientific/Other
-# Copyright 2011 ECMWF
-
-BuildRequires: gcc
-BuildRequires: grib_api  
-BuildRequires: grib_api-devel
-
-%if 0%{?suse_version}
-BuildRequires: gcc-fortran
-%else
-BuildRequires: gcc-gfortran
-%endif
-
-%if 0%{?suse_version} > 1100
-BuildRequires: libjasper-devel
-%endif
-
-
-#!BuildIgnore: post-build-checks
-
-Requires: grib_api
-
-%description
-Runtime files of the ECMWF Emoslib, an application program interface accessible developed to do meteorological interpolation and for the encoding of WMO FM-92 GRIB edition 1 and BUFR files.
-
-Please be aware that this library is build in DOUBLE PRECISION for the use in Magics++ and Metview.
-
-
-
-%prep
-
-%setup -q
-
-%build
-
-export R64=R64
-export CNAME=_gfortran
-export target=linux
-export GRIB_API=grib_api_merging
-export GRIB_API_DIR=/usr
-export JASPER_DIR="-ljasper"
-
-%ifarch x86_64
- export A64=A64
-%endif
-
-echo $R64 > .r64
-echo %_libdir > .emos
-
-# correct link options for 64bit
-%ifarch x86_64
-olds="DEBUG ="
-news="DEBUG = -fPIC "
-chmod +w config/config.$target$CNAME$R64$A64.in
-sed "s/${olds}/${news}/g" config/config.$target$CNAME$R64$A64.in > temp.in
-\mv -f temp.in config/config.$target$CNAME$R64$A64.in
-%endif
-
-#cat Makefile.in | sed s:reals:$R64: > Makefile
-cat Makefile.in | sed s:reals:$R64: | sed s:glue:grib_api_merging: > Makefile
-
-for subdirs in gribex pbio bufrdc bufrtables crexdc interpolation fft
-do
-cat $subdirs/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:depl:emos: | sed s:comp:$CNAME: > $subdirs/Makefile
-done
-
-for subdirs in examples/gribex examples/bufr examples/crex examples/interpolation examples/fft
-do
-cat $subdirs/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:comp:$CNAME: > $subdirs/Makefile
-done
-
-#grib_api
-cat grib_api_merging/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:comp:$CNAME: | sed s:depl:emos: | sed s:glue:$GRIB_API_DIR: > grib_api_merging/Makefile
-
-cat examples/interpolation_grib_api/Makefile.in | sed s:reals:$R64: | sed s:arch:$target: | sed s:plat:$A64: | sed s:comp:$CNAME: | sed s:glue:$GRIB_API_DIR: | sed s:jasp:$JASPER_DIR: > examples/interpolation_grib_api/Makefile
-
-cat config/config.$target$CNAME$R64$A64.in | sed s:emos:$INSTALL_DIR: > config/config.$target$CNAME$R64$A64
-
-
-make
-ls bufrtables/*000* > .list/bufrtables
-
-
-
-%install
-# install all files into the BuildRoot
-#./install
-echo $PWD
-echo $RPM_BUILD_ROOT
-export R64=R64
-export INSTALL_DIR=$RPM_BUILD_ROOT/%_libdir
-
-mkdir -p $RPM_BUILD_ROOT/%_libdir
-
-echo "Installing Tables, land-sea mask and EMOS library into $INSTALL_DIR ... "
-
-
-mkdir -p $INSTALL_DIR/gribtables
-mkdir -p $INSTALL_DIR/bufrtables
-mkdir -p $INSTALL_DIR/crextables
-mkdir -p $INSTALL_DIR/land_sea_mask
-mkdir -p $INSTALL_DIR/gribtemplates
-
-for i in `cat .list/gribtables` ; do
-    cp $i $INSTALL_DIR/gribtables
-done
-for i in `cat .list/bufrtables` ; do
-    cp $i $INSTALL_DIR/bufrtables
-done
-for i in `cat .list/crextables` ; do
-    cp $i $INSTALL_DIR/crextables
-done
-for i in `cat .list/land_sea_mask` ; do
-    cp $i $INSTALL_DIR/land_sea_mask
-done
-for i in `cat .list/gribtemplates` ; do
-    cp $i $INSTALL_DIR/gribtemplates
-done
-
-cp libemos$R64.a $INSTALL_DIR/
-
-%clean
-# clean up the hard disc after build
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root,-)
-%_libdir/libemosR64.a
-%_libdir/bufrtables
-%_libdir/crextables
-%_libdir/gribtables
-%_libdir/gribtemplates
-%_libdir/land_sea_mask
-
-%changelog
-
-* Tue Mar 22 2011 - magics at ecmwf.int
-- Full support for GRIB 2 files for interpolation
-- Links with GribAPI 1.9.9
-
-* Sun Feb 21 2011 - magics at ecmwf.int
-- update Emos version to 377 
-- Better GRIB 2 support
-
-* Sun Dec 19 2010 - magics at ecmwf.int
-- update Emos version to 376
-
diff --git a/tools/RPM_build_specs/emoslib/generateRPM.sh b/tools/RPM_build_specs/emoslib/generateRPM.sh
deleted file mode 100755
index 4803abb..0000000
--- a/tools/RPM_build_specs/emoslib/generateRPM.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-# (C) Copyright 1996-2016 ECMWF.
-# 
-# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
-
-
-logfile=$0_.log
-echo "Log is written in ${logfile}"
-exec > $logfile 2>&1
-set -x
-
-EMOS_VERSION=000380
-
-rpmspec=EmosLib.spec
-
-#
-#  generate SPEC file with emos version number
-#
-sed "s/000xxx/${EMOS_VERSION}/g" ${rpmspec}.in > ${rpmspec}
-
-#
-#   Prepare tarball in right format
-#
-tar -xzf emos_${EMOS_VERSION}.tar.gz
-\mv emos_${EMOS_VERSION} emos-${EMOS_VERSION}
-# correct link options for 64bit
-olds="DEBUG ="
-news="DEBUG = -fPIC "
-chmod +w emos-${EMOS_VERSION}/config/config.linux_gfortranR64A64.in
-sed "s/${olds}/${news}/g" emos-${EMOS_VERSION}/config/config.linux_gfortranR64A64.in > temp.in
-\mv -f temp.in emos-${EMOS_VERSION}/config/config.linux_gfortranR64A64.in
-tar -cjf emos-${EMOS_VERSION}.tar.bz emos-${EMOS_VERSION}
-\rm -rf emos-${EMOS_VERSION}
-
-#
-#  SRC RPM
-#
-rpmbuild --nodeps --buildroot=${PWD}/_rpm -bs \
-	--define="_rpmdir ${PWD}"  --define="_srcrpmdir ${PWD}" --define="_sourcedir ${PWD}" \
-	--define="_specdir ${PWD}" --define="_builddir ${PWD}" \
-	${rpmmacros} ${rpmspec}
-
-#
-#  BIN RPM
-#
-rpmbuild --nodeps --buildroot=${PWD}/_rpm -ba \
-	--define="_rpmdir ${PWD}"  --define="_sourcedir ${PWD}" \
-	--define="_specdir ${PWD}" --define="_builddir ${PWD}" \
-	${rpmmacros} ${rpmspec}
-
-\rm -rf emos-000380.tar.bz emos-000380 ${rpmspec}
diff --git a/tools/RPM_build_specs/grib_api/rpms/grib_api.spec b/tools/RPM_build_specs/grib_api/rpms/grib_api.spec
deleted file mode 100644
index e408665..0000000
--- a/tools/RPM_build_specs/grib_api/rpms/grib_api.spec
+++ /dev/null
@@ -1,96 +0,0 @@
-Name: grib_api
-Version: 1.9.9
-Release: 2.1
-Summary: Library and tools to handle Grib 1 and 2 files
-URL:http://www.ecmwf.int/products/data/software/grib_api.html
-BuildRoot:    %{_tmppath}/%{name}-%{version}-build
-Source0: %{name}-%{version}.tar.gz
-License: LGPLv3
-Group: Productivity/Scientific/Other
-
-#
-# Build requirements
-#
-BuildRequires: gcc
-
-%if 0%{?suse_version} >= 1130
-BuildRequires: python-numpy-devel python-devel swig
-Requires: python python-numpy
-%endif
-
-%if 0%{?suse_version}  
-BuildRequires: gcc-fortran  
-%else  
-BuildRequires: gcc-gfortran  
-%endif
-
-#
-#  SLES 9 & 10 do NOT have jasper!!!
-#
-%if 0%{?sles_version} != 10 && 0%{?sles_version} != 9 && 0%{?centos_version} < 100 
-PreReq: libjasper-devel
-%endif
-
-
-# Copyright 2010 ECMWF
-
-#!BuildIgnore: post-build-checks
-
-%description
-Runtime files of the ECMWF GRIB API is an application program interface accessible from C and FORTRAN programs developed for encoding and decoding WMO FM-92 GRIB edition 1 and edition 2 messages. A useful set of command line tools is also provided to give quick access to grib messages.
-
-%package devel
-Summary: Developing package for grib_api
-Group: Development/Libraries
-%description devel
-Header files and library of the ECMWF GRIB API is an application program interface accessible from C and FORTRAN programs developed for encoding and decoding WMO FM-92 GRIB edition 1 and edition 2 messages. A useful set of command line tools is also provided to give quick access to grib messages.
-
-
-%prep
-%setup -q
-%build
-%if 0%{?sles_version} == 10 || 0%{?sles_version} == 9 || 0%{?centos_version} > 500 
-  ./configure --prefix=/usr --libdir=%_libdir CFLAGS="$CFLAGS -fPIC" --disable-jpeg
-%else
-%if 0%{?suse_version} >= 1130
-  ./configure --prefix=/usr --libdir=%_libdir CFLAGS="$CFLAGS -fPIC" --enable-python
-%else
-  ./configure --prefix=/usr --libdir=%_libdir CFLAGS="$CFLAGS -fPIC"
-%endif
-%endif
-
-make
-%install
-# install all files into the BuildRoot
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-# clean up the hard disc after build
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root,-)
-/usr/bin/grib*
-/usr/bin/tigge*
-/usr/bin/big2gribex
-/usr/bin/parser
-/usr/bin/points
-/usr/bin/gg_sub_area_check
-/usr/share/definitions
-%if 0%{?suse_version} == 1130
-%_libdir/python2.6/site-packages/grib_api
-%endif
-%if 0%{?suse_version} > 1130
-%_libdir/python2.7/site-packages/grib_api
-%endif
-
-%files devel
-%defattr(-,root,root,-)
-/usr/include/grib_api.h
-/usr/include/grib_api.mod
-/usr/include/grib_api_f77.h
-%_libdir/libgrib_api.a
-%_libdir/libgrib_api_f77.a
-%_libdir/libgrib_api_f90.a
-/usr/ifs_samples
-/usr/share/samples
diff --git a/tools/docs.json b/tools/docs.json
new file mode 100644
index 0000000..a0c9705
--- /dev/null
+++ b/tools/docs.json
@@ -0,0 +1,6421 @@
+{
+    "Binary": {}, 
+    "pcdfgram": {
+        "cdf_clim_line_thickness": {
+            "default": "4", 
+            "from": "int"
+        }, 
+        "cdf_clim_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "efi_box_border_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "cdf_lines_thickness_array": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "efi_font_style": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "efi_box_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "cdf_clim_line_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "efi_box_border_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "efi_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "efi_box_colour_array": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "cdf_lines_colour_array": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "efi_normal_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "efi_font_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "cdf_lines_style_array": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "efi_normal_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "efi_normal_thickness": {
+            "default": "4", 
+            "from": "int"
+        }
+    }, 
+    "projection": {
+        "subpage_upper_right_longitude": {
+            "default": "180.0", 
+            "from": "float"
+        }, 
+        "subpage_map_centre_longitude": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "subpage_minimal_area": {
+            "default": "0.1", 
+            "from": "float"
+        }, 
+        "subpage_map_geos_sweep": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "subpage_lower_left_longitude": {
+            "default": "-180.0", 
+            "from": "float"
+        }, 
+        "subpage_map_area_coordinate_system": {
+            "default": "users", 
+            "from": "string"
+        }, 
+        "subpage_map_centre_latitude": {
+            "default": "90.0", 
+            "from": "float"
+        }, 
+        "subpage_map_hemisphere": {
+            "default": "north", 
+            "from": "string"
+        }, 
+        "subpage_map_proj4_definition": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "subpage_map_area_definition": {
+            "default": "full", 
+            "from": "string"
+        }, 
+        "subpage_lower_left_latitude": {
+            "default": "-90.0", 
+            "from": "float"
+        }, 
+        "subpage_map_vertical_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "subpage_upper_right_latitude": {
+            "default": "90.0", 
+            "from": "float"
+        }, 
+        "subpage_coordinates_system": {
+            "default": "latlon", 
+            "from": "string"
+        }, 
+        "subpage_map_area_definition_polar": {
+            "default": "corners", 
+            "from": "string"
+        }, 
+        "subpage_map_scale": {
+            "default": "50.e6", 
+            "from": "float"
+        }
+    }, 
+    "pimport": {
+        "layers": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "import_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "import_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "import_y_position": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "import_format": {
+            "default": "png", 
+            "from": "string"
+        }, 
+        "service": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "url": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "import_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "import_valid_time": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "import_x_position": {
+            "default": "0", 
+            "from": "float"
+        }
+    }, 
+    "pline": {
+        "polyline_pivot_marker_name": {
+            "default": "cyclone", 
+            "from": "string"
+        }, 
+        "polyline_trajectory_factor": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "polyline_line_style_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_transparency_pivot_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "polyline_input_longitudes": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_shade_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "polyline_shade_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "polyline_input_latitudes": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_thickness_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_colour_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_priority_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_shade_min_level": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "polyline_pivot_marker_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "polyline_shade_level_selection_type": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "polyline_thickness_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_shade_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "polyline_transparency_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_input_values_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_thickness_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_level_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "polyline_colour_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "polyline_line_style_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "polyline_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "polyline_line_style_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "polyline_shade_colour_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }, 
+        "polyline_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "polyline_line_style_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_input_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "polyline_input_break_indicator": {
+            "default": "-999", 
+            "from": "float"
+        }, 
+        "polyline_pivot_marker": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "polyline_shade_colour_method": {
+            "default": "calculate", 
+            "from": "string"
+        }, 
+        "polyline_input_positions_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_colour_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_trajectory_pivot_index": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "polyline_thickness_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "polyline_shade": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "polyline_level_tolerance": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "polyline_reference_level": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "polyline_shade_max_level": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "polyline_transparency_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "polyline_interval": {
+            "default": "8.0", 
+            "from": "float"
+        }, 
+        "polyline_legend_only": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "polyline_line_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "polyline_effect_method": {
+            "default": "classic", 
+            "from": "string"
+        }, 
+        "polyline_pivot_marker_height": {
+            "default": "0.4", 
+            "from": "float"
+        }, 
+        "polyline_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }
+    }, 
+    "pwind": {
+        "wind_legend_text": {
+            "default": "vector", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_level_tolerance": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "wind_arrow_head_shape": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "wind_flag_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "wind_thinning_debug": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "wind_flag_calm_below": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "wind_flag_calm_indicator": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "wind_flag_length": {
+            "default": "1.0", 
+            "from": "float"
+        }, 
+        "wind_streamline_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_table_colour_method": {
+            "default": "calculate", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_selection_type": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "wind_arrow_unit_velocity": {
+            "default": "25.0", 
+            "from": "float"
+        }, 
+        "wind_streamline_head_ratio": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "wind_thinning_method": {
+            "default": "data", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_min_value": {
+            "default": "-1.e21", 
+            "from": "float"
+        }, 
+        "wind_advanced_colour_max_value": {
+            "default": "1.e21", 
+            "from": "float"
+        }, 
+        "wind_advanced_colour_reference_level": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "wind_streamline_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "wind_flag_calm_indicator_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "wind_arrow_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "wind_streamline_min_density": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "wind_arrow_calm_indicator": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "wind_flag_origin_marker": {
+            "default": "circle", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "wind_streamline_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "wind_advanced_colour_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }, 
+        "wind_flag_cross_boundary": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "wind_flag_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "wind_flag_origin_marker_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "wind_arrow_head_ratio": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "wind_advanced_colour_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "wind_flag_max_speed": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "wind_advanced_colour_parameter": {
+            "default": "speed", 
+            "from": "string"
+        }, 
+        "wind_arrow_min_speed": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "wind_flag_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "wind_arrow_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "wind_arrow_calm_below": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "wind_arrow_legend_text": {
+            "default": "m/s", 
+            "from": "string"
+        }, 
+        "wind_flag_min_speed": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "wind_arrow_calm_indicator_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "wind_legend_only": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "wind_thinning_factor": {
+            "default": "2.0", 
+            "from": "float"
+        }, 
+        "wind_arrow_unit_system": {
+            "default": "paper", 
+            "from": "string"
+        }, 
+        "wind_arrow_max_speed": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "wind_arrow_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "wind_field_type": {
+            "default": "arrows", 
+            "from": "string"
+        }, 
+        "wind_advanced_colour_level_interval": {
+            "default": "8.0", 
+            "from": "float"
+        }, 
+        "wind_streamline_min_speed": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "wind_advanced_colour_level_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "wind_advanced_colour_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "wind_arrow_origin_position": {
+            "default": "tail", 
+            "from": "string"
+        }, 
+        "wind_streamline_head_shape": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "wind_advanced_method": {
+            "default": "off", 
+            "from": "string"
+        }
+    }, 
+    "PostScript": {
+        "output_ps_colour_model": {
+            "default": "rgb", 
+            "from": "string"
+        }, 
+        "output_ps_split": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "output_ps_scale": {
+            "default": "1.0", 
+            "from": "float"
+        }
+    }, 
+    "pmetgram": {
+        "epsbufr_short_title": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "metgram_flag_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "metgram_time": {
+            "default": "0000", 
+            "from": "string"
+        }, 
+        "epsbufr_parameter_title": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_plume_control": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_plume_legend": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "epsxml_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "metgram_bar_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "eps_plume_median_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "metgram_parameter_title": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "epsbufr_parameter_2_descriptor": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "eps_plume_forecast_line_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "metgram_database": {
+            "default": "/vol/epsgram/data/spotbase/epsdb", 
+            "from": "string"
+        }, 
+        "metgram_latitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_shade_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "eps_plume_control_line_thickness": {
+            "default": "5", 
+            "from": "int"
+        }, 
+        "metgram_curve_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "eps_plume_forecast_line_thickness": {
+            "default": "5", 
+            "from": "int"
+        }, 
+        "eps_direction_line_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "metgram_bar_keyword": {
+            "default": "curve1", 
+            "from": "string"
+        }, 
+        "efi_legend": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "epsxml_title": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "epsbufr_accumulated_parameter": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "metgram_station_height": {
+            "default": "-1.", 
+            "from": "float"
+        }, 
+        "epsbufr_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "epsbufr_station_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "metgram_curve2_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "eps_plume_forecast": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "epsbufr_parameter_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "eps_plume_forecast_line_colour": {
+            "default": "cyan", 
+            "from": "string"
+        }, 
+        "metgram_curve_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "metgram_station_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_legend_normal_thickness": {
+            "default": "4", 
+            "from": "int"
+        }, 
+        "eps_plume_method": {
+            "default": "time_serie", 
+            "from": "string"
+        }, 
+        "eps_plume_members": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "efi_long_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "metgram_date": {
+            "default": "-1", 
+            "from": "string"
+        }, 
+        "eps_plume_control_line_colour": {
+            "default": "cyan", 
+            "from": "string"
+        }, 
+        "epsbufr_y_axis_percentile": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "eps_plume_control_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "epsbufr_parameter_descriptor": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "efi_legend_box_type": {
+            "default": "both", 
+            "from": "string"
+        }, 
+        "efi_legend_normal_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "eps_shade_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "eps_plume_median": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "efi_legend_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "metgram_curve_keyword2": {
+            "default": "curve2", 
+            "from": "string"
+        }, 
+        "metgram_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_plume_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "metgram_flag_component2": {
+            "default": "curve2", 
+            "from": "string"
+        }, 
+        "metgram_flag_component1": {
+            "default": "curve1", 
+            "from": "string"
+        }, 
+        "metgram_flag_method": {
+            "default": "SD", 
+            "from": "string"
+        }, 
+        "metgram_curve2_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "metgram_long_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "metgram_flag_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "epsbufr_information": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "metgram_parameter_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "metgram_curve_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "epsxml_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_direction_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "eps_shade_line_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "eps_plume_shading": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "efi_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "metgram_flag_length": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "eps_plume_median_line_thickness": {
+            "default": "5", 
+            "from": "int"
+        }, 
+        "epsbufr_y_axis_threshold": {
+            "default": "50", 
+            "from": "float"
+        }, 
+        "metgram_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_plume_shading_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "eps_plume_line_colour": {
+            "default": "magenta", 
+            "from": "string"
+        }, 
+        "eps_direction_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "eps_plume_shading_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "efijson_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "metgram_curve2_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "epsbufr_title": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "epsbufr_station_latitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "metgram_curve_keyword": {
+            "default": "curve1", 
+            "from": "string"
+        }, 
+        "metgram_parameter_offset": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "epsbufr_parameter_offset_factor": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_plume_median_line_colour": {
+            "default": "cyan", 
+            "from": "string"
+        }, 
+        "epsxml_long_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "eps_plume_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "metgram_temperature_correction": {
+            "default": "yes", 
+            "from": "string"
+        }, 
+        "epsbufr_station_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_shade_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "eps_direction_keyword": {
+            "default": "forecast", 
+            "from": "string"
+        }, 
+        "metgram_plot_style": {
+            "default": "curve", 
+            "from": "string"
+        }
+    }, 
+    "GeoJson": {
+        "geojson_link": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "geojson_description": {
+            "default": "Generated by Magics++", 
+            "from": "string"
+        }, 
+        "geojson_zip": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "geojson_author": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "geojson_coastlines": {
+            "default": "off", 
+            "from": "string"
+        }
+    }, 
+    "pimage": {
+        "image_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "image_pixel_selection_frequency": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "image_colour_table_creation_mode": {
+            "default": "equidistant", 
+            "from": "string"
+        }, 
+        "image_level_count": {
+            "default": "127", 
+            "from": "int"
+        }, 
+        "image_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "image_colour_table_type": {
+            "default": "computed", 
+            "from": "string"
+        }, 
+        "image_colour_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }
+    }, 
+    "pcoast": {
+        "map_label_top": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_coastline_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_label_latitude_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_coastline": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_cities": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_rivers_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_administrative_boundaries_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_grid_frame": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_efas": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_label_bottom": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_coastline_sea_shade_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "map_disputed_boundaries_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "map_efas_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_disputed_boundaries_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "map_grid_latitude_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "map_boundaries_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_cities_marker_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "map_grid_longitude_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "map_administrative_boundaries_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "map_label_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "map_grid_latitude_increment": {
+            "default": "10", 
+            "from": "float"
+        }, 
+        "map_coastline_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_user_layer_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_label_blanking": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_grid_colour": {
+            "default": "BLACK", 
+            "from": "string"
+        }, 
+        "map_coastline_sea_shade": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_grid_frame_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_cities_name_position": {
+            "default": "above", 
+            "from": "string"
+        }, 
+        "map_preview": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_administrative_boundaries_countries_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "map_grid_frame_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "map_user_layer_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "map_cities_unit_system": {
+            "default": "percent", 
+            "from": "string"
+        }, 
+        "map_label_left": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_disputed_boundaries_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "map_boundaries": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_coastline_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "map_rivers_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "map_user_layer": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_boundaries_colour": {
+            "default": "grey", 
+            "from": "string"
+        }, 
+        "map_cities_font_size": {
+            "default": "2.5", 
+            "from": "float"
+        }, 
+        "map_user_layer_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "map_cities_marker": {
+            "default": "plus", 
+            "from": "string"
+        }, 
+        "map_user_layer_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_cities_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "map_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_cities_font_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "map_efas_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "map_label_longitude_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_administrative_boundaries": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_cities_marker_height": {
+            "default": "0.7", 
+            "from": "float"
+        }, 
+        "map_administrative_boundaries_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "map_grid_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_cities_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "map_coastline_resolution": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "map_coastline_land_shade_colour": {
+            "default": "green", 
+            "from": "string"
+        }, 
+        "map_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "map_efas_domain": {
+            "default": "current", 
+            "from": "string"
+        }, 
+        "map_label_height": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "map_rivers_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "map_coastline_land_shade": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_grid_frame_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_coastline_general_style": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "map_boundaries_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_disputed_boundaries": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "map_efas_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "map_grid_longitude_increment": {
+            "default": "20", 
+            "from": "float"
+        }, 
+        "map_rivers": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "map_label_right": {
+            "default": "on", 
+            "from": "string"
+        }
+    }, 
+    "popen/pnew": {
+        "plot_direction": {
+            "default": "vertical", 
+            "from": "string"
+        }, 
+        "plot_start": {
+            "default": "bottom", 
+            "from": "string"
+        }
+    }, 
+    "xml": {
+        "efi_record": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "efi_filename": {
+            "default": "", 
+            "from": "string"
+        }
+    }, 
+    "pgrib": {
+        "grib_field_position": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "grib_interpolation_method": {
+            "default": "interpolate", 
+            "from": "string"
+        }, 
+        "grib_text_units": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "grib_interpolation_method_missing_fill_count": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "grib_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "grib_wind_position_2": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "grib_wind_position_1": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "grib_loop_step": {
+            "default": "loopondate", 
+            "from": "string"
+        }, 
+        "grib_dimension": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "grib_automatic_scaling": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "grib_missing_value_indicator": {
+            "default": "-1.5e+21", 
+            "from": "float"
+        }, 
+        "grib_id": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "grib_loop_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "grib_wind_mode": {
+            "default": "uv", 
+            "from": "string"
+        }, 
+        "grib_position_colour": {
+            "default": "longintarray()", 
+            "from": "longintarray"
+        }, 
+        "grib_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "grib_text_experiment": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "grib_automatic_derived_scaling": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "grib_file_address_mode": {
+            "default": "record", 
+            "from": "string"
+        }, 
+        "grib_wind_position_colour": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "grib_position": {
+            "default": "longintarray()", 
+            "from": "longintarray"
+        }, 
+        "grib_loop_step_span": {
+            "default": "3", 
+            "from": "float"
+        }, 
+        "grib_position_1": {
+            "default": "longintarray()", 
+            "from": "longintarray"
+        }, 
+        "grib_position_2": {
+            "default": "longintarray()", 
+            "from": "longintarray"
+        }, 
+        "grib_scaling_offset": {
+            "default": "0", 
+            "from": "float"
+        }
+    }, 
+    "pobsjson": {
+        "obsjson_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "obsjson_info_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }
+    }, 
+    "pnetcdf": {
+        "netcdf_x_position_variable": {
+            "default": "x", 
+            "from": "string"
+        }, 
+        "netcdf_longitude_variable": {
+            "default": "longitude", 
+            "from": "string"
+        }, 
+        "netcdf_x_variable": {
+            "default": "x", 
+            "from": "string"
+        }, 
+        "netcdf_speed_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_y_auxiliary_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_type": {
+            "default": "matrix", 
+            "from": "string"
+        }, 
+        "netcdf_field_add_offset": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "netcdf_field_suppress_above": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "netcdf_y_position_variable": {
+            "default": "y", 
+            "from": "string"
+        }, 
+        "netcdf_missing_attribute": {
+            "default": "_FillValue", 
+            "from": "string"
+        }, 
+        "netcdf_latitude_variable": {
+            "default": "latitude", 
+            "from": "string"
+        }, 
+        "netcdf_dimension_setting_method": {
+            "default": "value", 
+            "from": "string"
+        }, 
+        "netcdf_x2_variable": {
+            "default": "x2", 
+            "from": "string"
+        }, 
+        "netcdf_y2_variable": {
+            "default": "y2", 
+            "from": "string"
+        }, 
+        "netcdf_colour_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_x_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_value_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_y_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_x_auxiliary_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_y_geoline_convention": {
+            "default": "lonlat", 
+            "from": "string"
+        }, 
+        "netcdf_direction_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "netcdf_x_geoline_convention": {
+            "default": "lonlat", 
+            "from": "string"
+        }, 
+        "netcdf_field_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "netcdf_field_suppress_below": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "netcdf_metadata": {
+            "default": "{}", 
+            "from": "string"
+        }, 
+        "netcdf_reference_date": {
+            "default": "0", 
+            "from": "string"
+        }, 
+        "netcdf_longitude_sample": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "netcdf_latitude_sample": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "netcdf_matrix_primary_index": {
+            "default": "longitude", 
+            "from": "string"
+        }, 
+        "netcdf_y_variable": {
+            "default": "y", 
+            "from": "string"
+        }, 
+        "netcdf_dimension_setting": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }
+    }, 
+    "pmapgen": {
+        "mapgen_record": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "mapgen_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }
+    }, 
+    "unknown": {
+        "graph_bar_annotation": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "graph_missing_data_mode": {
+            "default": "ignore", 
+            "from": "string"
+        }, 
+        "y_base_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_font_size": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "obs_wind_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "landgram_top_box2_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "y_upper_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "histogram_level_tolerance": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "graph_thickness_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "page_id_line_logo_plot": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_months_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "table_combine_delimiters": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "box_left": {
+            "default": "5%", 
+            "from": "string"
+        }, 
+        "obs_high_cloud": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_field_x_coordinates": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "y_lower_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "graph_bar_line_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_height_method": {
+            "default": "list", 
+            "from": "string"
+        }, 
+        "y2_base_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "page_id_line_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "axis_days_label_composition": {
+            "default": "three", 
+            "from": "string"
+        }, 
+        "blanking": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "user_logo_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "symbol_text_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "y_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "input_field_initial_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "user_logo_left": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_tip_title_quality": {
+            "default": "medium", 
+            "from": "string"
+        }, 
+        "ppm_min_latitude": {
+            "default": "-90", 
+            "from": "float"
+        }, 
+        "obs_time_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "obs_past_weather": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_whisker_line_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "obs_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "graph_symbol": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "page_id_line_magics": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "y_upper_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_min_table": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "obs_sea_temperature_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "graph_bar_justification": {
+            "default": "centre", 
+            "from": "string"
+        }, 
+        "table_x_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "symbol_input_y_position": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "output_width": {
+            "default": "800", 
+            "from": "int"
+        }, 
+        "javascript_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "table_y_component_variable": {
+            "default": "-1", 
+            "from": "string"
+        }, 
+        "image_min_level": {
+            "default": "-1.0e+21", 
+            "from": "int"
+        }, 
+        "y_date_offset": {
+            "default": "second", 
+            "from": "string"
+        }, 
+        "axis_grid_reference_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "output_filelist_name": {
+            "default": "magics_outputs.lst", 
+            "from": "string"
+        }, 
+        "boxplot_box_colour": {
+            "default": "sky", 
+            "from": "string"
+        }, 
+        "input_wind_direction": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "obs_past_weather_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "graph_line_style_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "symbol_max_table": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "boxplot_whisker_line_thickness": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "obs_ring_size": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "table_latitude_variable": {
+            "default": "2", 
+            "from": "string"
+        }, 
+        "symbol_marker_mode": {
+            "default": "index", 
+            "from": "string"
+        }, 
+        "magnifier_hidden_symbol_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "graph_thickness_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "mgb_height": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "output_creator": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_tick_label_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "frame": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "root_node_orientation": {
+            "default": "landscape", 
+            "from": "string"
+        }, 
+        "landgram_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_years_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "input_field": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "obs_visibility_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "output_debug": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "graph_bar_annotation_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "input_x2_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "output_png_transparent": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "graph_colour_value_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "text_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "input_date_y2_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "page_id_line_system_plot": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_y_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "input_type": {
+            "default": "cartesian", 
+            "from": "string"
+        }, 
+        "symbol_text_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "magnifier_text_font_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "input_field_y_coordinates": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "y_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "graph_missing_data_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "graph_colour_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "symbol_colour_table": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "graph_symbol_marker_index": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "histogram_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "axis_title_orientation": {
+            "default": "parallel", 
+            "from": "string"
+        }, 
+        "image_outlayer_rejection": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "axis_tick_label_last": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_field_initial_x": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "input_field_initial_y": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "input_date_x_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "magnifier_text_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "boxplot_box_border_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "graph_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "landgram_bottom_box1_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "box_height": {
+            "default": "10%", 
+            "from": "string"
+        }, 
+        "axis_tick_position_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_outlayer_min_value": {
+            "default": "-1.e21", 
+            "from": "float"
+        }, 
+        "obs_level_2": {
+            "default": "1000", 
+            "from": "int"
+        }, 
+        "boxplot_whisker_box_colour": {
+            "default": "sky", 
+            "from": "string"
+        }, 
+        "graph_arrow_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "input_field_longitudes": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "obs_sea_temperature": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_median_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "table_longitude_variable": {
+            "default": "1", 
+            "from": "string"
+        }, 
+        "symbol_position_mode": {
+            "default": "geographic", 
+            "from": "string"
+        }, 
+        "obs_station_ring_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "symbol_height_table": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "graph_symbol_outline_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "root_node_frame_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "obs_height_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "x2_date_offset": {
+            "default": "second", 
+            "from": "string"
+        }, 
+        "profile_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "graph_style_setting": {
+            "default": "simple", 
+            "from": "string"
+        }, 
+        "obs_time": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "x_lower_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "user_logo_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "obs_distance_apart": {
+            "default": "1.0", 
+            "from": "float"
+        }, 
+        "axis_days_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "axis_hours_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "input_field_final_y_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "sql_observation": {
+            "default": "observation", 
+            "from": "string"
+        }, 
+        "height": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "histogram_interval": {
+            "default": "8.0", 
+            "from": "float"
+        }, 
+        "page_id_line_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "obs_dewpoint": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_median": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_field_suppress_above": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "axis_months_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "efi_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "input_field_suppress_below": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "obs_demo2_text_colour": {
+            "default": "cyan", 
+            "from": "string"
+        }, 
+        "obs_upper_air_pressure": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "table_y_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "input_field_latitudes": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "obs_present_weather": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_name_table": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "input_field_final_y": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "output_file_minimal_width": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "graph_line_style_value_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "input_field_final_x_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "graph_type": {
+            "default": "curve", 
+            "from": "string"
+        }, 
+        "box_width": {
+            "default": "85%", 
+            "from": "string"
+        }, 
+        "graph_missing_data_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "symbol_input_wind_direction": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "graph_bar_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "obs_waves_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "sql_database": {
+            "default": "obs.bufr", 
+            "from": "string"
+        }, 
+        "obs_wind": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_months_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_days_label_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "axis_hours_label_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "histogram_bar_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "axis_tick": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_colour": {
+            "default": "BLUE", 
+            "from": "string"
+        }, 
+        "graph_flag_length": {
+            "default": "0.75", 
+            "from": "float"
+        }, 
+        "graph_shade_hatch_index": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "x_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "landgram_input_offset_factor": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "graph_shade_dot_density": {
+            "default": "20", 
+            "from": "int"
+        }, 
+        "x_lower_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "axis_tick_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "obs_type_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "graph_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "landgram_title": {
+            "default": "landgram parameter", 
+            "from": "string"
+        }, 
+        "axis_tick_label_height": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "table_header_row": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "obs_level_tolerance": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "input_field_y_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_min_value": {
+            "default": "-1.e21", 
+            "from": "float"
+        }, 
+        "output_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "metadata_path": {
+            "default": "meta.xml", 
+            "from": "string"
+        }, 
+        "input_field_subpage_mapping": {
+            "default": "upper_left", 
+            "from": "string"
+        }, 
+        "histogram_selection_type": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "page_id_line_logo_name": {
+            "default": "ecmwf", 
+            "from": "string"
+        }, 
+        "axis_grid_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "axis_tick_position": {
+            "default": "out", 
+            "from": "string"
+        }, 
+        "input_field_x_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_text_list_policy": {
+            "default": "cycle", 
+            "from": "string"
+        }, 
+        "user_logo_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "boxplot_median_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "obs_level": {
+            "default": "500", 
+            "from": "int"
+        }, 
+        "axis_years_label_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "obs_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "output_frame_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "orientation": {
+            "default": "landscape", 
+            "from": "string"
+        }, 
+        "output_title": {
+            "default": "Magics plot", 
+            "from": "string"
+        }, 
+        "boxplot_median_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "input_field_initial_y_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "boxplot_whisker_box_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "landgram_bottom_box1_shading": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "magnifier_symbol_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_text_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "boxplot_maximum_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "axis_grid_reference_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "axis_position": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "obs_medium_cloud_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "graph_line_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "axis_tick_size": {
+            "default": "0.175", 
+            "from": "float"
+        }, 
+        "input_field_initial_x_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_tick_label_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "x_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "axis_tip_title_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "ppm_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_minor_tick_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "image_max_level": {
+            "default": "1.0e+21", 
+            "from": "int"
+        }, 
+        "page_id_line_date_plot": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_x_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "output_gif_delay": {
+            "default": "100", 
+            "from": "int"
+        }, 
+        "symbol_advanced_table_colour_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "input_wind_v_component": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "axis_title_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "boxplot_box_upper_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "boxplot_whisker_box_border_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "graph_bar_clipping": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "page_id_line_height": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "mgb_transparency": {
+            "default": "1.0", 
+            "from": "float"
+        }, 
+        "axis_years_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_marker_name_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "boxplot_whisker_box_width": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "graph_flag_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "axis_tick_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "wrep_node_height": {
+            "default": "400", 
+            "from": "float"
+        }, 
+        "graph_bar_width": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "output_fullname": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "symbol_image_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "graph_shade": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_level_tolerance": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "axis_grid_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "axis_grid_reference_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_text_font_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "sql_query": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "input_field_y_step": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "graph_symbol_outline_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "obs_low_cloud": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "input_field_x_step": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "axis_years_label_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "output_name_first_page_number_value": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "y2_date_offset": {
+            "default": "second", 
+            "from": "string"
+        }, 
+        "axis_minor_grid": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "output_filelist_reset": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "input_y_missing_value": {
+            "default": "-21.e6", 
+            "from": "float"
+        }, 
+        "obs_visibility": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_marker_table": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "input_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "table_x_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "x2_base_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "sql_longitude": {
+            "default": "longitude", 
+            "from": "string"
+        }, 
+        "obs_station_ring": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_title": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_box_width": {
+            "default": "1.0", 
+            "from": "float"
+        }, 
+        "graph_curve_method": {
+            "default": "straight", 
+            "from": "string"
+        }, 
+        "contour_sample_y_interval": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "axis_days_sunday_label_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "axis_line": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "histogram_min_value": {
+            "default": "-1.e21", 
+            "from": "float"
+        }, 
+        "axis_minor_grid_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "obs_temperature_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "table_value_variable": {
+            "default": "-1", 
+            "from": "string"
+        }, 
+        "axis_tick_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "graph_shade_style": {
+            "default": "area_fill", 
+            "from": "string"
+        }, 
+        "input_x_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "x_upper_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "input_y_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_text_position": {
+            "default": "right", 
+            "from": "string"
+        }, 
+        "axis_months_label_composition": {
+            "default": "three", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_text_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "format": {
+            "default": "a4", 
+            "from": "string"
+        }, 
+        "axis_minor_tick_count": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "symbol_input_number_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "graph_thickness_value_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "axis_minor_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "boxplot_positions": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "x_upper_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "axis_title_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "input_date_y_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "input_y_component_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_legend_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "symbol_image_format": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "box_bottom": {
+            "default": "80%", 
+            "from": "string"
+        }, 
+        "axis_tick_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "axis_tick_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "root_node_frame_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "graph_line_style_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "boxplot_median_thickness": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "graph_x_suppress_above": {
+            "default": "LLONG_MAX", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_height_max_value": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "symbol_text_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "input_y2_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_text_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "symbol_input_x_position": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "graph_bar_annotation_font_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "graph_symbol_outline": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "boxplot_whisker": {
+            "default": "line", 
+            "from": "string"
+        }, 
+        "page_id_line_user_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "table_data_row_offset": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "axis_days_label_position": {
+            "default": "12", 
+            "from": "int"
+        }, 
+        "boxplot_whisker_box_border": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "page_id_line_user_text_plot": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_box": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "obs_thickness": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_line_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "axis_tip_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "meta": {
+            "default": "nometadata", 
+            "from": "string"
+        }, 
+        "graph_symbol_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "axis_minor_grid_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "x_date_offset": {
+            "default": "second", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "efi_template": {
+            "default": "efi_template.js", 
+            "from": "string"
+        }, 
+        "axis_type": {
+            "default": "regular", 
+            "from": "string"
+        }, 
+        "graph_bar_style": {
+            "default": "bar", 
+            "from": "string"
+        }, 
+        "page_id_line_errors_plot": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_input_wind_speed": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "axis_tick_label_orientation": {
+            "default": "horizontal", 
+            "from": "string"
+        }, 
+        "y2_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "magnifier_text_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "input_field_longitude_step": {
+            "default": "1.5", 
+            "from": "float"
+        }, 
+        "obs_low_cloud_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "x_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_advanced_table_height_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "axis_line_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "symbol_image_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "graph_y_suppress_above": {
+            "default": "LLONG_MAX", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_outlayer_method": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "axis_minor_tick": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "axis_tick_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "ppm_max_longitude": {
+            "default": "180", 
+            "from": "float"
+        }, 
+        "obs_pressure_tendency": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_tick_label_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "obs_present_weather_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "title_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "landgram_bottom_box2_shading": {
+            "default": "dot", 
+            "from": "string"
+        }, 
+        "histogram_max_value": {
+            "default": "1.e21", 
+            "from": "float"
+        }, 
+        "input_longitude_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "boxplot_minimum_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "boxplot_box_border": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_date_positions": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "table_variable_identifier_type": {
+            "default": "index", 
+            "from": "string"
+        }, 
+        "graph_x_suppress_below": {
+            "default": "LLONG_MIN", 
+            "from": "float"
+        }, 
+        "axis_tick_label_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "symbol_advanced_table_marker_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "graph_line_style_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "symbol_advanced_table_max_value": {
+            "default": "1.e21", 
+            "from": "float"
+        }, 
+        "graph_bar_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "input_date_x2_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "input_x_component_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "sql_latitude": {
+            "default": "latitude", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_height_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "obs_upper_air_pressure_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "axis_minor_tick_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "obs_pressure_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "input_mars_metadata": {
+            "default": "{}", 
+            "from": "string"
+        }, 
+        "x_base_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "obs_medium_cloud": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "obs_high_cloud_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "boxplot_box_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "output_name_first_page_number": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "boxplot_box_lower_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "table_x_variable": {
+            "default": "1", 
+            "from": "string"
+        }, 
+        "input_field_final_x": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "symbol_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "axis_tick_label_first": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_tick_interval": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_selection_type": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "landgram_top_box1_shading": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "y_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "output_jpeg_quality": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "root_node_format": {
+            "default": "a4", 
+            "from": "string"
+        }, 
+        "magnifier_symbol_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "title_justification": {
+            "default": "centre", 
+            "from": "string"
+        }, 
+        "boxplot_whisker_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "magnifier_hidden_symbol_height": {
+            "default": "0.1", 
+            "from": "float"
+        }, 
+        "obs_thickness_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "obs_pressure": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "graph_missing_data_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "symbol_marker_index": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "root_node_frame_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "obs_height": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_grid": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "axis_hours_label": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "graph_bar_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "symbol_marker_name": {
+            "default": "dot", 
+            "from": "string"
+        }, 
+        "legend_user_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "graph_bar_orientation": {
+            "default": "vertical", 
+            "from": "string"
+        }, 
+        "root_node_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "output_filelist": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "page_id_line_colour": {
+            "default": "ecmwf_blue", 
+            "from": "string"
+        }, 
+        "axis_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "width": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "wrep_node_width": {
+            "default": "800", 
+            "from": "float"
+        }, 
+        "contour_sample_x_interval": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "input_x_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "symbol_image_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "image_level_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "axis_tip_title_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "root_node_frame": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "graph_thickness_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "user_logo_position_units": {
+            "default": "cm", 
+            "from": "string"
+        }, 
+        "input_binning": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_outlayer_max_value": {
+            "default": "1.e21", 
+            "from": "float"
+        }, 
+        "mgb_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_hours_label_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "axis_days_label_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "graph_bar_minimum_value": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "sql_x": {
+            "default": "x", 
+            "from": "string"
+        }, 
+        "sql_y": {
+            "default": "y", 
+            "from": "string"
+        }, 
+        "table_y_variable": {
+            "default": "2", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_colour_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }, 
+        "input_wind_speed": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "axis_tip_title_height": {
+            "default": "0.4", 
+            "from": "float"
+        }, 
+        "input_field_organization": {
+            "default": "regular", 
+            "from": "string"
+        }, 
+        "axis_months_label_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "user_logo_x_position": {
+            "default": "80", 
+            "from": "float"
+        }, 
+        "user_logo_format": {
+            "default": "PNG", 
+            "from": "string"
+        }, 
+        "input_latitude_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "y_lower_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "obs_demo2_missing_text": {
+            "default": "///", 
+            "from": "string"
+        }, 
+        "world_file_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrep_node_mapping_anchor": {
+            "default": "centre", 
+            "from": "string"
+        }, 
+        "axis_grid_reference_level": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "output_file_separator": {
+            "default": ".", 
+            "from": "string"
+        }, 
+        "graph_shade_dot_size": {
+            "default": "0.02", 
+            "from": "float"
+        }, 
+        "axis_title_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "landgram_width": {
+            "default": "6", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_text_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "magnifier_symbol_name": {
+            "default": "magics_3", 
+            "from": "string"
+        }, 
+        "axis_date_type": {
+            "default": "days", 
+            "from": "string"
+        }, 
+        "obs_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_days_label": {
+            "default": "both", 
+            "from": "string"
+        }, 
+        "obs_template_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_text_display_type": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "boxplot_box_border_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "obs_temperature": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "table_y_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "table_x_component_variable": {
+            "default": "-1", 
+            "from": "string"
+        }, 
+        "input_field_latitude_step": {
+            "default": "-1.5", 
+            "from": "float"
+        }, 
+        "histogram_reference_level": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "axis_years_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "obs_dewpoint_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "axis_hours_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "sql_level": {
+            "default": "press", 
+            "from": "string"
+        }, 
+        "input_field_initial_latitude": {
+            "default": "90", 
+            "from": "float"
+        }, 
+        "x2_date_values": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "symbol_text_font_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "axis_months_label_height": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "table_meta_data_rows": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "symbol_advanced_table_interval": {
+            "default": "8.0", 
+            "from": "float"
+        }, 
+        "title_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "obs_cloud": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "graph_arrow_unit_velocity": {
+            "default": "25.0", 
+            "from": "float"
+        }, 
+        "y2_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "landgram_bottom_box2_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "magnifier_text_font_size": {
+            "default": "0.2", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_colour_method": {
+            "default": "calculate", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_height_min_value": {
+            "default": "0.1", 
+            "from": "float"
+        }, 
+        "output_legacy_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "boxplot_whisker_box_border_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "landgram_input_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "root_node_application": {
+            "default": "magml", 
+            "from": "string"
+        }, 
+        "graph_line": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_advanced_table_reference_level": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_marker_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "input_wind_u_component": {
+            "default": "Matrix()", 
+            "from": "Matrix"
+        }, 
+        "obs_pressure_tendency_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "table_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "axis_orientation": {
+            "default": "horizontal", 
+            "from": "string"
+        }, 
+        "graph_symbol_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "ppm_min_longitude": {
+            "default": "-180", 
+            "from": "float"
+        }, 
+        "ppm_max_latitude": {
+            "default": "90", 
+            "from": "float"
+        }, 
+        "axis_title_height": {
+            "default": "0.4", 
+            "from": "float"
+        }, 
+        "symbol_advanced_table_level_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "landgram_top_box2_shading": {
+            "default": "dot", 
+            "from": "string"
+        }, 
+        "obs_identification_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "title_text": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "graph_y_suppress_below": {
+            "default": "LLONG_MIN", 
+            "from": "float"
+        }, 
+        "obs_identification": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "magnifier_hidden_symbol_name": {
+            "default": "magics_3", 
+            "from": "string"
+        }, 
+        "obs_waves": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "axis_title_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "graph_colour_variable_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "landgram_top_box1_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "title_template_filename": {
+            "default": "title_template.xml", 
+            "from": "string"
+        }, 
+        "symbol_text_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "obs_wind_projected": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "user_logo_y_position": {
+            "default": "2.5", 
+            "from": "float"
+        }, 
+        "mgb_width": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "graph_symbol_outline_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "axis_tick_label_position": {
+            "default": "on_tick", 
+            "from": "string"
+        }, 
+        "table_binning": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "x2_values": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "bottom": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "axis_days_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "image_index_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "root_node_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "output_mgb_template": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "graph_shade_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "axis_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "mgb_x": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "mgb_y": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "histogram_level_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "histogram_bar_width": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "input_simple_field": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "graph_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "mgb_blur_radius": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "user_logo_bottom": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "table_delimiter": {
+            "default": ",", 
+            "from": "string"
+        }
+    }, 
+    "pnew": {
+        "subpage_right_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_vertical_axis_width": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "subpage_y_min_latitude": {
+            "default": "-90", 
+            "from": "float"
+        }, 
+        "subpage_map_overlay_control": {
+            "default": "basic", 
+            "from": "string"
+        }, 
+        "subpage_horizontal_axis_height": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "subpage_y_date_max": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "subpage_map_magnifier": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_map_preview": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "super_page_frame_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "subpage_x_max": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "page_id_line": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "plot_direction": {
+            "default": "vertical", 
+            "from": "string"
+        }, 
+        "page_theme": {
+            "default": "super_page_theme", 
+            "from": "string"
+        }, 
+        "page_frame": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_frame_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "super_page_frame_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "super_page_theme": {
+            "default": "xxmagics", 
+            "from": "string"
+        }, 
+        "subpage_map_library_area": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "page_frame_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "layout": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "subpage_y_min": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "subpage_x_length": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_x_min_latitude": {
+            "default": "-90", 
+            "from": "float"
+        }, 
+        "subpage_x_axis_type": {
+            "default": "regular", 
+            "from": "string"
+        }, 
+        "subpage_y_date_min": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "page_y_length": {
+            "default": "21", 
+            "from": "float"
+        }, 
+        "subpage_background_colour": {
+            "default": "white", 
+            "from": "string"
+        }, 
+        "plot_start": {
+            "default": "bottom", 
+            "from": "string"
+        }, 
+        "subpage_y_min_longitude": {
+            "default": "-180", 
+            "from": "float"
+        }, 
+        "subpage_frame_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "subpage_x_min": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "subpage_map_area_name": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_x_min_longitude": {
+            "default": "-180", 
+            "from": "float"
+        }, 
+        "subpage_x_position_internal": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_y_max_latitude": {
+            "default": "90", 
+            "from": "float"
+        }, 
+        "subpage_frame": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "subpage_align_vertical": {
+            "default": "bottom", 
+            "from": "string"
+        }, 
+        "subpage_y_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "page_frame_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "subpage_x_date_min": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "subpage_map_projection": {
+            "default": "cylindrical", 
+            "from": "string"
+        }, 
+        "page_y_position": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "subpage_x_automatic_reverse": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_top_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_y_max": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "subpage_y_position_internal": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "super_page_y_length": {
+            "default": "21.0", 
+            "from": "float"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "super_page_frame_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "subpage_x_max_latitude": {
+            "default": "90", 
+            "from": "float"
+        }, 
+        "subpage_clipping": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "page_x_position": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "page_x_length": {
+            "default": "29.7", 
+            "from": "float"
+        }, 
+        "super_page_frame": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_map_json_definition": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "subpage_y_automatic": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "super_page_x_length": {
+            "default": "29.7", 
+            "from": "float"
+        }, 
+        "automatic_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_y_max_longitude": {
+            "default": "180", 
+            "from": "float"
+        }, 
+        "subpage_y_length_internal": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_x_date_max": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "subpage_align_horizontal": {
+            "default": "left", 
+            "from": "string"
+        }, 
+        "subpage_y_automatic_reverse": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_x_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_frame_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "subpage_x_automatic": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "subpage_y_length": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "subpage_y_axis_type": {
+            "default": "regular", 
+            "from": "string"
+        }, 
+        "subpage_x_max_longitude": {
+            "default": "180", 
+            "from": "float"
+        }, 
+        "subpage_x_length_internal": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "page_frame_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }
+    }, 
+    "ptext": {
+        "text_automatic": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "text_font_size": {
+            "default": "0.5", 
+            "from": "string"
+        }, 
+        "text_box_x_length": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "text_border_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "text_integer_4": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_box_blanking": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "text_character_10": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_height_ratio_6": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_box_y_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "text_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "text_mode": {
+            "default": "title", 
+            "from": "string"
+        }, 
+        "text_real_10": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_parameter_escape_character": {
+            "default": "@", 
+            "from": "string"
+        }, 
+        "text_orientation": {
+            "default": "horizontal", 
+            "from": "string"
+        }, 
+        "text_border": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "text_line_8": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_height_ratios": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "text_integer_10": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_character_8": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_character_9": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "text_line_count": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "text_real_3": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_line_4": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_5": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_character_2": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_box_x_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "text_character_4": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_character_5": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_2": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_3": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_real_8": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_box_y_length": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "text_real_1": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_real_2": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_line_9": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_lines": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "text_real_6": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_real_7": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_real_4": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_real_5": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_real_9": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "text_character_1": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_integer_7": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_border_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "text_line_6": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_font": {
+            "default": "helvetica", 
+            "from": "string"
+        }, 
+        "text_first_line": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "text_line_height_ratio_9": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_height_ratio_8": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_character_3": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_justification": {
+            "default": "centre", 
+            "from": "string"
+        }, 
+        "text_line_height_ratio_1": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "text_line_height_ratio_3": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_height_ratio_2": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_height_ratio_5": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_height_ratio_4": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_height_ratio_7": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_line_1": {
+            "default": "<magics_title/>", 
+            "from": "string"
+        }, 
+        "text_integer_9": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_integer_8": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_character_6": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_html": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "text_integer_6": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_integer_1": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_line_height_ratio_10": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "text_integer_3": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_character_7": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_integer_5": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "text_line_7": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_line_10": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "text_integer_2": {
+            "default": "0", 
+            "from": "int"
+        }
+    }, 
+    "pobsstat": {
+        "obsstat_filename": {
+            "default": "", 
+            "from": "string"
+        }
+    }, 
+    "peps": {
+        "eps_date": {
+            "default": "-1", 
+            "from": "string"
+        }, 
+        "eps_parameter_title": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_long_title_station": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_font_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "eps_box_shift": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "eps_maximum_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "eps_rose_wind_colour": {
+            "default": "grey", 
+            "from": "string"
+        }, 
+        "eps_rose_wind_border_colour": {
+            "default": "grey", 
+            "from": "string"
+        }, 
+        "eps_rose_cloud_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "eps_maximum_font_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "eps_y_axis_threshold": {
+            "default": "50", 
+            "from": "float"
+        }, 
+        "eps_rose_wave_colour": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "eps_title": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "eps_maximum_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "eps_deterministic_legend_text": {
+            "default": "High Resolution", 
+            "from": "string"
+        }, 
+        "eps_control_line_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "eps_whisker": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_rose_cloud_border_colour": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "eps_rose_wind_convention": {
+            "default": "meteorological", 
+            "from": "string"
+        }, 
+        "eps_grey_legend": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_station_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_deterministic_line_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "eps_deterministic_line_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "eps_long_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "eps_station_height": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "eps_deterministic_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "eps_right_box_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "eps_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_legend_resolution": {
+            "default": "truncature", 
+            "from": "string"
+        }, 
+        "eps_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_box_quantiles_colour": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "eps_deterministic": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_latitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "eps_box_border_thickness": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "eps_temperature_correction": {
+            "default": "yes", 
+            "from": "string"
+        }, 
+        "eps_database": {
+            "default": "/vol/epsgram/data/spotbase/epsdb", 
+            "from": "string"
+        }, 
+        "eps_long_title_point": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_type": {
+            "default": "eps10", 
+            "from": "string"
+        }, 
+        "eps_box_median_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "eps_box_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "eps_legend_control_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_box_median_thickness": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "eps_maximum": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "eps_long_title_height": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_left_box_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "eps_control_legend_text": {
+            "default": "ENS Control", 
+            "from": "string"
+        }, 
+        "eps_font_style": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_control_line_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "legend": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "eps_maximum_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "eps_legend_forecast_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "eps_parameter_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "eps_control_line_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "eps_box_colour": {
+            "default": "cyan", 
+            "from": "string"
+        }, 
+        "eps_title_text": {
+            "default": "EPS Meteogram", 
+            "from": "string"
+        }, 
+        "eps_y_axis_percentile": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "eps_parameter_offset_factor": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_time": {
+            "default": "0000", 
+            "from": "string"
+        }, 
+        "eps_font_size": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "eps_legend_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "eps_box_border_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "eps_parameter_hour_shift": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "eps_control": {
+            "default": "on", 
+            "from": "string"
+        }
+    }, 
+    "Interactive": {
+        "selection_mode_background_opacity": {
+            "default": "75", 
+            "from": "int"
+        }, 
+        "selection_mode_background_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "selection_mode_object_instancies": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "selection_mode_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "selection_mode_line_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "selection_mode_line_thickness": {
+            "default": "2", 
+            "from": "int"
+        }
+    }, 
+    "KML": {
+        "kml_longitude": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "kml_description": {
+            "default": "Generated by Magics++", 
+            "from": "string"
+        }, 
+        "kml_tilt": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "kml_latitude": {
+            "default": "40.0", 
+            "from": "float"
+        }, 
+        "kml_height": {
+            "default": "5.0", 
+            "from": "float"
+        }, 
+        "kml_transparency": {
+            "default": "100", 
+            "from": "int"
+        }, 
+        "kml_kmz": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "kml_author": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "kml_coastlines": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "kml_link": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "kml_range": {
+            "default": "6000", 
+            "from": "int"
+        }
+    }, 
+    "Qt": {}, 
+    "SVG": {
+        "output_svg_fix_size": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "output_svg_meta": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "output_svg_desc": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "output_svg_logo_location": {
+            "default": "inline", 
+            "from": "string"
+        }, 
+        "output_svg_use_external_files": {
+            "default": "off", 
+            "from": "string"
+        }
+    }, 
+    "pplot": {
+        "crs": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "import_height": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "import_x_position": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "import_format": {
+            "default": "PNG", 
+            "from": "string"
+        }, 
+        "crs_miny": {
+            "default": "-90.", 
+            "from": "float"
+        }, 
+        "crs_minx": {
+            "default": "-180.", 
+            "from": "float"
+        }, 
+        "crs_maxy": {
+            "default": "-90.", 
+            "from": "float"
+        }, 
+        "crs_maxx": {
+            "default": "180.", 
+            "from": "float"
+        }, 
+        "import_system_coordinates": {
+            "default": "user", 
+            "from": "string"
+        }, 
+        "import_width": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "import_y_position": {
+            "default": "0", 
+            "from": "float"
+        }
+    }, 
+    "pgeojson": {
+        "geojson_binning_grid_resolution": {
+            "default": "1.", 
+            "from": "float"
+        }, 
+        "geojson_input_type": {
+            "default": "file", 
+            "from": "string"
+        }, 
+        "geojson_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "geojson_input": {
+            "default": "{}", 
+            "from": "string"
+        }
+    }, 
+    "ptaylor": {
+        "taylor_standard_deviation_max": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "taylor_standard_deviation_min": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "taylor_reference_line_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "taylor_primary_label_height": {
+            "default": "0.35", 
+            "from": "float"
+        }, 
+        "taylor_secondary_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "taylor_reference_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "taylor_label": {
+            "default": "Correlation", 
+            "from": "string"
+        }, 
+        "taylor_primary_grid_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "taylor_primary_grid_increment": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "taylor_secondary_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "taylor_primary_grid_reference": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "taylor_secondary_grid_line_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_secondary_label_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_label_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_secondary_label_height": {
+            "default": "0.35", 
+            "from": "float"
+        }, 
+        "taylor_label_height": {
+            "default": "0.35", 
+            "from": "float"
+        }, 
+        "taylor_primary_label_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_secondary_grid": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "taylor_primary_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "taylor_primary_grid_line_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_secondary_grid_reference": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "taylor_primary_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "taylor_reference_line_colour": {
+            "default": "navy", 
+            "from": "string"
+        }, 
+        "taylor_secondary_grid_increment": {
+            "default": "0.5", 
+            "from": "float"
+        }, 
+        "taylor_secondary_grid_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }
+    }, 
+    "popen": {
+        "output_formats": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "output_format": {
+            "default": "ps", 
+            "from": "string"
+        }
+    }, 
+    "ptephi": {
+        "thermo_mixing_ratio_label_colour": {
+            "default": "purple", 
+            "from": "string"
+        }, 
+        "y_max": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "thermo_saturated_adiabatic_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "x_max": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "thermo_dry_adiabatic_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "thermo_mixing_ratio_colour": {
+            "default": "purple", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_dry_adiabatic_interval": {
+            "default": "10", 
+            "from": "float"
+        }, 
+        "thermo_saturated_adiabatic_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "thermo_isobar_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "thermo_mixing_ratio_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "thermo_saturated_adiabatic_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "thermo_isobar_label_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "thermo_isobar_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_reference_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "thermo_saturated_adiabatic_label_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "y_min": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "thermo_annotation_width": {
+            "default": "25", 
+            "from": "float"
+        }, 
+        "thermo_isobar_interval": {
+            "default": "100", 
+            "from": "float"
+        }, 
+        "thermo_isobar_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_isotherm_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "thermo_mixing_ratio_label_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "thermo_saturated_adiabatic_label_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "thermo_isobar_label_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "thermo_isobar_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "thermo_dry_adiabatic_label_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "thermo_saturated_adiabatic_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "thermo_saturated_adiabatic_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "thermo_isobar_colour": {
+            "default": "evergreen", 
+            "from": "string"
+        }, 
+        "thermo_saturated_adiabatic_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "x_min": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "thermo_saturated_adiabatic_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_mixing_ratio_style": {
+            "default": "dash", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_isotherm_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "thermo_isotherm_interval": {
+            "default": "10", 
+            "from": "float"
+        }, 
+        "thermo_mixing_ratio_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_isobar_label_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "thermo_isotherm_reference_thickness": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "thermo_saturated_adiabatic_interval": {
+            "default": "5", 
+            "from": "float"
+        }, 
+        "thermo_isotherm_label_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_isotherm_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_isobar_grid": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_label_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "thermo_mixing_ratio_label_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "thermo_isobar_reference": {
+            "default": "1000", 
+            "from": "float"
+        }, 
+        "thermo_isotherm_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "subpage_y_automatic": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_label_colour": {
+            "default": "charcoal", 
+            "from": "string"
+        }, 
+        "thermo_mixing_ratio_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "thermo_mixing_ratio_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_label_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "thermo_isotherm_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "thermo_mixing_ratio_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "subpage_x_automatic": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "thermo_dry_adiabatic_label_font_size": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "thermo_saturated_adiabatic_label_font": {
+            "default": "sanserif", 
+            "from": "string"
+        }, 
+        "thermo_isotherm_reference_style": {
+            "default": "solid", 
+            "from": "string"
+        }
+    }, 
+    "pcont": {
+        "contour_legend_only": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_shade_min_level_density": {
+            "default": "1.0", 
+            "from": "float"
+        }, 
+        "contour_shade_method": {
+            "default": "dot", 
+            "from": "string"
+        }, 
+        "contour_label_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "contour_reference_level": {
+            "default": "0.0", 
+            "from": "float"
+        }, 
+        "contour_grid_value_max": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_label_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "contour_interpolation_ceiling": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "contour_line_colour_rainbow": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_shade_hatch_density": {
+            "default": "18.0", 
+            "from": "float"
+        }, 
+        "contour_internal_reduction_factor": {
+            "default": "4", 
+            "from": "float"
+        }, 
+        "contour_shade_marker_table_type": {
+            "default": "index", 
+            "from": "string"
+        }, 
+        "contour_grid_value_marker_index": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "contour_max_level": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_shade_technique": {
+            "default": "polygon_shading", 
+            "from": "string"
+        }, 
+        "contour_hilo": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_special_legend": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "contour_interval": {
+            "default": "8.0", 
+            "from": "float"
+        }, 
+        "contour_gradients_waypoint_method": {
+            "default": "both", 
+            "from": "string"
+        }, 
+        "contour_akima_x_resolution": {
+            "default": "1.5", 
+            "from": "float"
+        }, 
+        "contour_legend_text": {
+            "default": " ", 
+            "from": "string"
+        }, 
+        "contour_line_colour_rainbow_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_shade": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_grid_value_plot_type": {
+            "default": "value", 
+            "from": "string"
+        }, 
+        "contour_akima_y_resolution": {
+            "default": "1.5", 
+            "from": "float"
+        }, 
+        "contour_automatic_setting": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_gradients_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_hilo_max_value": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_highlight_thickness": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "contour_line_style_rainbow_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "contour_shade_hatch_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "contour_highlight": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "contour_grid_value_min": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_line_thickness_rainbow_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "contour_grid_value_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_gradients_technique": {
+            "default": "linear", 
+            "from": "string"
+        }, 
+        "contour_hilo_window_size": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_grid_value_plot": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_line_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_hilo_height": {
+            "default": "0.4", 
+            "from": "float"
+        }, 
+        "contour_shade_cell_resolution": {
+            "default": "10", 
+            "from": "float"
+        }, 
+        "contour_shade_marker_table": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "image_colour_table": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_hilo_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "contour_shade_colour_table": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_internal_technique": {
+            "default": "interpolate", 
+            "from": "string"
+        }, 
+        "contour_shade_cell_resolution_method": {
+            "default": "classic", 
+            "from": "string"
+        }, 
+        "contour_label_height": {
+            "default": "0.3", 
+            "from": "float"
+        }, 
+        "contour_hi_text": {
+            "default": "H", 
+            "from": "string"
+        }, 
+        "contour_gradients_technique_direction": {
+            "default": "clockwise", 
+            "from": "string"
+        }, 
+        "contour_hilo_blanking": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_hi_max_value": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_grid_value_marker_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "contour_line_style_rainbow_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_line_thickness_rainbow_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "contour_lo_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_hilo_type": {
+            "default": "text", 
+            "from": "string"
+        }, 
+        "contour_shade_max_level_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_level_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "contour_hilo_marker": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "contour_label_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "contour_grid_value_quality": {
+            "default": "low", 
+            "from": "string"
+        }, 
+        "contour_grid_shading_position": {
+            "default": "middle", 
+            "from": "string"
+        }, 
+        "contour_shade_colour_method": {
+            "default": "calculate", 
+            "from": "string"
+        }, 
+        "contour_shade_max_level": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_level_tolerance": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "contour_hilo_marker_index": {
+            "default": "3", 
+            "from": "int"
+        }, 
+        "contour_label_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "contour_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "contour_gradients_value_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "contour_line_colour_rainbow_method": {
+            "default": "calculate", 
+            "from": "string"
+        }, 
+        "contour_label_colour": {
+            "default": "contour_line_colour", 
+            "from": "string"
+        }, 
+        "contour_grid_value_lat_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "contour_lo_max_value": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_hilo_marker_height": {
+            "default": "0.1", 
+            "from": "float"
+        }, 
+        "contour": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "contour_shade_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_level_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "contour_shade_colour_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }, 
+        "contour_label_frequency": {
+            "default": "2", 
+            "from": "int"
+        }, 
+        "contour_shade_dot_size": {
+            "default": "0.02", 
+            "from": "float"
+        }, 
+        "contour_hi_min_value": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_grid_value_marker_qual": {
+            "default": "low", 
+            "from": "string"
+        }, 
+        "contour_hilo_min_value": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_interpolation_floor": {
+            "default": "-INT_MAX", 
+            "from": "float"
+        }, 
+        "contour_method": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "contour_shade_hatch_index": {
+            "default": "0", 
+            "from": "int"
+        }, 
+        "contour_gradients_technique_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_grid_value_lon_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "contour_highlight_frequency": {
+            "default": "4", 
+            "from": "int"
+        }, 
+        "contour_shade_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "contour_shade_min_level": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_grid_value_height": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "contour_grid_value_type": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "contour_line_colour_rainbow_colour_list_policy": {
+            "default": "lastone", 
+            "from": "string"
+        }, 
+        "contour_line_colour_rainbow_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_shade_height_table": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "contour_highlight_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "contour_line_colour_rainbow_min_level_colour": {
+            "default": "red", 
+            "from": "string"
+        }, 
+        "contour_line_colour_rainbow_direction": {
+            "default": "anti_clockwise", 
+            "from": "string"
+        }, 
+        "contour_grid_value_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "contour_label": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "contour_min_level": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_gradients_step_list": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "contour_lo_min_value": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "contour_highlight_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_gradients_waypoint_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "contour_shade_marker_name_table": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "contour_level_selection_type": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "contour_lo_text": {
+            "default": "L", 
+            "from": "string"
+        }, 
+        "contour_grid_value_marker_height": {
+            "default": "0.25", 
+            "from": "float"
+        }, 
+        "contour_label_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "contour_shade_max_level_density": {
+            "default": "50.0", 
+            "from": "float"
+        }, 
+        "contour_hilo_quality": {
+            "default": "low", 
+            "from": "string"
+        }, 
+        "contour_hi_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "contour_shade_cell_method": {
+            "default": "nearest", 
+            "from": "string"
+        }, 
+        "contour_label_blanking": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "contour_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "contour_automatic_library_path": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "contour_hilo_marker_colour": {
+            "default": "red", 
+            "from": "string"
+        }
+    }, 
+    "legend": {
+        "legend_user_maximum": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_user_text_8": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_user_text_9": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_user_text_4": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_user_text_5": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_user_text_6": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_histogram_grid_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "legend_user_minimum": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_text_quality": {
+            "default": "medium", 
+            "from": "string"
+        }, 
+        "legend_column_count": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "legend_text_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "legend_entry_border": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "legend_text_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "legend_histogram_mean_value": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_user_maximum_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_entry_plot_direction": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "legend_user_minimum_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_values_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "legend_box_y_length": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "legend_wrep": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_title_font_size": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "legend_text_composition": {
+            "default": "automatic_text_only", 
+            "from": "string"
+        }, 
+        "legend_only": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_title_font_colour": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "legend_histogram_border_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "legend_border_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "legend_automatic_position": {
+            "default": "top", 
+            "from": "string"
+        }, 
+        "legend_box_mode": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "legend_text_font_size": {
+            "default": "0.3", 
+            "from": "string"
+        }, 
+        "legend_title_orientation": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "legend_user_text_10": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_title_position": {
+            "default": "automatic", 
+            "from": "string"
+        }, 
+        "legend_user_text_7": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_display_type": {
+            "default": "disjoint", 
+            "from": "string"
+        }, 
+        "legend_label_frequency": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "legend_units_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_box_y_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "legend_border_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "legend_user_text_1": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_entry_border_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "legend_box_x_position": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "legend_user_text_2": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "legend_box_blanking": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_histogram_grid_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "legend_histogram_max_value": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "legend_histogram_grid_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "legend_histogram_mean_value_marker": {
+            "default": "15", 
+            "from": "int"
+        }, 
+        "legend_histogram_border": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "legend_text_orientation": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "legend_entry_plot_orientation": {
+            "default": "bottom_top", 
+            "from": "string"
+        }, 
+        "legend_symbol_height_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "legend_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_text_font": {
+            "default": "sansserif", 
+            "from": "string"
+        }, 
+        "legend_histogram_mean_value_marker_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "legend_box_x_length": {
+            "default": "-1", 
+            "from": "float"
+        }, 
+        "legend_border": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend_user_lines": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "legend_user_text": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_title_position_ratio": {
+            "default": "25", 
+            "from": "float"
+        }, 
+        "legend_entry_text_width": {
+            "default": "60", 
+            "from": "float"
+        }, 
+        "legend_user_text_3": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "legend_text_font_style": {
+            "default": "normal", 
+            "from": "string"
+        }, 
+        "legend_histogram_mean_value_marker_size": {
+            "default": "0.4", 
+            "from": "float"
+        }, 
+        "legend_title_text": {
+            "default": "legend", 
+            "from": "string"
+        }
+    }, 
+    "pwrepjson": {
+        "wrepjson_steps": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "wrepjson_family": {
+            "default": "eps", 
+            "from": "string"
+        }, 
+        "wrepjson_clim_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_keyword": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_y_axis_percentile": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "wrepjson_key": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_product_information": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_temperature_correction": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "wrepjson_clim_step": {
+            "default": "36", 
+            "from": "int"
+        }, 
+        "wrepjson_y_max_threshold": {
+            "default": "INT_MAX", 
+            "from": "float"
+        }, 
+        "wrepjson_parameter_offset_factor": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "wrepjson_plumes_interval": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "wrepjson_position_information": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "wrepjson_y_percentage": {
+            "default": "0.01", 
+            "from": "float"
+        }, 
+        "wrepjson_title": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "wrepjson_ignore_keys": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "wrepjson_input_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_parameter_scaling_factor": {
+            "default": "1", 
+            "from": "float"
+        }, 
+        "wrepjson_parameter": {
+            "default": "1", 
+            "from": "string"
+        }, 
+        "wrepjson_missing_value": {
+            "default": "-9999", 
+            "from": "float"
+        }, 
+        "wrepjson_y_axis_threshold": {
+            "default": "50", 
+            "from": "float"
+        }, 
+        "wrepjson_station_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_parameter_information": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "wrepjson_information": {
+            "default": "on", 
+            "from": "string"
+        }
+    }, 
+    "pshape": {
+        "shape_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }
+    }, 
+    "pbinning": {
+        "binning_y_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "binning_y_min_value": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "binning_y_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "binning_y_method": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "binning_x_min_value": {
+            "default": "-1.0e+21", 
+            "from": "float"
+        }, 
+        "binning_x_interval": {
+            "default": "10", 
+            "from": "float"
+        }, 
+        "binning_x_count": {
+            "default": "10", 
+            "from": "int"
+        }, 
+        "binning_x_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "binning_y_max_value": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "binning_x_method": {
+            "default": "count", 
+            "from": "string"
+        }, 
+        "binning_x_max_value": {
+            "default": "1.0e+21", 
+            "from": "float"
+        }, 
+        "binning_x_list": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "binning_y_reference": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "binning_y_interval": {
+            "default": "10", 
+            "from": "float"
+        }
+    }, 
+    "Cairo": {
+        "output_geotiff_quality": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "output_cairo_drawing_context": {
+            "default": "0", 
+            "from": "cairo_t*"
+        }, 
+        "output_cairo_transparent_background": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "output_cairo_palette": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "output_cairo_antialias": {
+            "default": "on", 
+            "from": "string"
+        }
+    }, 
+    "pgeo": {
+        "geo_input_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "geo_missing_value": {
+            "default": "3.0E+38", 
+            "from": "float"
+        }
+    }, 
+    "podb": {
+        "odb_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_x": {
+            "default": "press", 
+            "from": "string"
+        }, 
+        "odb_y_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_coordinates_unit": {
+            "default": "degrees", 
+            "from": "string"
+        }, 
+        "odb_database": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_binning": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "odb_query": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_level": {
+            "default": "press", 
+            "from": "string"
+        }, 
+        "odb_database_option": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_time": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_latitude": {
+            "default": "latitude", 
+            "from": "string"
+        }, 
+        "odb_value_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_longitude": {
+            "default": "longitude", 
+            "from": "string"
+        }, 
+        "odb_nb_rows": {
+            "default": "-1", 
+            "from": "int"
+        }, 
+        "odb_y": {
+            "default": "press", 
+            "from": "string"
+        }, 
+        "odb_y_variable": {
+            "default": "lon", 
+            "from": "string"
+        }, 
+        "odb_starting_row": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "odb_parameters": {
+            "default": "floatarray()", 
+            "from": "floatarray"
+        }, 
+        "odb_observation_2": {
+            "default": "obsvalue", 
+            "from": "string"
+        }, 
+        "odb_longitude_variable": {
+            "default": "lon", 
+            "from": "string"
+        }, 
+        "odb_observation": {
+            "default": "obsvalue", 
+            "from": "string"
+        }, 
+        "odb_filename": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_x_component_variable": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_user_title": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "odb_latitude_variable": {
+            "default": "lat", 
+            "from": "string"
+        }, 
+        "odb_x_variable": {
+            "default": "lat", 
+            "from": "string"
+        }
+    }, 
+    "Ming": {}, 
+    "psymb": {
+        "symbol_outline_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "symbol_connect_automatic_line_colour": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "symbol_table_mode": {
+            "default": "OFF", 
+            "from": "string"
+        }, 
+        "symbol_outline": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "symbol_connect_line": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "symbol_legend_only": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "symbol_connect_line_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "symbol_format": {
+            "default": "(automatic)", 
+            "from": "string"
+        }, 
+        "symbol_connect_line_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "symbol_outline_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "symbol_scaling_factor": {
+            "default": "4.", 
+            "from": "float"
+        }, 
+        "symbol_connect_line_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "symbol_scaling_method": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "symbol_outline_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "symbol_scaling_level_0_height": {
+            "default": "0.1", 
+            "from": "float"
+        }, 
+        "symbol_type": {
+            "default": "number", 
+            "from": "string"
+        }, 
+        "symbol_text_blanking": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "legend": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "symbol_marker_mode": {
+            "default": "index", 
+            "from": "string"
+        }
+    }, 
+    "pefigram": {
+        "efi_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "efi_clim_root_database": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_steps": {
+            "default": "intarray()", 
+            "from": "intarray"
+        }, 
+        "efi_long_title": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "efi_legend_root_database": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_longitude": {
+            "default": "0", 
+            "from": "float"
+        }, 
+        "efi_clim_step": {
+            "default": "36", 
+            "from": "int"
+        }, 
+        "efi_legend_box_type": {
+            "default": "both", 
+            "from": "string"
+        }, 
+        "efi_clim_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_dates": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "efi_root_database": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_legend_normal_colour": {
+            "default": "black", 
+            "from": "string"
+        }, 
+        "efi_clim_date": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_legend": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "efi_parameter": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "efi_legend_normal_thickness": {
+            "default": "4", 
+            "from": "int"
+        }, 
+        "efi_legend_colour_list": {
+            "default": "stringarray()", 
+            "from": "stringarray"
+        }, 
+        "efi_latitude": {
+            "default": "0", 
+            "from": "float"
+        }
+    }, 
+    "MagML": {
+        "scene_node_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "scene_node_border_bottom": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_padding_colour": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "scene_node_border_right": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_standalone_height": {
+            "default": "64", 
+            "from": "float"
+        }, 
+        "scene_node_width": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "view_width": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "scene_node_padding_colour": {
+            "default": "none", 
+            "from": "string"
+        }, 
+        "scene_node_bottom": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_padding_bottom": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_border_top": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_border_bottom": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_blanking": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "view_padding_bottom": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_margin_right": {
+            "default": "undef", 
+            "from": "string"
+        }, 
+        "view_border_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "view_display": {
+            "default": "inline", 
+            "from": "string"
+        }, 
+        "view_border_colour": {
+            "default": "tan", 
+            "from": "string"
+        }, 
+        "view_margin_bottom": {
+            "default": "undef", 
+            "from": "string"
+        }, 
+        "scene_node_border_left": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_standalone": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "view_standalone_format": {
+            "default": "png", 
+            "from": "string"
+        }, 
+        "view_margin_top": {
+            "default": "undef", 
+            "from": "string"
+        }, 
+        "view_bottom": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_border_colour": {
+            "default": "blue", 
+            "from": "string"
+        }, 
+        "view_fitted_mode": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "scene_node_border": {
+            "default": "off", 
+            "from": "string"
+        }, 
+        "view_padding_top": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_height": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "scene_node_border_top": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "scene_node_padding_top": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_margin_top": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_background_colour": {
+            "default": "white", 
+            "from": "string"
+        }, 
+        "view_left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_background_colour": {
+            "default": "white", 
+            "from": "string"
+        }, 
+        "view_standalone_width": {
+            "default": "128", 
+            "from": "float"
+        }, 
+        "scene_node_id_line": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "view_border": {
+            "default": "on", 
+            "from": "string"
+        }, 
+        "scene_node_margin_left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "subpage_map_projection": {
+            "default": "cylindrical", 
+            "from": "string"
+        }, 
+        "scene_node_padding_right": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_margin_right": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_margin_left": {
+            "default": "undef", 
+            "from": "string"
+        }, 
+        "view_border_right": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "scene_node_left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_border_style": {
+            "default": "solid", 
+            "from": "string"
+        }, 
+        "view_border_left": {
+            "default": "1px", 
+            "from": "string"
+        }, 
+        "view_padding_right": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_standalone_file_name": {
+            "default": "", 
+            "from": "string"
+        }, 
+        "scene_node_height": {
+            "default": "100%", 
+            "from": "string"
+        }, 
+        "view_padding_left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "scene_node_padding_left": {
+            "default": "0%", 
+            "from": "string"
+        }, 
+        "view_border_thickness": {
+            "default": "1", 
+            "from": "int"
+        }, 
+        "scene_node_margin_bottom": {
+            "default": "0%", 
+            "from": "string"
+        }
+    }
+}
diff --git a/tools/docs.template b/tools/docs.template
new file mode 100644
index 0000000..6cfc37b
--- /dev/null
+++ b/tools/docs.template
@@ -0,0 +1,161 @@
+
+/******************************  LICENSE  *******************************
+
+ * (C) Copyright 1996-2017 ECMWF.
+ * 
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+ * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+
+ *******************************  LICENSE  *******************************/
+
+/*! \\file {{object }}Attributes.h
+    \\brief Definition of {{ object }} Attributes class.
+
+    This file is automatically generated.
+    Do Not Edit!
+
+    Generated: {{ date }}
+*/
+
+#include "{{ object }}Attributes.h"
+#include "MagicsParameter.h"
+#include "ParameterSettings.h"
+
+using namespace magics;
+
+{{ object }}Attributes::{{ object }}Attributes(){{ ":" if not string_parameters | length == 0 or not factory_parameters | length == 0 }}
+	{% for param  in string_parameters -%} 
+ 	{{ param.member }}_(ParameterManager::{{ param.method }}("{{ param.name }}")){{ "," if not loop.last }}
+	{% endfor -%}
+	{{ "," if not string_parameters | length == 0 and not factory_parameters | length == 0 }}
+	{% for param  in factory_parameters -%}
+	{{ param.member }}_(MagTranslator<{{ param.from }}, {{ param.to }}>().magics("{{ param.name }}")){{ "," if not loop.last }}
+	{% endfor %} 
+{
+} 
+
+
+{{ object }}Attributes::~{{ object }}Attributes()
+{
+	
+}
+
+    
+void {{ object }}Attributes::set(const std::map<string, string>& params)
+{
+	vector<string> prefix({{ prefix | length -}});
+	int i = 0;
+	{% for key in prefix -%} 
+	prefix[i++] = "{{ key }}";
+	{% endfor %}
+	{% for param  in string_parameters -%} 
+ 	setAttribute(prefix, "{{ param.name }}", {{ param.member }}_, params);
+	{% endfor %}
+	{% for param  in factory_parameters -%} 
+ 	{{ param.method }}(prefix, "{{ param.name }}", {{ param.member }}_, params);
+	{% endfor %}
+}
+
+void {{ object }}Attributes::copy(const {{ object }}Attributes& other)
+{
+	{% for param  in string_parameters -%} 
+ 		{{ param.member }}_ = other.{{ param.member }}_;
+	{% endfor -%}
+	{% for param  in factory_parameters -%} 
+	{% if param.enum  -%}
+		{{ param.member }}_ = other.{{ param.member }}_;
+	{% else -%}
+ 		{{ param.member }}_ = auto_ptr<{{ param.to }}>(other.{{ param.member }}_->clone());
+	{% endif -%}
+	{% endfor %}
+} 
+
+
+bool {{ object }}Attributes::accept(const string& node)
+{	
+	if ( magCompare(node, "{{ tag }}")  )
+		return true;
+	{% for param  in factory_parameters -%} 
+	{% if not param.niceprint -%}
+		if ( acceptNode(node, {{ param.member }}_) )
+		return true;
+	{% endif -%}
+	{% endfor %}
+}
+
+void {{ object }}Attributes::set(const XmlNode& node)
+{
+	if ( this->accept(node.name()) == false ) 
+		return;
+
+	if ( magCompare(node.name(), "{{ tag }}") )
+		set(node.attributes());
+	else {
+		{% for param  in factory_parameters -%} 
+		{% if not param.niceprint  -%}
+		setMember(node.name(), {{ param.member }}_, node);
+		{% endif -%}
+		{% endfor %}
+	}
+	for (XmlNode::ElementIterator elt = node.firstElement(); elt != node.lastElement(); ++elt) {
+		{% for param  in factory_parameters -%} 
+		{% if not param.niceprint  -%}
+		setMember((*elt)->name(), {{ param.member }}_, *(*elt)); 
+		{% endif -%}
+		{% endfor %}
+	}
+}
+
+void {{ object }}Attributes::print(ostream& out)  const
+{
+	out << "{{ name }}Attributes[";
+	{% for param  in string_parameters -%} 
+ 		out << " {{ param.member }} = " <<  {{ param.member }}_;
+	{% endfor -%}
+	{% for param  in factory_parameters -%} 
+	{% if param.enum -%}
+		out << " {{ param.member }} = " <<  {{ param.member }}_;
+	{% else -%}
+		out << " {{ param.member }} = " <<  *{{ param.member }}_;
+	{% endif -%}
+	{% endfor %}
+	out << "]" << "\n";
+}
+
+void {{ object }}Attributes::toxml(ostream& out)  const
+{
+	out <<  "\"{{ tag }}\"";
+	{% for param  in string_parameters -%} 
+	out << ", \"{{ param.name }}:\":";
+	niceprint(out,{{ param.member }}_);
+	{% endfor -%}    
+	{% for param  in factory_parameters -%} 
+	out << ", \"{{ param.name }}\":";
+	{% if param.niceprint -%}
+	niceprint(out, {{ "*" if not param.enum }}{{ param.member }}_);
+	{% else -%} 
+	{{ param.member }}_->toxml(out);
+	{% endif -%}
+	{% endfor %}
+}
+
+{% for param  in string_parameters -%} 
+static MagicsParameter<{{ param.from }}> {{ param.name }}("{{ param.name }}", {{ param.delimiter }}{{ param.default }}{{ param.delimiter }}, "");
+{% endfor -%}  
+{% for param  in factory_parameters -%} 
+static MagicsParameter<{{ param.from }}> {{ param.name }}("{{ param.name }}", {{ param.delimiter }}{{ param.default }}{{ param.delimiter }}, ""); 
+{% endfor  -%}  
+{% for include  in include_options -%} 
+#include "{{ include }}"
+{% endfor -%} 
+{% for param  in factory_parameters -%} 
+{% if  not param.niceprint -%} 
+{% for value  in param.options -%} 
+static SimpleObjectMaker<{{ value.object }} , {{ value.parent }}> {{ value.name }}_{{ value.object }}("{{ value.key }}");
+{% endfor -%} 
+{% endif -%} 
+{% endfor -%}   
+
diff --git a/tools/header.template b/tools/header.template
new file mode 100644
index 0000000..1b9f68e
--- /dev/null
+++ b/tools/header.template
@@ -0,0 +1,81 @@
+
+/*******************************  LICENSE  *******************************
+
+ * (C) Copyright 1996-2016 ECMWF.
+ * 
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+ * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+
+ *******************************  LICENSE  *******************************/
+
+/*! \file{{ object }}Attributes.h
+    \brief Definition of {{ object }} Attributes class.
+
+    This file is automatically generated.
+    Do Not Edit!
+
+    Generated: {{ genereated }}
+*/
+   
+
+#ifndef {{ object }}Attributes_H
+#define {{ object }}Attributes_H
+
+#include "magics.h"
+{% for include  in include -%} 
+#include "{{ include }}"
+{% endfor -%} 
+
+
+namespace magics {
+
+class XmlNode;
+class {{ object }}Attributes {{ ":" if not implements | length == 0 }}
+{% for i in implements -%}
+	{{ '    ' }}public {{ i }}{{ "," if not loop.last }}
+{% endfor -%} 
+{
+public:
+//  --  constructor
+    {{ object }}Attributes();
+    
+//  --  destructor
+    virtual ~{{ object }}Attributes();
+    
+    virtual void set(const std::map<std::string, std::string>&);
+    virtual void set(const XmlNode&);
+    virtual void copy(const {{ object }}Attributes&);
+    virtual bool accept(const std::string&);
+
+    void setTag(const std::string& tag) { tag_ = tag; }
+
+public:
+	//  --  method
+	virtual void print(std::ostream&) const;
+	virtual void toxml(std::ostream& out) const;
+	//  --  members:
+	string tag_;
+	{% for param  in string_parameters -%} 
+	{{ param.to }} {{ param.member }}_;
+	{% endfor -%}
+	{% for param  in factory_parameters -%} 
+	{% if param.enum  -%}
+	{{ param.to }} {{ param.member }}_;
+	{% else -%}
+ 	auto_ptr<{{ param.to }}> {{ param.member }}_;
+	{% endif -%}
+	{% endfor %} 
+
+private:
+	friend ostream& operator<<(ostream& s,const {{ object }}Attributes& p)
+	{ p.print(s); return s; }
+};
+
+} // namespace magics
+
+#endif
+
+
diff --git a/tools/source.template b/tools/source.template
new file mode 100644
index 0000000..08b7180
--- /dev/null
+++ b/tools/source.template
@@ -0,0 +1,162 @@
+
+/******************************  LICENSE  *******************************
+
+ * (C) Copyright 1996-2017 ECMWF.
+ * 
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+ * In applying this licence, ECMWF does not waive the privileges and immunities 
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+
+ *******************************  LICENSE  *******************************/
+
+/*! \\file {{object }}Attributes.h
+    \\brief Definition of {{ object }} Attributes class.
+
+    This file is automatically generated.
+    Do Not Edit!
+
+    Generated: {{ date }}
+*/
+
+#include "{{ object }}Attributes.h"
+#include "MagicsParameter.h"
+#include "ParameterSettings.h"
+
+using namespace magics;
+
+{{ object }}Attributes::{{ object }}Attributes(){{ ":" if not string_parameters | length == 0 or not factory_parameters | length == 0 }}
+	{% for param  in string_parameters -%} 
+ 	{{ param.member }}_(ParameterManager::{{ param.method }}("{{ param.name }}")){{ "," if not loop.last }}
+	{% endfor -%}
+	{{ "," if not string_parameters | length == 0 and not factory_parameters | length == 0 }}
+	{% for param  in factory_parameters -%}
+	{{ param.member }}_(MagTranslator<{{ param.from }}, {{ param.to }}>().magics("{{ param.name }}")){{ "," if not loop.last }}
+	{% endfor %} 
+{
+} 
+
+
+{{ object }}Attributes::~{{ object }}Attributes()
+{
+	
+}
+
+    
+void {{ object }}Attributes::set(const std::map<string, string>& params)
+{
+	vector<string> prefix({{ prefix | length -}});
+	int i = 0;
+	{% for key in prefix -%} 
+	prefix[i++] = "{{ key }}";
+	{% endfor %}
+	{% for param  in string_parameters -%} 
+ 	setAttribute(prefix, "{{ param.name }}", {{ param.member }}_, params);
+	{% endfor %}
+	{% for param  in factory_parameters -%} 
+ 	{{ param.method }}(prefix, "{{ param.name }}", {{ param.member }}_, params);
+	{% endfor %}
+}
+
+void {{ object }}Attributes::copy(const {{ object }}Attributes& other)
+{
+	{% for param  in string_parameters -%} 
+ 		{{ param.member }}_ = other.{{ param.member }}_;
+	{% endfor -%}
+	{% for param  in factory_parameters -%} 
+	{% if param.enum  -%}
+		{{ param.member }}_ = other.{{ param.member }}_;
+	{% else -%}
+ 		{{ param.member }}_ = auto_ptr<{{ param.to }}>(other.{{ param.member }}_->clone());
+	{% endif -%}
+	{% endfor %}
+} 
+
+
+bool {{ object }}Attributes::accept(const string& node)
+{	
+	if ( magCompare(node, "{{ tag }}")  )
+		return true;
+	{% for param  in factory_parameters -%} 
+	{% if not param.niceprint -%}
+		if ( acceptNode(node, {{ param.member }}_) )
+		return true;
+	{% endif -%}
+	{% endfor %}
+	return false;
+}
+
+void {{ object }}Attributes::set(const XmlNode& node)
+{
+	if ( this->accept(node.name()) == false ) 
+		return;
+
+	if ( magCompare(node.name(), "{{ tag }}") )
+		set(node.attributes());
+	else {
+		{% for param  in factory_parameters -%} 
+		{% if not param.niceprint  -%}
+		setMember(node.name(), {{ param.member }}_, node);
+		{% endif -%}
+		{% endfor %}
+	}
+	for (XmlNode::ElementIterator elt = node.firstElement(); elt != node.lastElement(); ++elt) {
+		{% for param  in factory_parameters -%} 
+		{% if not param.niceprint  -%}
+		setMember((*elt)->name(), {{ param.member }}_, *(*elt)); 
+		{% endif -%}
+		{% endfor %}
+	}
+}
+
+void {{ object }}Attributes::print(ostream& out)  const
+{
+	out << "{{ name }}Attributes[";
+	{% for param  in string_parameters -%} 
+ 		out << " {{ param.member }} = " <<  {{ param.member }}_;
+	{% endfor -%}
+	{% for param  in factory_parameters -%} 
+	{% if param.enum -%}
+		out << " {{ param.member }} = " <<  {{ param.member }}_;
+	{% else -%}
+		out << " {{ param.member }} = " <<  *{{ param.member }}_;
+	{% endif -%}
+	{% endfor %}
+	out << "]" << "\n";
+}
+
+void {{ object }}Attributes::toxml(ostream& out)  const
+{
+	out <<  "\"{{ tag }}\"";
+	{% for param  in string_parameters -%} 
+	out << ", \"{{ param.name }}:\":";
+	niceprint(out,{{ param.member }}_);
+	{% endfor -%}    
+	{% for param  in factory_parameters -%} 
+	out << ", \"{{ param.name }}\":";
+	{% if param.niceprint -%}
+	niceprint(out, {{ "*" if not param.enum }}{{ param.member }}_);
+	{% else -%} 
+	{{ param.member }}_->toxml(out);
+	{% endif -%}
+	{% endfor %}
+}
+
+{% for param  in string_parameters -%} 
+static MagicsParameter<{{ param.from }}> {{ param.name }}("{{ param.name }}", {{ param.delimiter }}{{ param.default }}{{ param.delimiter }}, "");
+{% endfor -%}  
+{% for param  in factory_parameters -%} 
+static MagicsParameter<{{ param.from }}> {{ param.name }}("{{ param.name }}", {{ param.delimiter }}{{ param.default }}{{ param.delimiter }}, ""); 
+{% endfor  -%}  
+{% for include  in include_options -%} 
+#include "{{ include }}"
+{% endfor -%} 
+{% for param  in factory_parameters -%} 
+{% if  not param.niceprint -%} 
+{% for value  in param.options -%} 
+static SimpleObjectMaker<{{ value.object }} , {{ value.parent }}> {{ value.name }}_{{ value.object }}("{{ value.key }}");
+{% endfor -%} 
+{% endif -%} 
+{% endfor -%}   
+
diff --git a/tools/x b/tools/x
deleted file mode 100644
index c8e8a13..0000000
--- a/tools/x
+++ /dev/null
@@ -1 +0,0 @@
-DONE
diff --git a/tools/xml2cc.py b/tools/xml2cc.py
new file mode 100755
index 0000000..8a9c9cf
--- /dev/null
+++ b/tools/xml2cc.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+import jinja2
+from xml.sax.handler import ContentHandler
+from xml.sax import make_parser
+from datetime import date
+
+import sys
+
+
+
+class ObjectHandler(ContentHandler):
+
+    name = ""
+    tag = ""
+    generated = date.today().strftime('%Y-%m-%d')
+    parameters = { "basic" : [],
+                   "factory" : [] }
+    basic = {
+        "bool" : "getBool",
+        "int"  : "getInt",
+        "float" : "getDouble",
+        "string" : "getString",
+        "stringarray" : "getStringArray",
+        "intarray" : "getIntArray",
+        "floatarray" : "getDoubleArray",
+        "longintarray" : "getLongIntArray",
+    }
+    types = {
+        "float" : "double",
+        "floatarray" : "doublearray",
+        "longintarray" : "longintarray",
+    }
+    include = {}
+    include_options = {}
+    implements = []
+
+    def addinterface(self, name):
+        if name == "" :
+            return
+        add = name.split('/')
+        for a in add:
+            self.implements.append(a)
+
+    def addimplements(self, name) :
+        if name == "" :
+            return
+        add = name.split('/')
+        for a in add:
+            self.include["%s.h" % a] = "%s.h" % a
+        self.addinterface(name)
+
+    def newclass(self, attrs):
+        self.name = attrs.get("name")
+        self.prefix = attrs.get("prefix", "").split("/")
+        self.tag = attrs.get("xmltag")
+        self.addimplements(attrs.get("implements", ""))
+        self.addinterface(attrs.get("interface", ""))
+        self.current = {}
+
+    def parameter(self, attrs):
+        if attrs.get("implemented") == "no" :
+            return
+        type = attrs.get("to")
+        fromt = attrs.get("from")
+        to = self.types.get(type, type)
+
+        if type in self.basic :
+            self.parameters["basic"].append (
+                {
+                    "name" : attrs.get("name"),
+                    "from" : self.types.get(fromt, fromt),
+                    "to" : to,
+                    "member" : attrs.get("member"),
+                    "default" : attrs.get("default"),
+                    "method" : self.basic[type]
+                }
+                )
+            if type in ["string", "bool"]:
+                self.parameters["basic"][-1]["delimiter"] = "\""
+        else :
+
+            self.parameters["factory"].append (
+                {
+                    "name" : attrs.get("name"),
+                    "from" : attrs.get("from"),
+                    "to" : attrs.get("to"),
+                    "member" : attrs.get("member"),
+                    "default" : attrs.get("default"),
+                    "options"  : [],
+                    "method" : "setMember",
+                    "delimiter" : "\""
+                }
+                )
+            if ( type in ["LineStyle", "ArrowPosition", "Justification",
+                          "AxisAutomaticSetting", "ListPolicy", "Position",
+                          "Hemisphere", "DisplayType", "Matrix", "cairo_t*"]):
+                self.parameters["factory"][-1]["enum"] = True
+                self.parameters["factory"][-1]["method"] = "setAttribute"
+                self.parameters["factory"][-1]["niceprint"] = True
+
+            else :
+                self.include[attrs.get("include", "%s.h" % attrs.get("to"))] = attrs.get("include", "%s.h" % attrs.get("to"))
+            if type in ["Matrix"]:
+                self.parameters["factory"][-1]["delimiter"] = ""
+                self.include["Matrix.h"] = "Matrix.h"
+            if type in ["cairo_t*"]:
+                self.parameters["factory"][-1]["delimiter"] = ""
+                self.include["cairo.h"] = "cairo.h"
+            if type in ["Colour"]:
+                self.parameters["factory"][-1]["niceprint"] = True
+
+
+
+    def option(self, attrs):
+
+        param = self.parameters["factory"][-1]
+        name = attrs.get("xml")
+        if name != None:
+            param["options"].append({
+                "key" : attrs.get("xml"),
+                "name" : name.replace(":", "_"),
+                "parent" : param["to"],
+                "object" : attrs.get("name") } )
+            self.include_options[attrs["include"]] = attrs["include"]
+
+        if attrs.get("fortran") != attrs.get("xml"):
+            name = attrs.get("fortran")
+            if name != None:
+                param["options"].append({
+                    "key" : attrs.get("fortran"),
+                    "name" : name.replace(":", "_"),
+                    "parent" : param["to"],
+                    "object" : attrs.get("name") } )
+                self.include_options[attrs["include"]] = attrs["include"]
+
+
+
+    options = { "class" : newclass,
+                "parameter" : parameter,
+                "option" : option }
+
+    def startElement(self, name, attrs):
+        if name in self.options.keys():
+            self.options[name](self, attrs)
+    def endElement(self, name):
+        pass
+
+object = ObjectHandler()
+saxparser = make_parser()
+saxparser.setContentHandler(object)
+
+toolssource = sys.argv[1]
+
+datasource = open(sys.argv[2], "r")
+destination = sys.argv[3]
+
+saxparser.parse(datasource)
+
+
+with open("%s/source.template" % toolssource,  "r") as source:
+    template = jinja2.Template(source.read())
+with open("%s/%sAttributes.cc" % (destination, object.name), "wt") as out:
+    out.write(template.render(object = object.name,
+                              string_parameters = object.parameters["basic"],
+                              factory_parameters = object.parameters["factory"],
+                              include = object.include,
+                              include_options = object.include_options,
+                              date = object.generated,
+                              tag = object.tag,
+                              prefix = object.prefix
+                             )
+             )
+with open("%s/header.template" % (toolssource), "r") as source:
+    template = jinja2.Template(source.read())
+with open("%s/%sAttributes.h" % (destination, object.name), "wt") as out:
+    out.write(template.render(object = object.name,
+                              string_parameters = object.parameters["basic"],
+                              factory_parameters = object.parameters["factory"],
+                              include = object.include,
+                              include_options = object.include_options,
+                              implements = object.implements,
+                              date = object.generated,
+                              tag = object.tag,
+                              prefix = object.prefix
+                             )
+             )
diff --git a/tools/xml2docs.py b/tools/xml2docs.py
new file mode 100644
index 0000000..7502332
--- /dev/null
+++ b/tools/xml2docs.py
@@ -0,0 +1,73 @@
+import jinja2
+from xml.sax.handler import ContentHandler
+from xml.sax import make_parser
+from datetime import date
+
+import sys
+import json
+
+
+class ObjectHandler(ContentHandler):
+
+	
+	generated = date.today().strftime('%Y-%m-%d')
+	magics = {}
+	current = ""
+	basic = {
+		"bool" : "getBool",
+		"int"  : "getInt",
+		"float" : "getDouble",
+		"string" : "getString",
+		"stringarray" : "getStringArray",
+		"intarray" : "getIntArray",
+		"floatarray" : "getDoubleArray",
+		"longintarray" : "getLongIntArray",
+	}
+	types = {
+		"float" : "double",
+		"floatarray" : "doublearray",
+		"longintarray" : "longintarray",
+	}
+	
+	
+	def newclass(self, attrs):
+		self.current = attrs.get("action", "unknown")
+		self.parameters = self.magics.get(self.current, {})
+	
+
+	def parameter(self, attrs):
+		if attrs.get("implemented") == "no" :
+			return
+		self.parameters.update( { attrs["name"] : { key : attrs[key] for key in ["from", "default"] }})
+
+		
+	options = { "class" : newclass,
+				"parameter" : parameter,
+			}		
+
+
+
+	def startElement(self, name, attrs):
+		if name in self.options.keys():
+			self.options[name](self, attrs)
+	def endElement(self, name):
+		self.magics[self.current] = self.parameters
+		
+
+object = ObjectHandler()
+saxparser = make_parser()
+saxparser.setContentHandler(object)
+
+import glob
+
+
+for a in glob.glob("../src/params/*.xml") :
+	datasource = open(a, "r")
+	saxparser.parse(datasource)	
+
+small = { key : object.magics[key] for key in ["unknown", "pcont"] }
+
+
+print json.dumps(object.magics, indent = 4)
+
+
diff --git a/tools/xml2milana.json b/tools/xml2milana.json
new file mode 100644
index 0000000..284677f
--- /dev/null
+++ b/tools/xml2milana.json
@@ -0,0 +1,7 @@
+
+import xmltodict
+
+with open('../src/params/CoastPlotting.xml') as fd:
+	definition = xmltodict.parse(fd)
+
+print definition
diff --git a/tools/xml2milana.py b/tools/xml2milana.py
new file mode 100644
index 0000000..5949c4c
--- /dev/null
+++ b/tools/xml2milana.py
@@ -0,0 +1,11 @@
+
+import xmltodict
+
+with open('../src/params/CoastPlotting.xml') as fd:
+	definition = xmltodict.parse(fd)
+
+print definition
+
+
+for params in definition["magics"]["class"]:
+	print params
\ No newline at end of file
diff --git a/tools/xml2mv.py b/tools/xml2mv.py
index b360028..50c8175 100755
--- a/tools/xml2mv.py
+++ b/tools/xml2mv.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python 
+#!/usr/bin/env python
 # (C) Copyright 1996-2016 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
@@ -15,8 +15,8 @@ import sys
 
 
 if(len(sys.argv) != 6) :
-    print ("\n\tYou need to give 4 input parameters:")
-    print ("\n\t  %s source.xml targetDef CLASS_NAME rulesDef\n") % sys.argv[0]
+    print("\n\tYou need to give 4 input parameters:")
+    print("\n\t  %s source.xml targetDef CLASS_NAME rulesDef\n",sys.argv[0])
     sys.exit()
 
 
@@ -81,7 +81,7 @@ class ObjectHandler(ContentHandler):
 
 	def default(self, attrs):
 		val = attrs.get("metview_default");
-		if ( isinstance(val, NoneType) ):
+		if val is None:
 			val = attrs.get("default");
 
 		if (val == "") :
@@ -126,7 +126,7 @@ class ObjectHandler(ContentHandler):
 
 	def characters(self, data):
 		pass
-	
+
 
 	# addhidden - if the appropriate flag is set in the attributes, return the text that will
 	#             make the parameter hidden (but available) in Metview
@@ -382,7 +382,7 @@ class ObjectHandler(ContentHandler):
 
 			# we now know that the clause should go into position 'position' in the new tuple
 			if self.debug:
-				print ("put into position " + str(position ))
+				print("put into position " + str(position))
 			if position == 0:
 				firstpart = ()
 				secondpart = (newtuple3,)
@@ -540,7 +540,7 @@ class ObjectHandler(ContentHandler):
 					try:
 						file = open(fname, "r")
 						if (self.debug):
-							print ("Opened (start class)" + fname)
+							print("Opened (start class)" + fname)
 						self.filehistory.append(fname)
 						object = ObjectHandler()
 						object.myoptions = []
@@ -585,7 +585,7 @@ class ObjectHandler(ContentHandler):
 			metview_type = attrs.get("metview_interface")
 			if metview_type != None:
 				type = metview_type
-			if (self.types.has_key(type)):
+			if (type in self.types):
 				f = self.types[type]
 				self.newparam(self.param, f(self, attrs), self.default(attrs))
 			else:
@@ -613,7 +613,7 @@ class ObjectHandler(ContentHandler):
 					#	self.classes[attrs.get("name")]["inherits_reqs_from"].add(self.classname)
 					#	print "YClass " + attrs.get("name") + " inherits_reqs_from " + self.classname
 					if attrs.get("docdive") != 'no' and  attrs.get("doc_inherits") != 'no' :
-						if ( not(isinstance(attrs.get("xmlfile"), NoneType))):
+						if attrs.get("xmlfile") is not None:
 							fname = "/%s.xml" % attrs.get("xmlfile")
 						else:
 							fname = "%s/%s.xml" % (sys.argv[1], attrs.get("name"))
@@ -622,7 +622,7 @@ class ObjectHandler(ContentHandler):
 								file = open(fname, "r")
 								self.filehistory.append(fname)
 								if (self.debug):
-									print ("Opened (start option) " + fname)
+									print("Opened (start option) " + fname)
 								object = ObjectHandler()
 								object.myoptions = []
 								object.myrules = {}
@@ -675,13 +675,13 @@ class ObjectHandler(ContentHandler):
 			self.last = self.last + "\t} = %s\n" % self.defparam
 			self.newparam(self.param, self.last, self.defparam)
 			if (self.debug) :
-				print ("  endparam: " + self.param)
-				print ("  endparam SL: \n" + self.last)
+				print("  endparam: " + self.param)
+				print("  endparam SL: \n" + self.last)
 			self.last = ""
 			for option in self.myoptions:
 				for p in option:
 					#print "    adding newparam from option: " + p[0]
-					self.newparam(p[0], p[1], p[2]) 
+					self.newparam(p[0], p[1], p[2])
 			self.myoptions = []
 			for rules in self.myrules:
 				current = rules
@@ -694,7 +694,7 @@ class ObjectHandler(ContentHandler):
 							except:
 								pass
 							unsets.append(p[0])
-					
+
 				for unset in self.myrules:
 					if (unset == rules):
 						for p in self.myrules[unset]:
@@ -710,8 +710,8 @@ class ObjectHandler(ContentHandler):
 						pass
 
 			self.myrules = {}
-			
-			
+
+
 		if (name == "magics") :
 			if self.toplevel:
 				#print "SL (end class): " + self.last
@@ -838,7 +838,7 @@ class ObjectHandler(ContentHandler):
 							prevparam = condition[0]
 							#print('condition rules:')
 							#print condition
-							rules.write(" " + condition[0].upper() + " <> " + condition[1].upper())
+							rules.write(" " + condition[0].upper() + " != " + condition[1].upper())
 						rules.write(" %then")
 #						for optparam in self.optionalparams2[conditions]:
 						for optparam in clause[1]:

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/magics.git



More information about the debian-science-commits mailing list