[qgis] 01/14: Imported Upstream version 2.8.4+dfsg

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Tue Dec 1 22:36:51 UTC 2015


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

sebastic pushed a commit to branch master
in repository qgis.

commit ff02873e44966411572156af646dd6e58fa0e233
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Mon Nov 30 07:51:19 2015 +0100

    Imported Upstream version 2.8.4+dfsg
---
 CMakeLists.txt                                     |   2 +-
 ChangeLog                                          | 561 +++++++++++++++++++++
 debian/changelog                                   |  14 +
 debian/compat.in                                   |   2 +-
 debian/control.in                                  | 112 ++--
 debian/qgis-plugin-grass.install.in                |   4 -
 debian/qgis-plugin-grass.postrm                    |  12 -
 debian/qgis-plugin-grass.preinst                   |  13 -
 ...s.install.in => qgis-provider-grass.install.in} |   2 -
 debian/qgis-provider-grass.lintian-overrides       |   2 +
 debian/qgis-provider-grass.postrm                  |  12 +
 debian/qgis-provider-grass.preinst                 |  13 +
 debian/rules                                       |  59 ++-
 i18n/qgis_ar.ts                                    |   2 +-
 i18n/qgis_bs.ts                                    |   2 +-
 i18n/qgis_ca.ts                                    |   2 +-
 i18n/qgis_cs.ts                                    |   2 +-
 i18n/qgis_da.ts                                    |   2 +-
 i18n/qgis_de.ts                                    |   2 +-
 i18n/qgis_el.ts                                    |   2 +-
 i18n/qgis_en.ts                                    |   4 +-
 i18n/qgis_es.ts                                    |   2 +-
 i18n/qgis_et.ts                                    |   2 +-
 i18n/qgis_eu.ts                                    |   2 +-
 i18n/qgis_fa.ts                                    |   2 +-
 i18n/qgis_fi.ts                                    |   2 +-
 i18n/qgis_fr.ts                                    |   2 +-
 i18n/qgis_gl.ts                                    |   2 +-
 i18n/qgis_hi.ts                                    |   2 +-
 i18n/qgis_hr.ts                                    |   2 +-
 i18n/qgis_hu.ts                                    |   2 +-
 i18n/qgis_id.ts                                    |   2 +-
 i18n/qgis_is.ts                                    |   2 +-
 i18n/qgis_it.ts                                    |   2 +-
 i18n/qgis_ja.ts                                    |   2 +-
 i18n/qgis_km.ts                                    |   2 +-
 i18n/qgis_ko.ts                                    |   2 +-
 i18n/qgis_lt.ts                                    |   2 +-
 i18n/qgis_lv.ts                                    |   2 +-
 i18n/qgis_mn.ts                                    |   2 +-
 i18n/qgis_nb.ts                                    |   2 +-
 i18n/qgis_nl.ts                                    |   2 +-
 i18n/qgis_pl.ts                                    |   2 +-
 i18n/qgis_pt_BR.ts                                 |   2 +-
 i18n/qgis_pt_PT.ts                                 |   2 +-
 i18n/qgis_ro.ts                                    |   2 +-
 i18n/qgis_ru.ts                                    |   2 +-
 i18n/qgis_sk.ts                                    |   2 +-
 i18n/qgis_sl.ts                                    |   2 +-
 i18n/qgis_sr.ts                                    |   2 +-
 i18n/qgis_sr at latin.ts                              |   2 +-
 i18n/qgis_sv.ts                                    |   2 +-
 i18n/qgis_th.ts                                    |   2 +-
 i18n/qgis_tr.ts                                    |   2 +-
 i18n/qgis_uk.ts                                    |   2 +-
 i18n/qgis_vi.ts                                    |   2 +-
 i18n/qgis_zh-Hans.ts                               |   2 +-
 i18n/qgis_zh_CN.ts                                 |   2 +-
 i18n/qgis_zh_TW.ts                                 |   2 +-
 python/core/__init__.py                            |   6 +-
 python/core/qgsdistancearea.sip                    |  16 +-
 python/core/qgserror.sip                           |   2 +-
 python/core/qgsfeaturestore.sip                    |   2 +-
 python/core/qgsfield.sip                           |  16 +-
 python/core/qgsmapunitscale.sip                    |  16 +-
 python/core/qgsvectorlayer.sip                     |   6 +-
 python/core/qgsvectorlayereditutils.sip            |   4 +-
 python/core/symbology-ng/qgsfillsymbollayerv2.sip  |   8 +-
 python/core/symbology-ng/qgslinesymbollayerv2.sip  |   2 +-
 python/core/symbology-ng/qgssvgcache.sip           |   6 +-
 python/core/symbology-ng/qgsvectorcolorrampv2.sip  |  17 +-
 .../db_manager/db_plugins/postgis/plugin.py        | 493 +++++++++---------
 python/plugins/processing/algs/qgis/VectorGrid.py  |   2 +-
 .../description/2.1.2/OrdinaryKriging(Global).txt  |  33 +-
 .../saga/description/2.1.2/OrdinaryKriging.txt     |  10 +-
 .../description/2.1.2/UniversalKriging(Global).txt |  34 +-
 .../saga/description/2.1.2/UniversalKriging.txt    |  45 +-
 resources/function_help/lpad                       |   4 +-
 resources/function_help/rpad                       |   4 +-
 scripts/release.pl                                 |   6 +-
 src/app/composer/qgscomposer.cpp                   |  68 ++-
 src/app/composer/qgscomposerscalebarwidget.cpp     |   5 +
 src/app/ogr/qgsopenvectorlayerdialog.cpp           |   4 +-
 src/app/qgisapp.cpp                                |  78 ++-
 src/app/qgisapp.h                                  |   6 +
 src/app/qgsattributetabledialog.cpp                |   3 +-
 src/app/qgsidentifyresultsdialog.cpp               |   2 +-
 src/app/qgsmaptoolcapture.cpp                      |   7 +
 src/app/qgsmaptoolfillring.cpp                     |  36 +-
 src/app/qgsmergeattributesdialog.cpp               |  26 +-
 src/app/qgsmergeattributesdialog.h                 |   5 +
 src/app/qgsprojectproperties.cpp                   |   8 +-
 src/app/qgssnappingdialog.cpp                      |   1 +
 src/app/qgstipfactory.cpp                          |   2 +-
 src/core/composer/qgscomposerscalebar.cpp          |  24 +-
 src/core/composer/qgscomposition.cpp               |  35 +-
 src/core/qgis.h                                    |   8 +
 src/core/qgsdistancearea.cpp                       |   8 +
 src/core/qgsdistancearea.h                         |  16 +-
 src/core/qgserror.h                                |   2 +-
 src/core/qgsexpression.cpp                         |  68 ++-
 src/core/qgsfeaturestore.cpp                       |   5 +-
 src/core/qgsfeaturestore.h                         |   2 +-
 src/core/qgsfield.cpp                              |  34 +-
 src/core/qgsfield.h                                |   4 +-
 src/core/qgsmaplayer.cpp                           |   1 +
 src/core/qgsmapunitscale.h                         |  22 +-
 src/core/qgspallabeling.cpp                        |   2 +
 src/core/qgsvectorfilewriter.cpp                   |  22 +-
 src/core/qgsvectorfilewriter.h                     |   1 +
 src/core/qgsvectorlayer.cpp                        |  16 +-
 src/core/qgsvectorlayer.h                          |   6 +-
 src/core/qgsvectorlayereditbuffer.cpp              |  40 +-
 src/core/qgsvectorlayereditutils.cpp               |   5 +-
 src/core/qgsvectorlayereditutils.h                 |   4 +-
 src/core/symbology-ng/qgsellipsesymbollayerv2.cpp  |  15 +-
 src/core/symbology-ng/qgsellipsesymbollayerv2.h    |   5 +-
 src/core/symbology-ng/qgsfillsymbollayerv2.cpp     |  14 +-
 src/core/symbology-ng/qgsfillsymbollayerv2.h       |   6 +-
 src/core/symbology-ng/qgsmarkersymbollayerv2.cpp   |  12 +-
 src/core/symbology-ng/qgsmarkersymbollayerv2.h     |   5 +-
 src/core/symbology-ng/qgsrulebasedrendererv2.cpp   |   2 +-
 src/core/symbology-ng/qgsrulebasedrendererv2.h     |   2 +-
 src/core/symbology-ng/qgssvgcache.cpp              |  10 +-
 src/core/symbology-ng/qgssvgcache.h                |   6 +-
 src/core/symbology-ng/qgssymbollayerv2.cpp         |  15 +-
 src/core/symbology-ng/qgssymbollayerv2utils.cpp    |   6 +-
 src/core/symbology-ng/qgsvectorcolorrampv2.cpp     |  12 +-
 src/core/symbology-ng/qgsvectorcolorrampv2.h       |   6 +-
 .../qgsattributetablefiltermodel.cpp               |   3 +-
 src/gui/attributetable/qgsattributetablemodel.cpp  |   5 +-
 src/gui/qgsattributeform.cpp                       |   5 +-
 src/gui/qgsmapoverviewcanvas.cpp                   |   1 +
 .../qgssinglebandpseudocolorrendererwidget.cpp     |  11 +
 .../qgspointdisplacementrendererwidget.cpp         |   4 +-
 .../qgsvectorgradientcolorrampv2dialog.cpp         |   5 +-
 src/plugins/grass/qgsgrassmodule.cpp               |   4 +
 src/plugins/heatmap/heatmap.cpp                    |   8 +-
 src/plugins/heatmap/heatmap.h                      |   4 +-
 src/plugins/heatmap/heatmapgui.cpp                 |  20 +-
 src/plugins/heatmap/heatmapgui.h                   |   8 +-
 src/plugins/heatmap/heatmapguibase.ui              |   4 +-
 src/providers/ogr/qgsogrprovider.cpp               |   2 +-
 src/providers/oracle/qgsoracleprovider.cpp         |   2 +-
 src/providers/postgres/qgspostgresprovider.cpp     |   7 +
 src/server/qgshttprequesthandler.cpp               |   1 -
 src/server/qgsserverprojectparser.cpp              |  33 +-
 src/server/qgswfsserver.cpp                        |  21 +-
 src/server/qgswmsconfigparser.cpp                  |  16 +-
 src/server/qgswmsprojectparser.cpp                 |   8 +-
 src/server/qgswmsserver.cpp                        |   8 +-
 src/ui/qgsadvanceddigitizingdockwidgetbase.ui      |  47 +-
 tests/src/core/CMakeLists.txt                      |   1 +
 tests/src/core/testqgscomposermap.cpp              |  23 +-
 tests/src/core/testqgsdistancearea.cpp             |  31 +-
 tests/src/core/testqgsmarkerlinesymbol.cpp         | 154 ++++++
 tests/src/python/CMakeLists.txt                    |   1 +
 tests/src/python/test_qgsmapunitscale.py           | 101 ++++
 .../expected_line_offset/expected_line_offset.png  | Bin 0 -> 40258 bytes
 tests/testdata/marker_line_offset.qml              | 284 +++++++++++
 160 files changed, 2393 insertions(+), 755 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f80b672..f0fb60d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 SET(CPACK_PACKAGE_VERSION_MAJOR "2")
 SET(CPACK_PACKAGE_VERSION_MINOR "8")
-SET(CPACK_PACKAGE_VERSION_PATCH "3")
+SET(CPACK_PACKAGE_VERSION_PATCH "4")
 SET(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
 SET(RELEASE_NAME "Wien")
 IF (POLICY CMP0048) # in CMake 3.0.0+
diff --git a/ChangeLog b/ChangeLog
index bf26463..4c5b489 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,564 @@
+Juergen E. Fischer <jef at norbit.de>	2015-11-26
+
+    release.pl: point releases don't need a new splash
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-21
+
+    vector file writer: defer destroying spatial reference (fixes #10515)
+
+    (cherry picked from commit cee63c84f7f85586ddcb5348e70a0af0b1bcdf5e)
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-21
+
+    vector layer: update geometries first before feature id might change (fixes #8255)
+
+    (backported from commit 24b6e63)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-07
+
+    oracle provider: fix call of sdo_filter to verify a spatial index is present
+
+    (cherry picked from commit 684346a955dd4c79efcb6bfe519f6006c73c2aaa)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-11
+
+    attribute editing: don't allow editing without ChangeAttributeValues capability
+
+    (cherry picked from commit 15af5a11701fc8f0b3723b2d45423c19b07e4df5)
+
+Juergen E. Fischer <jef at norbit.de>	2015-09-29
+
+    ogr provider: don't add mysql table filter multiple times (fixes #13446)
+
+    (cherry picked from commit 32c5f551012a65a8705475266447b270dc2111ff)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-13
+
+    db manager: add credentials to postgis rasters (fixes #13594)
+
+    (backports from commit 53c507d)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-18
+
+    heatmap plugin: fix labeling s/metre/layer units/ (fixes #11276)
+
+    (backports from commit c373d7b)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-18
+
+    avoid on duplicate user functions (fixes #13579)
+
+    (backports from commit cc9c789)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-11
+
+    case-sensitivity of vector layer field (fixes #13032)
+    * fieldNameIndex: resort to case-insensitive lookup only if
+      case-sensitive lookup has no match
+    * file writer: fix handling of fields that only differ by case
+
+    (backported from commit 8e2b791)
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-21
+
+    fix rpad/lpad help (fixes #13433)
+
+rldhont <rldhont at gmail.com>	2015-11-26
+
+    [QGIS-Server] Enhance store project keyword list
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Fix fill ring tool creates more features than needed (fix #13354)
+
+    (cherry-picked from 45a6f715b3b980ea4ad0dce7e35aace041caac6d)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Fix overview canvas background color not set (fix #11157)
+
+    (cherry-picked from f60ca59996544a29567cfa6a68f6dc2c1664f6dd)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Fix merge attributes/features tool resets values to null for int fields
+
+    Also add a warning if merged attribute value is not compatible with
+    field type.
+
+    Fix #12842
+
+    (cherry-picked from 099a40bdf2a59f87e28b9c6664c6b9da6fd927b4)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Fix merge attributes tool sets skipped attributes to null (fix #13231)
+
+    (cherry-picked from 0bda18b6e04105d52cfe6f54792de2f2e2b4a925)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Fix storing string representations of doubles in an int field
+    results in NULL rather than converting value to int
+
+    (cherry-picked from 1c76b93d89e9edf3a3abb153402c541e66756add)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-19
+
+    Introduce qgsRound since std::round is available only in C++11 onwards
+
+    (cherry-picked from 468012a282d8f96d0ad4f12cade2504a77cd75f9)
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-19
+
+    fix build of distance area tests (followup 3667651)
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-19
+
+    fix precise build (followup 3667651)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix composer scale bar when crs units are non-meters and OTF is off (fix #13610)
+
+    (cherry-picked from d56dcdb02fc65d8cd6fc2a5a92b0be4756aa8e2d)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    [composer] Fix scalebar widgets not updated when changing units (fix #13572)
+
+    (cherry-picked from dc6c12b6c333fe31fd249c96fc64f87261da2716)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix potential crash in vector gradient dialog info button
+
+    Note that this doesn't seem to be actually utilised by any
+    of the preinstalled gradients, but if users have created
+    a gradient with info then clicking the button would have
+    crashed QGIS.
+
+    Identified by clazy.
+
+    (cherry-picked from 84dade97f6633e404a26be79814700f589c3a761)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    set selection color from project file
+
+    fix #3400
+    also remove duplicate setting of background color (it is set by ProjectProperties)
+
+    (cherry-picked from 07db9848301daae5c07b3ee5a4130cf80a357f65)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Also show features with modified geometry when "show edited and new
+    features" filter is active in attribute dialog (fix #11684)
+
+    (cherry-picked from e92e91060140e80c22a61406d640054fa4585a52)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Add tooltips to advanced digitizing dock
+
+    (cherry-picked from b4b70170685c029e52f78aace893144f5a777ab2)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix ellipse symbol layer with graduated/categorised renderer
+
+    (cherry-picked from 5a6bfbb260d4054fa5d075510423f7374ce1af78)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Followup a721752, also fix svg marker fill cannot be used with
+    categorised or graduated renderers
+
+    (cherry-picked from f9231df1f11723c9cb1be746d9ed3ed322545589)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Allow coloring of svg markers when used with graduated/categorised renderers (fix #11658)
+
+    (cherry-picked from a721752ced4931b13c9b6a79db8f2be059cc9824)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix crash if selecting a nonsense subrenderer for displacement renderer
+
+    (cherry-picked from 6bfdafe3d36dbcd88343efd583e725f3b4643675)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix fill and outline color for svg markers sometimes enabled
+    when SVG file does not support parameters
+
+    (Cherry-picked from 3aa6c4f0120bb5d9d5297d9d9f5503c38ff9a977)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix snapping options dialog not correctly initialised when loading projects
+
+    (cherry-picked from 0da930615947af1967262de4a7a9a400c6e3d69a)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix symbols drawn multiple times in rule based renderer if symbol
+    has multiple layers
+
+    (cherry-picked from a0d7653b53e63da9751755096b7bb4445e7632a1)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Fix fill ring tool used with advanced digitising crashes QGIS
+
+    (fix #13355)
+    (cherry-picked from aa4d65d3b8926b36f88205dbb0d192b12bc1d1ad)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    QgsMapUnitScale fixes:
+
+    - add docs
+    - add missing SIP bindings
+    - remove unnecessary cast from double->float->double
+    - add unit tests
+
+    (cherry-picked from f0a2fc192524a8990f8d8c2190505ade91f037e8)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Allow transparency for point displacement circle/label colors
+
+    (cherry-picked from 8f0ed6155acb9e531bbc2a1e8fcf599d061227e1)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Allow escape to cancel drawing new features
+
+    (cherry-picked from e2dc8bfe148a70173deee258f36c0194e53fda63)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    [labelling] set full rule of qpainterpath for text/buffer rendering
+
+    (cherry-picked from 2856981ebdf942fdeb7abf9fd8958dea946493d3)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-11-18
+
+    Add missing /Transfer/s to setSubSymbol
+
+    (cherry-picked from dc0639c7944320ceeca40413d5dc2147f5c2d328)
+
+Giovanni Manghi <giovanni.manghi at faunalia.pt>	2015-11-12
+
+    fix SAGA 2.1.2 kriging
+
+Sandro Santilli <strk at keybit.net>	2015-11-12
+
+    [BUGFIX] Fix endpoint swap on negative marker line offset
+
+    Fixes #13811
+    Includes testcase
+
+    (cherr-picked from 824fd7bf32a45e278f2ec2fe9fa1c7228c9fb27f)
+
+rldhont <rldhont at gmail.com>	2015-11-12
+
+    Update [BUGFIX] 13118 QGIS Server - WFS - GeoJSON and escaping line breaks
+
+    Enhance replace, thanks to @nyalldawson
+    Enhance format, thanks to @jef-n
+
+    fixes #13118
+
+Juergen E. Fischer <jef at norbit.de>	2015-11-12
+
+    fix windows build (followup 2175e7a)
+
+    (cherry picked from commit 6e1df491f64bff1b778502d7d53f37256afcd6f6)
+
+rldhont <rldhont at gmail.com>	2015-11-11
+
+    [BUGFIX] 13118 QGIS Server - WFS - GeoJSON and escaping line breaks
+
+    Line breaks are not properly handled in GeoJSON results when making GetFeature requests.
+    Line breaks should be replaced by \\n.
+
+rldhont <rldhont at gmail.com>	2015-11-10
+
+    [QGIS-Server] Use layer precision in searchRect
+
+Sandro Santilli <strk at keybit.net>	2015-11-06
+
+    Properly set invalid topology layer as invalid
+
+    Fixes #13781 (crash)
+
+Juergen E. Fischer <jef at norbit.de>	2015-10-24
+
+    render polygons with outline using drawPath (fixes #13343)
+
+    (cherry picked from commit 08185c9af47dcf113c0cb95faa858ec48e48dab2)
+
+rldhont <rldhont at gmail.com>	2015-10-26
+
+    [BUGFIX][QGIS Server] Laye order from group in GetPrint
+
+    Since QGIS 2.8, QGIS Server rendered layers form group in reverted order.
+
+    Conflicts:
+src/server/qgswmsconfigparser.cpp
+
+rldhont <rldhont at gmail.com>	2015-10-23
+
+    [BUGFIX] Set default units to mm in GetStyles
+
+    The default units in QgsMapRenderer is Millimeters. The default units in SLD
+     is Pixel but exportSld does not convert all millimeters in pixels.
+
+    We notes this bug by comparing default QGS Server rendering and rendering with
+     the SLD generated by QGIS.
+
+    To resolve it, we just have to add units to the document element.
+
+rldhont <rldhont at gmail.com>	2015-10-23
+
+    [BUGFIX] Set default units to mm in exportSld
+
+    The default units in QgsMapRenderer is Millimeters. The default units in SLD
+     is Pixel but exportSld does not convert all millimeters in pixels.
+
+    We notes this bug by comparing default QGS Server rendering and rendering with
+     the SLD generated by QGIS.
+
+    To resolve it, we just have to add units to the document element.
+
+rldhont <rldhont at gmail.com>	2015-10-22
+
+    [BUGFIX][QGIS Server] Clean Headers
+
+    With https://github.com/3liz/qgis-wfsOutputExtension, I found that QGIS Server
+     Headers are not always well formed. An extra line can be added at the end.
+
+    In the commit a9c830e67b7fe0e7f66fc23b5a5a85b7b8ac5c61 from @mhugent, I found
+     the fix.
+
+rldhont <rldhont at gmail.com>	2015-10-13
+
+    [BUGFIX][QGIS Server] Add layer coordinate transforms before setting destination CRS
+
+    If the layer_coordinate_transform_info child of mapcanvas has not been well
+     saved, the destinationCrs is not well applied and we get a blank image.
+
+    To resolve this issue, we just have to add layer coordinate transforms to the
+     map renderer before setting the destination CRS.
+
+rldhont <rldhont at gmail.com>	2015-10-06
+
+    [BUGFIX][QGIS-Server] Restricted layers and layer id as name are incompatible
+
+    If the user checks 'used layer id as name' and specifies 'restricted layers',
+     the restriction is not applied.
+
+    To fix it, I add the layer ids to the restricted layers list.
+
+Juergen E. Fischer <jef at norbit.de>	2015-09-28
+
+    debian packageing update (grass6/7)
+
+rldhont <rldhont at gmail.com>	2015-09-22
+
+    Update b54d2790d4b74449bd8f28a6ca838e42f66f55a2
+
+rldhont <rldhont at gmail.com>	2015-09-22
+
+    [Server][BUGFIX] Resolve relative pathes (SVGMArker, Netcdf, etc)
+
+    QGIS-Server has some trouble to resolve relative pathes. For example,
+     SVGMarker path and NETCDF datasource are not resolved in QGIS Server unlike
+     in QGIS Desktop.
+
+    To resolve relative path for SVGMarker, the class QgsSombolLayerV2Utils is
+     used and it based on QgsProject::instance()->fileName().
+    To resolve relative path for NETCDF datasource and other GDAL datasources, the
+     class QgsMapLayer is used and it based on
+     QgsProject::instance()->readPath( filename ).
+
+    To fix the issue, the QgsProject instance fileName is set in the
+     QgsServerProjectParser constructor.
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-09-16
+
+    Fix broken QgsFeatureStore::setFields method
+
+    Was setting fields only on temporary copies of the features, not
+    the stored features themselves
+
+    (cherry-picked from 910cb01)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-09-16
+
+    [composer] Fix generation of world file when map is not on first page
+
+    fix #13262
+
+    (cherry-picked from d897624)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-09-16
+
+    [composer] Fix world file filename for multipage compositions
+
+    also fix #11676
+
+    (cherry-picked from c84b2df)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-09-16
+
+    [composer] Remember last used atlas image export folder
+
+    (cherry-picked from 4bc606c)
+
+Salvatore Larosa <lrssvtml at gmail.com>	2015-09-15
+
+    fix filtered features number over the window title
+
+    cherry-picked from 7065762
+
+rldhont <rldhont at gmail.com>	2015-09-15
+
+    [SERVER][BUGFIX] Use cache if styleName is EMPTY_STYLE_NAME
+
+    The QGIS Server layer cache is used to store layer with default style, but in
+     QgsWMSProjectParser::mapLayerFromStyle layers are not cached if the style is
+     not empty.
+
+    In WMS, default and empty style is the same and the variable EMPTY_STYLE_NAME
+     is here for this.
+
+    The fix uses EMPTY_STYLE_NAME to use the cache.
+
+rldhont <rldhont at gmail.com>	2015-09-15
+
+    [SERVER][BUGFIX] Layer order from group
+
+    If custom order is not enabled and a group is requested, layers was added in
+     the DOM element order. The default endering order is the reverse.
+
+    To fix this issue, QgsWMSProjectParser::addLayersFromGroup has to read group
+     element children from end (bottom) to start (top).
+
+Juergen E. Fischer <jef at norbit.de>	2015-08-31
+
+    fix feature id handling when opening feature form from identify results (fixes #13289)
+
+    (cherry picked from commit 5326c6bd1bd5aebf9975d751f840750a491641a7)
+
+Juergen E. Fischer <jef at norbit.de>	2015-03-04
+
+    postgres provider: disable editing of existing features when ctid is key
+
+    (cherry picked from commit 2844005e805709bb39b95aef6a7e5a72777b8b0f)
+
+Juergen E. Fischer <jef at norbit.de>	2015-08-25
+
+    debian packaging update (grass7)
+
+Juergen E. Fischer <jef at norbit.de>	2015-08-23
+
+    fix typo
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-16
+
+    If user clicks cancel while browsing for file then don't clear
+    the existing filename in the vector open file dialog
+
+    (cherry-picked from 1a91ae8fd11511a8c09fa193a3ce33e04edc7b30)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-16
+
+    Fix memory leaks in geometry expression functions
+
+    (cherry-picked from cd7592df603cde1da5ef401b14cd6c7a14c9248c)
+
+Juergen E. Fischer <jef at norbit.de>	2015-08-07
+
+    vector layer: ignore non-existing fields in min/max/uniqueValues (fixes #13194)
+
+    (cherry picked from commit 71e7aabbdec6cc5d542420948d897f7f7fda8303)
+
+Merge: a3c239f 1207e38
+William Kyngesburye <kyngchaos at kyngchaos.com>	2015-08-08
+
+    Merge branch 'release-2_8' of https://github.com/qgis/QGIS into release-2_8
+
+William Kyngesburye <kyngchaos at kyngchaos.com>	2015-08-08
+
+    find bundled GRASS on OS X
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-05
+
+    Add missing color ramp methods and conversions to sip
+
+    (cherry-picked from 56a48ed0d2927dbffcb868ebadc5d253c3a8e2c9)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-05
+
+    Fix invalid color could be returned by QgsRandomColorsV2
+
+    (cherry-picked from 3c45b2352a2a26931b6fcf3fe8100f978412d73d)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-04
+
+    Fix bad alloc when styling raster with random color ramp (fix #13112)
+
+    (cherry-picked from 688ac1610e5b47fa3116875c463ba9fd2a026200)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-04
+
+    Fix random color ramps returning invalid QColors for value of 1.0
+
+    (cherry-picked from 1d2b4cb41aa81a7c11d351fa36d71f444cf7cc7c)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-04
+
+    Fix saturation range ignored for random color ramps
+
+    (cherry-picked from 569040211618904cb1f4f2eda1019ef0f5c0e8f3)
+
+Nyall Dawson <nyall.dawson at gmail.com>	2015-08-04
+
+    Fix incorrect values returned by certain color ramps
+
+    (cherry-picked from 27ee8eea45f4b7db9631980c2218598ca7edab05)
+
+Martin Dobias <wonder.sk at gmail.com>	2015-07-31
+
+    Fix crashes when rendering with SVG symbols that are missing
+
+    The crashes would happen after some time when browsing the map,
+    especially when size of SVGs is in map units. This was due to wrong
+    removal of deleted cache entries where cache entry key would be
+    different from SVG file's path, thus not removing the entry that
+    got deleted. Now explicitly keeping the lookup key in the entry
+    to make sure this does not happen.
+
+    Related issues: #9959, #8883
+
+    (cherry picked from commit febadfe21bb1eb5639d5a90d52f845415b31fb7b)
+
+Giovanni Manghi <giovanni.manghi at faunalia.pt>	2015-07-31
+
+    fix Processing QGIS vector grid as lines
+
+    fixes #13115
+    (cherry-picked from 1dfec33)
+
+Juergen E. Fischer <jef at norbit.de>	2015-07-28
+
+    Release of 2.8.3
+
 Nyall Dawson <nyall.dawson at gmail.com>	2015-07-22
 
     Fix 'nan'='nan' evaluates to false in expressions
diff --git a/debian/changelog b/debian/changelog
index 37ab519..b4be35a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+qgis (2.8.4) UNRELEASED; urgency=medium
+
+  * Release of 2.8.4
+
+ -- Jürgen E. Fischer <jef at norbit.de>  Fri, 27 Nov 2015 12:59:37 +0100
+
+qgis (2.8.3-1) unstable; urgency=medium
+
+  * split grass provider off into a separate package.
+  * disable grass plugin on sid (because of GRASS7)
+  * add ubuntu wily
+
+ -- Jürgen E. Fischer <jef at norbit.de>  Fri, 27 Nov 2015 12:59:37 +0100
+
 qgis (2.8.3) UNRELEASED; urgency=medium
 
   * Release of 2.8.3
diff --git a/debian/compat.in b/debian/compat.in
index 795b270..64dae5d 100644
--- a/debian/compat.in
+++ b/debian/compat.in
@@ -1,3 +1,3 @@
-#sid jessie sid-oracle trusty utopic vivid#9
+#stretch sid jessie trusty utopic vivid wily#9
 #wheezy jessie#8
 #precise#7
diff --git a/debian/control.in b/debian/control.in
index 37e39b3..baff09d 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -6,13 +6,13 @@ Priority: optional
 Build-Depends:
  bison,
  cmake (>= 2.8),
-#sid jessie wheezy saucy sid-oracle trusty utopic vivid# debhelper (>= 9),
+#sid stretch jessie wheezy saucy trusty utopic vivid wily# debhelper (>= 9),
 #precise# debhelper (>= 7),
  flex,
- grass-dev (<< 7),
+ grass-dev,
  libexpat1-dev,
  libfcgi-dev,
-#sid jessie sid-oracle trusty utopic vivid# libgdal-dev (>= 1.10.1-0~),
+#sid stretch jessie trusty utopic vivid wily# libgdal-dev (>= 1.10.1-0~),
 #precise# libgdal-dev (>= 1.9.0) | libgdal1-dev (<< 1.9.0),
 #saucy# libgdal-dev (>= 1.9.0),
 #wheezy# libgdal1-dev,
@@ -23,21 +23,23 @@ Build-Depends:
  libqt4-dev (>= 4.7.0),
  libqt4-opengl-dev,
  libqtwebkit-dev,
-#sid jessie wheezy sid-oracle# libqwt-dev,
-#precise saucy trusty utopic vivid# libqwt5-qt4-dev,
+#stretch jessie wheezy# libqwt-dev,
+#precise saucy trusty utopic vivid wily stretch sid# libqwt5-qt4-dev,
  libspatialite-dev,
  libsqlite3-dev,
  libspatialindex-dev,
  pkg-config,
  pyqt4-dev-tools,
  python-qscintilla2,
+ python-qt4 (>= 4.1.0),
+ python-qt4-dev,
 #precise saucy wheezy# python,
 #precise saucy# python-central (>= 0.5),
 #saucy wheezy# python-dev,
 #saucy# libpython2.7-dev,
-#sid jessie sid-oracle trusty utopic vivid# python-all (>= 2.6.6-3~), python-all-dev (>= 2.6.6-3~),
-#sid jessie wheezy precise saucy sid-oracle trusty utopic vivid# python-qt4 (>= 4.1.0), python-qt4-dev,
-#sid# pyqt4.qsci-dev,
+#sid stretch jessie trusty utopic vivid wily# python-all (>= 2.6.6-3~), python-all-dev (>= 2.6.6-3~),
+#sid stretch jessie# pyqt4.qsci-dev,
+#sid stretch jessie trusty utopic vivid wily# python-pyspatialite,
  python-sip (>= 4.5.0),
  python-sip-dev (>= 4.5.0),
  libosgearth-dev,
@@ -49,14 +51,14 @@ Build-Depends:
  txt2tags,
  xvfb, xauth,
  xfonts-base, xfonts-100dpi, xfonts-75dpi, xfonts-scalable,
-#sid-oracle# oracle-instantclient11.2-devel,
+#oracle# oracle-instantclient11.2-devel,
  spawn-fcgi, lighttpd, poppler-utils, locales
 Build-Conflicts: libqgis-dev, qgis-dev
-#sid jessie sid-oracle vivid#Standards-Version: 3.9.6
+#sid stretch jessie vivid wily#Standards-Version: 3.9.6
 #wheezy#Standards-Version: 3.9.3
 #precise saucy trusty utopic#Standards-Version: 3.8.4
-#sid jessie sid-oracle#X-Python-Version: >= 2.7, << 2.8
-#wheezy precise saucy trusty utopic vivid#XS-Python-Version: current
+#sid stretch jessie#X-Python-Version: >= 2.7, << 2.8
+#wheezy precise saucy trusty utopic vivid wily#XS-Python-Version: current
 Vcs-Browser: https://github.com/qgis/QGIS/
 Vcs-Git: https://github.com/qgis/QGIS.git
 Homepage: http://qgis.org/
@@ -69,7 +71,8 @@ Depends:
  qgis-providers (= ${binary:Version}),
  qgis-common (= ${source:Version})
 Recommends:
- qgis-plugin-grass,
+#grass6# qgis-plugin-grass,
+ qgis-provider-grass,
  qgis-plugin-globe,
  python-qgis
 Suggests: gpsbabel
@@ -210,9 +213,9 @@ Package: libqgis-dev
 Architecture: any
 Section: libdevel
 Depends:
- grass-dev (<< 7),
+ grass-dev,
  libexpat1-dev,
-#sid jessie sid-oracle trusty utopic vivid# libgdal-dev (>= 1.10.1-0~),
+#sid stretch jessie trusty utopic vivid wily# libgdal-dev (>= 1.10.1-0~),
 #precise# libgdal-dev (>= 1.9.0) | libgdal1-dev (<< 1.9.0),
 #saucy# libgdal-dev (>= 1.9.0),
 #wheezy# libgdal1-dev,
@@ -244,36 +247,51 @@ Description: QGIS - development files
  This package contains the headers and libraries needed to develop plugins for
  QGIS.
 
-Package: qgis-plugin-grass
+Package: qgis-provider-grass
 Architecture: any
 Depends:
  qgis (= ${binary:Version}),
- qgis-plugin-grass-common (= ${source:Version}),
  ${shlibs:Depends},
- ${misc:Depends},
-#!precise# grass-core (<< 7)
-#precise# grass (<< 7)
-Description: GRASS plugin for QGIS
- QGIS is a Geographic Information System (GIS) which manages, analyzes and
- display databases of geographic information.
- .
- This plugin enables GRASS data access in the QGIS geographic data viewer.
-
-Package: qgis-plugin-grass-common
-Architecture: all
-Depends:
-#sid jessie saucy sid-oracle trusty# python2.7,
-#wheezy precise# python,
  ${misc:Depends}
-Breaks: qgis-common (<< 1.5)
-Replaces: qgis-common (<< 1.5)
-Description: GRASS plugin for QGIS - architecture-independent data
+#grass7#Breaks: qgis-plugin-grass
+#grass7#Replaces: qgis-plugin-grass
+Description: GRASS plugin for QGIS
  QGIS is a Geographic Information System (GIS) which manages, analyzes and
  display databases of geographic information.
  .
- This package contains architecture-independent supporting data files for use
- with the QGIS GRASS plugin.
+ This provider enables GRASS data access in QGIS.
 
+#grass6#Package: qgis-plugin-grass
+#grass6#Architecture: any
+#grass6#Depends:
+#grass6# qgis (= ${binary:Version}),
+#grass6# qgis-plugin-grass-common (= ${source:Version}),
+#grass6# qgis-provider-grass (= ${source:Version}),
+#grass6# ${shlibs:Depends},
+#grass6# ${misc:Depends},
+#grass6##!precise# grass-core (<< 7)
+#grass6##precise# grass (<< 7)
+#grass6#Description: GRASS plugin for QGIS
+#grass6# QGIS is a Geographic Information System (GIS) which manages, analyzes and
+#grass6# display databases of geographic information.
+#grass6# .
+#grass6# This plugin enables GRASS data access in QGIS.
+#grass6#
+#grass6#Package: qgis-plugin-grass-common
+#grass6#Architecture: all
+#grass6#Depends:
+#grass6##saucy trusty# python2.7,
+#grass6##precise# python,
+#grass6# ${misc:Depends}
+#grass6#Breaks: qgis-common (<< 1.5)
+#grass6#Replaces: qgis-common (<< 1.5)
+#grass6#Description: GRASS plugin for QGIS - architecture-independent data
+#grass6# QGIS is a Geographic Information System (GIS) which manages, analyzes and
+#grass6# display databases of geographic information.
+#grass6# .
+#grass6# This package contains architecture-independent supporting data files for use
+#grass6# with the QGIS GRASS plugin.
+#grass6#
 Package: qgis-plugin-globe
 Architecture: any
 Depends:
@@ -315,7 +333,7 @@ Depends:
  python-dateutil,
  python-tz,
  python-six,
-#sid jessie trusty utopic vivid sid-oracle# python-pyspatialite,
+#sid stretch jessie trusty utopic vivid wily# python-pyspatialite,
  libqgispython{QGIS_ABI},
  ${shlibs:Depends},
  ${python:Depends},
@@ -401,13 +419,13 @@ Description: QGIS API documentation
  .
  This package contains the QGIS API documentation.
 
-#sid-oracle#Package: qgis-oracle-provider
-#sid-oracle#Architecture: any
-#sid-oracle#Depends: ${shlibs:Depends}, ${misc:Depends}
-#sid-oracle#Section: contrib/database
-#sid-oracle#Description: QGIS oracle provider
-#sid-oracle# QGIS is a Geographic Information System (GIS) which manages, analyzes and
-#sid-oracle# display databases of geographic information.
-#sid-oracle# .
-#sid-oracle# This package contains the QGIS oracle provider.
-#sid-oracle#
+#oracle#Package: qgis-oracle-provider
+#oracle#Architecture: any
+#oracle#Depends: ${shlibs:Depends}, ${misc:Depends}
+#oracle#Section: contrib/database
+#oracle#Description: QGIS oracle provider
+#oracle# QGIS is a Geographic Information System (GIS) which manages, analyzes and
+#oracle# display databases of geographic information.
+#oracle# .
+#oracle# This package contains the QGIS oracle provider.
+#oracle#
diff --git a/debian/qgis-plugin-grass.install.in b/debian/qgis-plugin-grass.install.in
index 31475de..f8f712a 100644
--- a/debian/qgis-plugin-grass.install.in
+++ b/debian/qgis-plugin-grass.install.in
@@ -1,6 +1,2 @@
-usr/lib/qgis/grass/modules/qgis.d.rast
-usr/lib/qgis/grass/modules/qgis.g.info
 usr/lib/qgis/grass/bin/qgis.g.browser
 usr/lib/qgis/plugins/libgrassplugin.so
-usr/lib/qgis/plugins/libgrassprovider.so
-usr/lib/qgis/plugins/libgrassrasterprovider.so
diff --git a/debian/qgis-plugin-grass.postrm b/debian/qgis-plugin-grass.postrm
deleted file mode 100755
index a38bf8c..0000000
--- a/debian/qgis-plugin-grass.postrm
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ "$1" = "remove" ]; then
-	dpkg-divert --package qgis-plugin-grass --remove --rename --divert /usr/bin/qgis.bin /usr/bin/qgis
-	dpkg-divert --package qgis-plugin-grass --remove --rename --divert /usr/bin/qbrowser.bin /usr/bin/qbrowser
-fi
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/qgis-plugin-grass.preinst b/debian/qgis-plugin-grass.preinst
deleted file mode 100755
index 2f875ba..0000000
--- a/debian/qgis-plugin-grass.preinst
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ "$1" = "install" -o "$1" = "upgrade" ]; then
-	dpkg-divert --package qgis-plugin-grass --add --rename --divert /usr/bin/qgis.bin /usr/bin/qgis
-	dpkg-divert --package qgis-plugin-grass --add --rename --divert /usr/bin/qbrowser.bin /usr/bin/qbrowser
-fi
-
-#DEBHELPER#
-
-exit 0
-
diff --git a/debian/qgis-plugin-grass.install.in b/debian/qgis-provider-grass.install.in
similarity index 68%
copy from debian/qgis-plugin-grass.install.in
copy to debian/qgis-provider-grass.install.in
index 31475de..7ca434b 100644
--- a/debian/qgis-plugin-grass.install.in
+++ b/debian/qgis-provider-grass.install.in
@@ -1,6 +1,4 @@
 usr/lib/qgis/grass/modules/qgis.d.rast
 usr/lib/qgis/grass/modules/qgis.g.info
-usr/lib/qgis/grass/bin/qgis.g.browser
-usr/lib/qgis/plugins/libgrassplugin.so
 usr/lib/qgis/plugins/libgrassprovider.so
 usr/lib/qgis/plugins/libgrassrasterprovider.so
diff --git a/debian/qgis-provider-grass.lintian-overrides b/debian/qgis-provider-grass.lintian-overrides
new file mode 100644
index 0000000..d830446
--- /dev/null
+++ b/debian/qgis-provider-grass.lintian-overrides
@@ -0,0 +1,2 @@
+qgis-plugin-grass: package-name-doesnt-match-sonames
+qgis-plugin-grass: no-symbols-control-file
diff --git a/debian/qgis-provider-grass.postrm b/debian/qgis-provider-grass.postrm
new file mode 100755
index 0000000..262da20
--- /dev/null
+++ b/debian/qgis-provider-grass.postrm
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+if [ "$1" = "remove" ]; then
+	dpkg-divert --package qgis-provider-grass --remove --rename --divert /usr/bin/qgis.bin /usr/bin/qgis
+	dpkg-divert --package qgis-provider-grass --remove --rename --divert /usr/bin/qbrowser.bin /usr/bin/qbrowser
+fi
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/qgis-provider-grass.preinst b/debian/qgis-provider-grass.preinst
new file mode 100755
index 0000000..2c4be4f
--- /dev/null
+++ b/debian/qgis-provider-grass.preinst
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+if [ "$1" = "install" -o "$1" = "upgrade" ]; then
+	dpkg-divert --package qgis-provider-grass --add --rename --divert /usr/bin/qgis.bin /usr/bin/qgis
+	dpkg-divert --package qgis-provider-grass --add --rename --divert /usr/bin/qbrowser.bin /usr/bin/qbrowser
+fi
+
+#DEBHELPER#
+
+exit 0
+
diff --git a/debian/rules b/debian/rules
index 038b456..db9dfa2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -16,6 +16,7 @@ DEB_BUILD_MULTIARCH ?= $(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)
 QT_PLUGIN_DIR = usr/lib/$(DEB_BUILD_MULTIARCH)/qt4/plugins
 
 DEB_TEST_TARGET ?= Experimental
+BUILDDIR ?= debian/build
 
 QGIS_VERSION=$(shell dpkg-parsechangelog | sed -ne 's/^Version: \(.*\)-.*/\1/p')
 
@@ -23,7 +24,12 @@ ifeq (,$(DISTRIBUTION))
 	DISTRIBUTION := $(shell dpkg-parsechangelog --format rfc822 | sed -ne "s/^Distribution: //p")
 endif
 
-ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"wheezy jessie precise trusty utopic vivid sid-oracle"))
+ifneq (,$(findstring -oracle,$(DISTRIBUTION)))
+	DISTRIBUTION := $(subst -oracle,,$(DISTRIBUTION))
+	WITH_ORACLE=1
+endif
+
+ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"wheezy jessie stretch precise trusty utopic vivid wily"))
 	DISTRIBUTION := sid
 endif
 
@@ -40,12 +46,12 @@ QGIS_MINOR=$(shell sed -ne 's/SET(CPACK_PACKAGE_VERSION_MINOR "\([0-9]*\)")/\1/p
 QGIS_PATCH=$(shell sed -ne 's/SET(CPACK_PACKAGE_VERSION_PATCH "\([0-9]*\)")/\1/p' CMakeLists.txt)
 QGIS_ABI=$(QGIS_MAJOR).$(QGIS_MINOR).$(QGIS_PATCH)
 GRASS=grass$(subst .,,$(shell pkg-config --modversion grass|cut -d. -f1,2))
+GRASSVER=$(subst .,,$(shell pkg-config --modversion grass|cut -d. -f1))
 
 CMAKE_OPTS := \
 	-DBUILDNAME=$(DEB_BUILD_NAME) \
 	-DCMAKE_VERBOSE_MAKEFILE=1 \
 	-DCMAKE_INSTALL_PREFIX=/usr \
-	-DGRASS_PREFIX=/usr/lib/$(GRASS) \
 	-DBINDINGS_GLOBAL_INSTALL=TRUE \
 	-DPEDANTIC=TRUE \
 	-DWITH_QSPATIALITE=TRUE \
@@ -62,7 +68,9 @@ CMAKE_OPTS := \
 	-DWITH_INTERNAL_PYGMENTS=FALSE \
 	-DWITH_INTERNAL_DATEUTIL=FALSE \
 	-DWITH_INTERNAL_PYTZ=FALSE \
-	-DWITH_INTERNAL_SIX=FALSE
+	-DWITH_INTERNAL_SIX=FALSE \
+	-DWITH_GRASS=TRUE \
+	-DGRASS_PREFIX=/usr/lib/$(GRASS)
 
 ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
 	NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
@@ -73,11 +81,15 @@ ifneq (,$(findstring $(DISTRIBUTION),"wheezy jessie sid precise"))
 	CMAKE_OPTS += -DWITH_PYSPATIALITE=TRUE
 endif
 
-ifneq (,$(findstring $(DISTRIBUTION),"sid sid-oracle"))
+ifneq (,$(findstring $(DISTRIBUTION),"sid stretch"))
 	CMAKE_OPTS += -DPOSTGRES_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libpq.so
 endif
 
-ifneq (,$(findstring $(DISTRIBUTION),"jessie trusty utopic vivid sid sid-oracle"))
+ifneq (,$(findstring $(DISTRIBUTION),"sid"))
+	CMAKE_OPTS += -DGEOS_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libgeos_c.so
+endif
+
+ifneq (,$(findstring $(DISTRIBUTION),"jessie stretch trusty utopic vivid wily sid"))
 	CMAKE_OPTS += -DPYTHON_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libpython2.7.so
 endif
 
@@ -85,7 +97,7 @@ ifneq (,$(findstring -oracle,$(DISTRIBUTION)))
 	CMAKE_OPTS += -DWITH_ORACLE=TRUE
 endif
 
-ifneq (,$(findstring $(DISTRIBUTION),"sid"))
+ifneq (,$(findstring $(DISTRIBUTION),"sid stretch jessie"))
 	CMAKE_OPTS += -DSPATIALINDEX_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libspatialindex.so
 endif
 
@@ -102,7 +114,7 @@ else
 	CMAKE_OPTS += -DENABLE_TESTS=TRUE
 endif
 
-ifneq (,$(findstring $(DISTRIBUTION),"wheezy jessie trusty sid sid-oracle"))
+ifneq (,$(findstring $(DISTRIBUTION),"wheezy jessie stretch trusty sid"))
 CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS)
 CFLAGS   := $(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS)
 CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS)
@@ -127,15 +139,30 @@ ifneq (,$(findstring profile,$(DEB_BUILD_OPTIONS)))
 	LDFLAGS += -pg
 endif
 
+# multi distribution support:
+# - remove lines with applicable excludes
+# - remove prefixes with applicable includes
+# - remove prefixes with not applicable excludes
+# - remove remaining comments
+
+CONTROL_EXPRESSIONS = $(DISTRIBUTION) grass$(GRASSVER)
+
+ifneq (,$(WITH_ORACLE))
+	CONTROL_EXPRESSIONS += oracle
+endif
+
 define gentemplate
 $(2): $(1)
 	sed -r \
-		-e 's/^#(.* |)$(DISTRIBUTION)( .*|)#//' \
-		-e '/^#($|[^!])/d' \
+		-e '/#(.+ |)!($(subst $(eval) ,|,$(CONTROL_EXPRESSIONS)))( .+|)#/d' \
+		-e 's/#([^#]+ |)($(subst $(eval) ,|,$(CONTROL_EXPRESSIONS)))( [^#]+|)#//g' \
+		-e 's/#([^#]+ |)![^#]+( [^#]*|)#//g' \
+		-e '/^#/d' \
 		-e "s/\{DEB_BUILD_GNU_TYPE\}/$(DEB_BUILD_GNU_TYPE)/g" \
 		-e "s#\{QT_PLUGIN_DIR\}#$(QT_PLUGIN_DIR)#g" \
 		-e "s/\{QGIS_ABI\}/$(QGIS_ABI)/g" \
 		-e "s/\{GRASS\}/$(GRASS)/g" \
+		-e "s/\{GRASSVER\}/$(GRASSVER)/g" \
 		$$^ >$$@
 
 templates:: $(2)
@@ -152,7 +179,7 @@ cleantemplates:
 	$(MAKE) -f debian/rules debian/control debian/compat
 
 binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep:
-	dh $@ --with python2 --parallel --builddirectory=debian/build
+	dh $@ --with python2 --parallel --builddirectory=$(BUILDDIR)
 
 override_dh_clean: cleantemplates
 	dh_clean
@@ -161,7 +188,7 @@ override_dh_clean: cleantemplates
 	-$(RM) $(CURDIR)/src/core/qgscontexthelp_texts.cpp
 	-$(RM) $(CURDIR)/src/core/qgsexpression_texts.cpp
 
-	-$(RM) -r $(CURDIR)/debian/build/
+	-$(RM) -r $(CURDIR)/$(BUILDDIR)/
 
 override_dh_auto_configure: templates
 	dh_auto_configure -- $(CMAKE_OPTS)
@@ -173,9 +200,9 @@ override_dh_auto_test:
 	localedef -f UTF-8 -i en_US ./debian/tmp/locale/en_US.UTF-8/
 	-LOCPATH=$(CURDIR)/debian/tmp/locale/ \
 	LC_ALL=en_US.UTF-8 \
-	LD_LIBRARY_PATH=$(CURDIR)/debian/build/output/lib:$(LD_LIBRARY_PATH) \
+	LD_LIBRARY_PATH=$(CURDIR)/$(BUILDDIR)/output/lib:$(LD_LIBRARY_PATH) \
 	PATH=/usr/sbin:$(PATH) \
-	$(TESTMAKE) -C debian/build $(DEB_TEST_TARGET)
+	$(TESTMAKE) -C $(BUILDDIR) $(DEB_TEST_TARGET)
 else
 override_dh_auto_test:
 	@echo Skipping tests.
@@ -221,9 +248,9 @@ override_dh_auto_install:
 	$(RM) $(CURDIR)/debian/tmp/usr/bin/qbrowser
 
 	# qgis binary wrappers
-	install -o root -g root -m 755 -d $(CURDIR)/debian/qgis-plugin-grass/usr/bin
-	install -o root -g root -m 755 $(CURDIR)/debian/qgis.sh $(CURDIR)/debian/qgis-plugin-grass/usr/bin/qgis
-	install -o root -g root -m 755 $(CURDIR)/debian/qgis.sh $(CURDIR)/debian/qgis-plugin-grass/usr/bin/qbrowser
+	install -o root -g root -m 755 -d $(CURDIR)/debian/qgis-provider-grass/usr/bin
+	install -o root -g root -m 755 $(CURDIR)/debian/qgis.sh $(CURDIR)/debian/qgis-provider-grass/usr/bin/qgis
+	install -o root -g root -m 755 $(CURDIR)/debian/qgis.sh $(CURDIR)/debian/qgis-provider-grass/usr/bin/qbrowser
 
 override_dh_install:
 	# Don't ship srs.db, automatically updated in postinst with crssync
diff --git a/i18n/qgis_ar.ts b/i18n/qgis_ar.ts
index 147f462..5d5bdf8 100644
--- a/i18n/qgis_ar.ts
+++ b/i18n/qgis_ar.ts
@@ -45653,7 +45653,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_bs.ts b/i18n/qgis_bs.ts
index 2c29e8a..2db3f5c 100644
--- a/i18n/qgis_bs.ts
+++ b/i18n/qgis_bs.ts
@@ -45767,7 +45767,7 @@ Problem je sa vašom bazom podataka simbola.</translation>
         <translation>Povezano iscrtavanje presijecanja polilinija</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_ca.ts b/i18n/qgis_ca.ts
index 970d85d..cc5c968 100644
--- a/i18n/qgis_ca.ts
+++ b/i18n/qgis_ca.ts
@@ -45395,7 +45395,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_cs.ts b/i18n/qgis_cs.ts
index c13bbad..265dced 100644
--- a/i18n/qgis_cs.ts
+++ b/i18n/qgis_cs.ts
@@ -45724,7 +45724,7 @@ There was a problem with your symbol database.</source>
         <translation>Spojte protnuté multilinie při vykreslování</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_da.ts b/i18n/qgis_da.ts
index 724a313..fbc2783 100644
--- a/i18n/qgis_da.ts
+++ b/i18n/qgis_da.ts
@@ -45827,7 +45827,7 @@ Der var et problem med til din symboldatabase.</translation>
         <translation>Join skærende polylinjer under udtegning</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Hvis du behøver hjælp med at bruge QGIS, har vi en 'users'-mailingliste, hvor brugere hjælper hinanden med problemer relateret til brugen af vores software. Vi har også en 'developers'-mailingliste for dem, som vil hjælpe og diskutere ting relateret til QGIS-kodebasen. Detaljer om, hvordan du abonnerer er i <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> på QGIS-hjemmesiden.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_de.ts b/i18n/qgis_de.ts
index 37bf8e6..38a2be3 100644
--- a/i18n/qgis_de.ts
+++ b/i18n/qgis_de.ts
@@ -46284,7 +46284,7 @@ Es gab ein Problem mit Ihrer Symboldatenbank.</translation>
         <translation>Kreuzenden Polylinen beim Zeichnen verbinden</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Wenn Sie Hilfe bei der Benutzung von QGIS brauchen, gibt es eine englische Anwender-Mailingliste, wo die Anwender sich gegenseitig helfen können. Wir haben außerdem eine englische Entwickler-Mailingliste, auf der über die Codebasis diskutiert werden kann.  Details zum Abonnement stehen in der Abteilung <a href="http://qgis.org/de/site/forusers/support.html#mailing-lists">Gemeinschaft</a> auf der QGIS-Homepage.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_el.ts b/i18n/qgis_el.ts
index 8ff3ccc..1fbc74d 100644
--- a/i18n/qgis_el.ts
+++ b/i18n/qgis_el.ts
@@ -45353,7 +45353,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_en.ts b/i18n/qgis_en.ts
index 226a7ef..541e230 100644
--- a/i18n/qgis_en.ts
+++ b/i18n/qgis_en.ts
@@ -46303,8 +46303,8 @@ There was a problem with your symbol database.</translation>
         <translation>Join intersected polylines when rendering</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
-        <translation>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</translation>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <translation>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</translation>
     </message>
     <message>
         <source>Both used to be correct, but we recently decided to just use 'QGIS'. For articles we suggest you write 'QGIS is ....'</source>
diff --git a/i18n/qgis_es.ts b/i18n/qgis_es.ts
index e4b26d4..a7df706 100644
--- a/i18n/qgis_es.ts
+++ b/i18n/qgis_es.ts
@@ -45855,7 +45855,7 @@ Hubo un problema con su base de datos de símbolos.</translation>
         <translation>Unir polilíneas que intersectan al dibujar</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Si necesita ayuda al usar QGIS tenemos una lista de correo de 'usuarios'en la que los usuarios se ayudan con asuntos relacionados con el uso de nuestro software. También tenemos una lista de correo de 'desarrolladores'. para aquellos que quieran ayudar y para debatir cosas relacionadas con el código base de QGIS. Los detalles para suscribirse se encuentran en la <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists"> [...]
     </message>
     <message>
diff --git a/i18n/qgis_et.ts b/i18n/qgis_et.ts
index d89f50d..6ca21a1 100644
--- a/i18n/qgis_et.ts
+++ b/i18n/qgis_et.ts
@@ -45590,7 +45590,7 @@ Täpse asukoha määramiseks kasuta <strong>Asukoht ja Suurus Size</str
         <translation>Ühenda lõikuvad jooned renderdamise ajal</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_eu.ts b/i18n/qgis_eu.ts
index cb4dd23..964e218 100644
--- a/i18n/qgis_eu.ts
+++ b/i18n/qgis_eu.ts
@@ -45795,7 +45795,7 @@ Arazo bat dago zure ikurren datu-basearekin.</translation>
         <translation>Elkartu ebakitzen polilerroak haiek errendatzean</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>QGIS erabiltzeko laguntza behar baduzu, erabiltzaileek gure softwarearen inguruko auziekin elkarri laguntzeko darabilten 'erabiltzaileen' posta-zerrenda bat dugu. 'Garatzaileen' posta-zerrenda bat ere baduzu, QGISen kodeari buruzko kontuak eztabaidatzeko. Zerrendotan izena emateko xehetasunak QGISen webgunearen <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">komunitatearen atalean</a> aurki ditzakezu.</t [...]
     </message>
     <message>
diff --git a/i18n/qgis_fa.ts b/i18n/qgis_fa.ts
index bf81b62..17201e1 100644
--- a/i18n/qgis_fa.ts
+++ b/i18n/qgis_fa.ts
@@ -45358,7 +45358,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_fi.ts b/i18n/qgis_fi.ts
index 42325f9..530806d 100644
--- a/i18n/qgis_fi.ts
+++ b/i18n/qgis_fi.ts
@@ -45855,7 +45855,7 @@ Symbolien tietokannassa oli ongelma.</translation>
         <translation>Liitä leikkaavat viivat hahmotettaessa</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Jos tarvitset apua QGIS käytössä, on meillä 'käyttäjien' sähköpostilista jossa käyttäjä auttavat toinen toisiaan erilaisissa ohjelmistoon liittyvissä asioissa. Meillä on myös 'kehittäjien' lista, niille jotka haluavat auttaa kehitystyössä ja keskustella erilaisista seikoista jotka liittyvät itse QGIS koodiin. Yksityiskohdat kuinka liittyä löytyvät <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">yhteisö osasta& [...]
     </message>
     <message>
diff --git a/i18n/qgis_fr.ts b/i18n/qgis_fr.ts
index aa96574..78856e2 100644
--- a/i18n/qgis_fr.ts
+++ b/i18n/qgis_fr.ts
@@ -45809,7 +45809,7 @@ Il y a un problème avec votre base de symboles.</translation>
         <translation>Joindre des lignes qui se croisent</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Si vous avez besoin d'aide pour QGIS, nous disposons d'une liste de diffusion «utilisateurs» pour les questions relatives à l'utilisation du logiciel. Nous avons aussi une liste de diffusion «développeurs». pour ceux qui cherchent de l'aide ou qui veulent discuter de sujets relatifs au code source de QGIS. Les modalités d'abonnement sont décrites dans la <a href="http://qgis.org/fr/site/forusers/support.html#mailing-lists"> se [...]
     </message>
     <message>
diff --git a/i18n/qgis_gl.ts b/i18n/qgis_gl.ts
index 0796cb6..01c7830 100644
--- a/i18n/qgis_gl.ts
+++ b/i18n/qgis_gl.ts
@@ -45866,7 +45866,7 @@ Houbo un problema coa base de datos de símbolos.</translation>
         <translation>Xuntar poliliñas intersectadas cando se renderiza</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Se necesita axuda con QGIS existe unha lista de correo de 'usuarios' onde os usuarios axúdanse uns ós outros con temas relacionados coa utilización deste software. Existe tamén unha lista de correo de 'desarrolladores' para aqueles que busquen axuda e para discutir cousas relacionadas co código base de QGIS. Hai detalles de como subscribirse na <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">sección da comunid [...]
     </message>
     <message>
diff --git a/i18n/qgis_hi.ts b/i18n/qgis_hi.ts
index 277eaae..2eec8d8 100644
--- a/i18n/qgis_hi.ts
+++ b/i18n/qgis_hi.ts
@@ -45705,7 +45705,7 @@ There was a problem with your symbol database.</source>
         <translation>प्र‍स्‍तुतिकरण के दौरान प्रतिच्‍छेदित बहुरेखाओं को शामिल करें </translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_hr.ts b/i18n/qgis_hr.ts
index 80be602..aa6255d 100644
--- a/i18n/qgis_hr.ts
+++ b/i18n/qgis_hr.ts
@@ -45541,7 +45541,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_hu.ts b/i18n/qgis_hu.ts
index 2eb1420..160dde1 100644
--- a/i18n/qgis_hu.ts
+++ b/i18n/qgis_hu.ts
@@ -45729,7 +45729,7 @@ Probléma volt a szimbólum adatbázisoddal.</translation>
         <translation>Metsző törtvonalak összekapcsolása rajzolás közben</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Van egy felhasználói levelező listánk, ha segítségre lenne szükséged, ahol a felhasználók a szoftver használattal kapcsolatos kérdésekben segítenek egymásnak. Van egy fejlesztői levelező listánk is azoknak akiknek a QGIS forráskódjával kapcsolatban van szüksége segítségre. A listákra feliratkozás részletei a <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> részben találhatók a QGIS honlapon.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_id.ts b/i18n/qgis_id.ts
index b328ddf..fadadcb 100644
--- a/i18n/qgis_id.ts
+++ b/i18n/qgis_id.ts
@@ -45735,7 +45735,7 @@ Ada masalah dengan basisdata simbol Anda.</translation>
         <translation>Menggabung polylines berpotongan saat rendering</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_is.ts b/i18n/qgis_is.ts
index d84a360..bd1780d 100644
--- a/i18n/qgis_is.ts
+++ b/i18n/qgis_is.ts
@@ -45371,7 +45371,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_it.ts b/i18n/qgis_it.ts
index 41972f3..c267b27 100644
--- a/i18n/qgis_it.ts
+++ b/i18n/qgis_it.ts
@@ -45876,7 +45876,7 @@ C'è stato un problema con il tuo database dei simboli.</translation>
         <translation>Unisci le intersezioni di polilinee durante lavisualizzazione</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Se hai bisogno di qualche aiuto nell'uso di QGIS esiste una mailing list dove ognuno aiuta l'altro in merito a problemi relativi all'uso del software. Inoltre esiste anche una mailing list degli sviluppatori se sei interessato ad aiuti o contributi in merito al codice di QGIS. Dettagli su come scriver in lista sono in <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">sezione communità</a>.  </translation>
     </message>
     <message>
diff --git a/i18n/qgis_ja.ts b/i18n/qgis_ja.ts
index cf65c49..a2db853 100644
--- a/i18n/qgis_ja.ts
+++ b/i18n/qgis_ja.ts
@@ -46136,7 +46136,7 @@ There was a problem with your symbol database.</source>
         <translation>レンダリング時に交差しているポリラインを結合する</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>もしあなたがQGISを使うのに助けが必要な場合はユーザ同士でこのソフトウェアの利用について助け合う'user'メーリングリストがあります.私たちは'developers'メーリングリストも持っています.そこではQGISのプログラムコードをベースにした論議が行われています.メーリングリストへの参加方法の詳細はQGISホームページの<a href="http://qgis.org/ja/site/forusers/support.html#mailing-lists">コミュニティセクション</a>を参照して下さい.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_km.ts b/i18n/qgis_km.ts
index 9a5435b..2b84794 100644
--- a/i18n/qgis_km.ts
+++ b/i18n/qgis_km.ts
@@ -45633,7 +45633,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_ko.ts b/i18n/qgis_ko.ts
index 68ed9ab..983cef1 100644
--- a/i18n/qgis_ko.ts
+++ b/i18n/qgis_ko.ts
@@ -45793,7 +45793,7 @@ There was a problem with your symbol database.</source>
         <translation>렌더링시 교차하는 폴리라인 결합</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>만약 QGIS를 사용하시는데 도움이 필요하시다면, '사용자' 메일링 리스트를 이용해 보십시요. 여기에서 사용중 발생한 이슈를 서로 주고 받으며 서로를 돕고 있습니다. 또 '개발자' 메일링 리스트도 있습니다. 여기에선 QGIS 코드와 관련된 도움과 토론을 기다립니다. 상세한 가입 방법은 QGIS 홈페이지의 <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">커뮤니티 섹션</a>에 있습니다.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_lt.ts b/i18n/qgis_lt.ts
index 8a857b3..dcffcbc 100644
--- a/i18n/qgis_lt.ts
+++ b/i18n/qgis_lt.ts
@@ -45728,7 +45728,7 @@ Buvo klaidų su jūsų simbolių duombaze.</translation>
         <translation>Vaizduojant sujungti persidengiančias polilinijas</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_lv.ts b/i18n/qgis_lv.ts
index feeb871..33755b0 100644
--- a/i18n/qgis_lv.ts
+++ b/i18n/qgis_lv.ts
@@ -45494,7 +45494,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_mn.ts b/i18n/qgis_mn.ts
index 2b2e8f5..7fbcb79 100644
--- a/i18n/qgis_mn.ts
+++ b/i18n/qgis_mn.ts
@@ -45338,7 +45338,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_nb.ts b/i18n/qgis_nb.ts
index d5b004b..fdba15a 100644
--- a/i18n/qgis_nb.ts
+++ b/i18n/qgis_nb.ts
@@ -45860,7 +45860,7 @@ Det oppsto et problem med din symboldatabase.</translation>
         <translation>Foren kryssende polylinjer under opptegning</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Hvis du trenger hjelp til å bruke QGIS har vi en 'bruker' e-postliste hvor brukere hjelper hverandre med problemstillinger relatert til å bruke vår programvare. Vi har også en 'utvikler' e-postliste for de som vil hjelpe og til å diskutere ting relatert til QGIS kodebase. Detaljer om hvordan du melder deg på finner du i  <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> på QGIS hjemme [...]
     </message>
     <message>
diff --git a/i18n/qgis_nl.ts b/i18n/qgis_nl.ts
index dc62077..3dc8e54 100644
--- a/i18n/qgis_nl.ts
+++ b/i18n/qgis_nl.ts
@@ -45830,7 +45830,7 @@ m elementen te verplaatsen. De linker (pijl naar rechts icoon) selecteert en ver
         <translation>Versmelt samenvallende lijnen bij het renderen</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Indien u hulp nodig heeft bij het gebruiken van QGIS, dan bestaat er de (Engelstalige) mailinglijst 'users' waar gebruikers elkaar helpen bij het vinden van oplossingen voor problemen met het gebruiken van onze software. Er bestaat ook een mailinglijst 'developers' voor hen die willen helpen en dingen willen bespreken in relatie tot de  codebasis van QGIS. Details over hoe u zich kunt abonneren staan in het gedeelte <a href="http://qgis.or [...]
     </message>
     <message>
diff --git a/i18n/qgis_pl.ts b/i18n/qgis_pl.ts
index 61a0cbf..03a48aa 100644
--- a/i18n/qgis_pl.ts
+++ b/i18n/qgis_pl.ts
@@ -45848,7 +45848,7 @@ Im niższy numer, tym wcześniej rysowana jest warstwa.</translation>
         <translation>Przenikanie przecinających się linii</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Jeśli potrzebujesz pomocy przy korzystaniu z QGIS, możesz skorzystać z listy dyskusyjnej użytkowników (users), gdzie użytkownicy pomagają sobie wzajemnie rozwiązać problemy, które napotykają w czasie pracy z naszą aplikacją. Mamy też listę dyskusyjną programistów (developers) dla tych, którzy potrzebują pomocy związanej z kodem źródłowym QGIS. O tym, jak zapisać się na te listy przeczytasz w <a href="http://qgis.org/pl/site/forusers/support.html#mailing-lists [...]
 Dla osób szukających pomocy w języku polskim, uruchomione zostało <a href="http://forum.quantum-gis.pl/">forum dyskusyjne</a> pod adresem (http://forum.quantum-gis.pl/).</translation>
     </message>
diff --git a/i18n/qgis_pt_BR.ts b/i18n/qgis_pt_BR.ts
index 86ebce5..eb787e2 100644
--- a/i18n/qgis_pt_BR.ts
+++ b/i18n/qgis_pt_BR.ts
@@ -45821,7 +45821,7 @@ Houve um problema com o seu banco de dados de simbologias.</translation>
         <translation>Unir polilinhas cruzadas ao renderizar</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Se necessita de ajuda quando usa o QGIS nós temos lista de discussão para 'utilizadores' onde utilizadores ajudam-se mutuamente na resolução de problemas associados ao nosso software. Nós também tempo uma lista de discussão de 'programadores', para aqueles que querem discutir e ajudar em temas relacionados com o código base do QGIS. Os detalhes de como subscrever estão em <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists [...]
     </message>
     <message>
diff --git a/i18n/qgis_pt_PT.ts b/i18n/qgis_pt_PT.ts
index e01f428..e8edf17 100644
--- a/i18n/qgis_pt_PT.ts
+++ b/i18n/qgis_pt_PT.ts
@@ -45825,7 +45825,7 @@ Foi detectado um problema com a sua base de dados de símbolo.</translation>
         <translation>Unir polilinhas que se interceptam quando renderizar</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Se necessita de ajuda quando usa o QGIS nós temos lista de discussão para 'utilizadores' onde utilizadores ajudam-se mutuamente na resolução de problemas associados ao nosso software. Nós também tempo uma lista de discussão de 'programadores', para aqueles que querem discutir e ajudar em temas relacionados com o código base do QGIS. Os detalhes de como subscrever estão em <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists [...]
     </message>
     <message>
diff --git a/i18n/qgis_ro.ts b/i18n/qgis_ro.ts
index 8e4ecc0..58290b0 100644
--- a/i18n/qgis_ro.ts
+++ b/i18n/qgis_ro.ts
@@ -45850,7 +45850,7 @@ A apărut o problemă cu baza de date a simbolurilor.</translation>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_ru.ts b/i18n/qgis_ru.ts
index 5974266..bd51ad6 100644
--- a/i18n/qgis_ru.ts
+++ b/i18n/qgis_ru.ts
@@ -45763,7 +45763,7 @@ There was a problem with your symbol database.</source>
         <translation>Объединённая заливка полилиний</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_sk.ts b/i18n/qgis_sk.ts
index 241d10e..4b436a6 100644
--- a/i18n/qgis_sk.ts
+++ b/i18n/qgis_sk.ts
@@ -45512,7 +45512,7 @@ Nastal problém s Vašou databázou symbolov.</translation>
         <translation>Spojte pretínajúce sa multilínie pri vykresľovaní</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_sl.ts b/i18n/qgis_sl.ts
index d127bea..5184c39 100644
--- a/i18n/qgis_sl.ts
+++ b/i18n/qgis_sl.ts
@@ -45623,7 +45623,7 @@ There was a problem with your symbol database.</source>
         <translation>Združevanje presekanih linij ob izrisu</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_sr.ts b/i18n/qgis_sr.ts
index b1723d2..eea6fef 100644
--- a/i18n/qgis_sr.ts
+++ b/i18n/qgis_sr.ts
@@ -45503,7 +45503,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_sr at latin.ts b/i18n/qgis_sr at latin.ts
index db49936..e5bb4a2 100644
--- a/i18n/qgis_sr at latin.ts
+++ b/i18n/qgis_sr at latin.ts
@@ -45503,7 +45503,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_sv.ts b/i18n/qgis_sv.ts
index 4a8c7f7..1b35d5e 100644
--- a/i18n/qgis_sv.ts
+++ b/i18n/qgis_sv.ts
@@ -45817,7 +45817,7 @@ Det uppkom ett problem med din symboldatabas.</translation>
         <translation>Slå ihop linjer som korsar varandra vid rendering</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Om du behöver hjälp med att använda QGIS så har vi en användar-maillista där användare hjälper varandra med problem som rör vår programvara. Vi har även en 'utvecklar'-maillista för de som vill diskutera saker rörande QGIS kodbas. Närmare instruktioner om hur du anmäler dig till maillistan finns under <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> på QGIS hemsida.</translation>
     </message>
     <message>
diff --git a/i18n/qgis_th.ts b/i18n/qgis_th.ts
index 2a2a1ee..1a09c07 100644
--- a/i18n/qgis_th.ts
+++ b/i18n/qgis_th.ts
@@ -45416,7 +45416,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_tr.ts b/i18n/qgis_tr.ts
index 5979ff8..0ff4d2b 100644
--- a/i18n/qgis_tr.ts
+++ b/i18n/qgis_tr.ts
@@ -45351,7 +45351,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_uk.ts b/i18n/qgis_uk.ts
index 93906e3..bb848f5 100644
--- a/i18n/qgis_uk.ts
+++ b/i18n/qgis_uk.ts
@@ -45449,7 +45449,7 @@ There was a problem with your symbol database.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
diff --git a/i18n/qgis_vi.ts b/i18n/qgis_vi.ts
index 1e2e797..49217d1 100644
--- a/i18n/qgis_vi.ts
+++ b/i18n/qgis_vi.ts
@@ -45744,7 +45744,7 @@ Có trục trặc với CSDL biểu tượng của bạn.</translation>
         <translation>Kết hợp các đường giao nhau khi kết xuất</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>Nếu bạn cần trợ giúp về QGIS, chúng tôi có danh sách thư tín 'người dùng', là nơi người giúp đỡ lẫn nhau về những vấn đề liên quan đến phần mềm của chúng tôi. Chúng tôi cũng có một danh sách thư tín 'những nhà phát triển', dành cho những người nào muốn giúp đỡ và thảo luận về những vấn đề liên quan đến mã của QGIS. Chi tiết về việc đăng ký có trong <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">phần cộng đồng [...]
     </message>
     <message>
diff --git a/i18n/qgis_zh-Hans.ts b/i18n/qgis_zh-Hans.ts
index 6fe952c..27c5dc3 100644
--- a/i18n/qgis_zh-Hans.ts
+++ b/i18n/qgis_zh-Hans.ts
@@ -45779,7 +45779,7 @@ There was a problem with your symbol database.</source>
         <translation>渲染时连接相交的多边形</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>如果你在使用QGIS时需要帮助,我们有一个“用户(users)”邮件列表,用户们在这个邮件列表中就使用我们软件过程中遇到的问题相互帮助。我们也有一个“开发者”邮件列表,供那些想要帮助和讨论有关QGIS代码库的人讨论问题。如何订阅的细节都在QGIS主页的<a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">社区部分</a>。</translation>
     </message>
     <message>
diff --git a/i18n/qgis_zh_CN.ts b/i18n/qgis_zh_CN.ts
index aa13df2..faee4a5 100644
--- a/i18n/qgis_zh_CN.ts
+++ b/i18n/qgis_zh_CN.ts
@@ -45767,7 +45767,7 @@ There was a problem with your symbol database.</source>
         <translation>渲染时连接相交的多边形</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>如果你在使用QGIS时需要帮助,我们有一个“用户(users)”邮件列表,用户们在这个邮件列表中就使用我们软件过程中遇到的问题相互帮助。我们也有一个“开发者”邮件列表,供那些想要帮助和讨论有关QGIS代码库的人讨论问题。如何订阅的细节都在QGIS主页的<a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">社区部分</a>。</translation>
     </message>
     <message>
diff --git a/i18n/qgis_zh_TW.ts b/i18n/qgis_zh_TW.ts
index 5fdb2e2..7bae0e8 100644
--- a/i18n/qgis_zh_TW.ts
+++ b/i18n/qgis_zh_TW.ts
@@ -45763,7 +45763,7 @@ There was a problem with your symbol database.</source>
         <translation>渲染時連接相交的多邊形</translation>
     </message>
     <message>
-        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our sofware. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
+        <source>If you need help using QGIS we have a 'users' mailing list where users help each other with issues related to using our software. We also have a 'developers' mailing list. for those wanting help and to discuss things relating to the QGIS code base. Details on how to subscribe are in the <a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">community section</a> of the QGIS home page.</source>
         <translation>如果您在QGIS使用上有任何問題,我們有'使用者'郵寄列表,在郵件中我們會相互討論使用上的問題。我們也有'開發者'郵寄列表,給那些想要幫助與討論QGIS相關程式碼的人使用。詳細的訂閱資訊可以在QGIS首頁的<a href="http://qgis.org/en/site/forusers/support.html#mailing-lists">社群專區</a> 。</translation>
     </message>
     <message>
diff --git a/python/core/__init__.py b/python/core/__init__.py
index 159d4f0..881d349 100644
--- a/python/core/__init__.py
+++ b/python/core/__init__.py
@@ -1,6 +1,7 @@
 import inspect
 import string
 from qgis._core import *
+from PyQt4.QtCore import QCoreApplication
 
 def register_function(function, arg_count, group, usesgeometry=False, **kwargs):
     """
@@ -66,7 +67,10 @@ def register_function(function, arg_count, group, usesgeometry=False, **kwargs):
     register = kwargs.get('register', True)
     if register and QgsExpression.isFunctionName(name):
         if not QgsExpression.unregisterFunction(name):
-            raise TypeError("Unable to unregister function")
+            msgtitle = QCoreApplication.translate("UserExpressions", "User expressions")
+            msg = QCoreApplication.translate("UserExpressions", "The user expression {0} already exists and could not be unregistered.").format(name)
+            QgsMessageLog.logMessage(msg + "\n", msgtitle, QgsMessageLog.WARNING)
+            return None
 
     function.__name__ = name
     helptext = helptemplate.safe_substitute(name=name, doc=helptext)
diff --git a/python/core/qgsdistancearea.sip b/python/core/qgsdistancearea.sip
index d900748..64611e4 100644
--- a/python/core/qgsdistancearea.sip
+++ b/python/core/qgsdistancearea.sip
@@ -64,9 +64,23 @@ class QgsDistanceArea
     //! measures line
     double measureLine( const QList<QgsPoint>& points );
 
-    //! measures line with one segment
+    /** Measures length of line with one segment
+     * @param p1 start of line
+     * @param p2 end of line
+     * @returns distance in meters, or map units if cartesian calculation was performed
+     */
     double measureLine( const QgsPoint& p1, const QgsPoint& p2 );
 
+    /** Measures length of line with one segment and returns units of distance.
+     * @param p1 start of line
+     * @param p2 end of line
+     * @param units will be set to units of measure
+     * @returns calculated distance between points. Distance units are stored in units parameter.
+     * @note backported from QGIS 2.12 (where it is const)
+     * @note not available in python bindings
+     */
+    // double measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units );
+
     //! measures polygon area
     double measurePolygon( const QList<QgsPoint>& points );
 
diff --git a/python/core/qgserror.sip b/python/core/qgserror.sip
index 7d29cdc..8b4e99c 100644
--- a/python/core/qgserror.sip
+++ b/python/core/qgserror.sip
@@ -71,7 +71,7 @@ class QgsError
      */
     QString message( QgsErrorMessage::Format theFormat = QgsErrorMessage::Html ) const;
 
-    /** Short error descriprion, usually the first error in chain, the real error.
+    /** Short error description, usually the first error in chain, the real error.
      *  @return error description
      */
     QString summary() const;
diff --git a/python/core/qgsfeaturestore.sip b/python/core/qgsfeaturestore.sip
index 80dd8b6..39c1535 100644
--- a/python/core/qgsfeaturestore.sip
+++ b/python/core/qgsfeaturestore.sip
@@ -19,7 +19,7 @@ class QgsFeatureStore
     /** Get fields list */
     QgsFields& fields();
 
-    /** Set fields. Resets feauters fields to pointer to new internal fields. */
+    /** Set fields. Resets feature's fields to pointer to new internal fields. */
     void setFields( const QgsFields & fields );
 
     /** Get crs */
diff --git a/python/core/qgsfield.sip b/python/core/qgsfield.sip
index d5d5ac7..1b26e92 100644
--- a/python/core/qgsfield.sip
+++ b/python/core/qgsfield.sip
@@ -14,7 +14,7 @@ class QgsField
 #include <qgsfield.h>
 %End
 
-public:
+  public:
     /** Constructor. Constructs a new QgsField object.
      * @param name Field name
      * @param type Field variant type, currently supported: String / Int / Double
@@ -171,6 +171,14 @@ public:
 }; // class QgsField
 
 
+/**
+ \ingroup core
+ Container of fields for a vector layer.
+
+ In addition to storing a list of QgsField instances, it also:
+ - allows quick lookups of field names to index in the list
+ - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
+ */
 
 class QgsFields
 {
@@ -192,6 +200,8 @@ class QgsFields
     void clear();
     //! Append a field. The field must have unique name, otherwise it is rejected (returns false)
     bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
+    //! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
+    bool appendExpressionField( const QgsField& field, int originIndex );
     //! Remove a field with the given index
     void remove( int fieldIdx );
     //! Extend with fields from another QgsFields container
@@ -240,8 +250,8 @@ class QgsFields
     //! Look up field's index from name. Returns -1 on error
     int indexFromName( const QString& name ) const;
 
-    //! Look up field's index from name - case insensitive
-    //! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
+    //! Look up field's index from name
+    //! also looks up case-insensitive if there is no match otherwise
     //! @note added in 2.4
     int fieldNameIndex( const QString& fieldName ) const;
 
diff --git a/python/core/qgsmapunitscale.sip b/python/core/qgsmapunitscale.sip
index c0d63b4..24ed908 100644
--- a/python/core/qgsmapunitscale.sip
+++ b/python/core/qgsmapunitscale.sip
@@ -13,13 +13,25 @@ class QgsMapUnitScale
 #include <qgsmapunitscale.h>
 %End
   public:
-    QgsMapUnitScale();
-    QgsMapUnitScale( float _minScale, float _maxScale );
+
+    /** Constructor for QgsMapUnitScale
+     * @param minScale minimum allowed scale, or 0.0 if no minimum scale set
+     * @param maxScale maximum allowed scale, or 0.0 if no maximum scale set
+     */
+    QgsMapUnitScale( double minScale = 0.0, double maxScale = 0.0 );
 
     /** The minimum scale, or 0.0 if unset */
     double minScale;
     /** The maximum scale, or 0.0 if unset */
     double maxScale;
 
+    /** Computes a map units per pixel scaling factor, respecting the minimum and maximum scales
+     * set for the object.
+     * @param c render context
+     * @returns map units per pixel, limited between minimum and maximum scales
+     */
     double computeMapUnitsPerPixel( const QgsRenderContext& c ) const;
+
+    bool operator==( const QgsMapUnitScale& other ) const;
+    bool operator!=( const QgsMapUnitScale& other ) const;
 };
diff --git a/python/core/qgsvectorlayer.sip b/python/core/qgsvectorlayer.sip
index 90c9df3..0a73d91 100644
--- a/python/core/qgsvectorlayer.sip
+++ b/python/core/qgsvectorlayer.sip
@@ -595,7 +595,9 @@ class QgsVectorLayer : QgsMapLayer
      */
     bool deleteSelectedFeatures( int *deletedCount = 0 );
 
-    /**Adds a ring to polygon/multipolygon features
+    /** Adds a ring to polygon/multipolygon features
+     * @param ring ring to add
+     * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter
      @return
        0 in case of success,
        1 problem with feature type,
@@ -604,7 +606,7 @@ class QgsVectorLayer : QgsMapLayer
        4 ring crosses existing rings,
        5 no feature found where ring can be inserted
        6 layer not editable */
-    int addRing( const QList<QgsPoint>& ring );
+    int addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId = 0 );
 
     /**Adds a new part polygon to a multipart feature
      @return
diff --git a/python/core/qgsvectorlayereditutils.sip b/python/core/qgsvectorlayereditutils.sip
index ab227bf..356d3f4 100644
--- a/python/core/qgsvectorlayereditutils.sip
+++ b/python/core/qgsvectorlayereditutils.sip
@@ -26,6 +26,8 @@ class QgsVectorLayerEditUtils
     bool deleteVertex( QgsFeatureId atFeatureId, int atVertex );
 
     /** Adds a ring to polygon/multipolygon features
+     * @param ring ring to add
+     * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter
      @return
        0 in case of success,
        1 problem with feature type,
@@ -33,7 +35,7 @@ class QgsVectorLayerEditUtils
        3 ring not valid,
        4 ring crosses existing rings,
        5 no feature found where ring can be inserted*/
-    int addRing( const QList<QgsPoint>& ring );
+    int addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId = 0 );
 
     /** Adds a new part polygon to a multipart feature
      @return
diff --git a/python/core/symbology-ng/qgsfillsymbollayerv2.sip b/python/core/symbology-ng/qgsfillsymbollayerv2.sip
index d78f2f0..939676c 100644
--- a/python/core/symbology-ng/qgsfillsymbollayerv2.sip
+++ b/python/core/symbology-ng/qgsfillsymbollayerv2.sip
@@ -438,7 +438,7 @@ class QgsImageFillSymbolLayer: QgsFillSymbolLayerV2
     void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
 
     virtual QgsSymbolV2* subSymbol();
-    virtual bool setSubSymbol( QgsSymbolV2* symbol );
+    virtual bool setSubSymbol( QgsSymbolV2* symbol /Transfer/ );
 
     void setOutlineWidthUnit( QgsSymbolV2::OutputUnit unit );
     QgsSymbolV2::OutputUnit outlineWidthUnit() const;
@@ -493,7 +493,7 @@ class QgsRasterFillSymbolLayer: QgsImageFillSymbolLayer
 
     //override QgsImageFillSymbolLayer's support for sub symbols
     virtual QgsSymbolV2* subSymbol();
-    virtual bool setSubSymbol( QgsSymbolV2* symbol );
+    virtual bool setSubSymbol( QgsSymbolV2* symbol /Transfer/ );
 
     /**Sets the path to the raster image used for the fill.
      * @param imagePath path to image file
@@ -756,7 +756,7 @@ class QgsLinePatternFillSymbolLayer: QgsImageFillSymbolLayer
     void setMapUnitScale( const QgsMapUnitScale& scale );
     QgsMapUnitScale mapUnitScale() const;
 
-    bool setSubSymbol( QgsSymbolV2* symbol );
+    bool setSubSymbol( QgsSymbolV2* symbol /Transfer/ );
     QgsSymbolV2* subSymbol();
 
     QSet<QString> usedAttributes() const;
@@ -802,7 +802,7 @@ class QgsPointPatternFillSymbolLayer : QgsImageFillSymbolLayer
     double displacementY() const;
     void setDisplacementY( double d );
 
-    bool setSubSymbol( QgsSymbolV2* symbol );
+    bool setSubSymbol( QgsSymbolV2* symbol /Transfer/ );
     virtual QgsSymbolV2* subSymbol();
 
     void setDistanceXUnit( QgsSymbolV2::OutputUnit unit );
diff --git a/python/core/symbology-ng/qgslinesymbollayerv2.sip b/python/core/symbology-ng/qgslinesymbollayerv2.sip
index 8129353..b316d8b 100644
--- a/python/core/symbology-ng/qgslinesymbollayerv2.sip
+++ b/python/core/symbology-ng/qgslinesymbollayerv2.sip
@@ -128,7 +128,7 @@ class QgsMarkerLineSymbolLayerV2 : QgsLineSymbolLayerV2
     void setColor( const QColor& color );
 
     QgsSymbolV2* subSymbol();
-    bool setSubSymbol( QgsSymbolV2* symbol );
+    bool setSubSymbol( QgsSymbolV2* symbol /Transfer/);
 
     virtual void setWidth( double width );
     virtual double width() const;
diff --git a/python/core/symbology-ng/qgssvgcache.sip b/python/core/symbology-ng/qgssvgcache.sip
index a574817..f607803 100644
--- a/python/core/symbology-ng/qgssvgcache.sip
+++ b/python/core/symbology-ng/qgssvgcache.sip
@@ -14,11 +14,15 @@ class QgsSvgCacheEntry
      * @param rasterScaleFactor raster scale factor
      * @param fill color of fill
      * @param outline color of outline
+     * @param lookupKey the key string used in QgsSvgCache for quick lookup of this entry (relative or absolute path)
      */
-    QgsSvgCacheEntry( const QString& file, double size, double outlineWidth, double widthScaleFactor, double rasterScaleFactor, const QColor& fill, const QColor& outline );
+    QgsSvgCacheEntry( const QString& file, double size, double outlineWidth, double widthScaleFactor, double rasterScaleFactor, const QColor& fill, const QColor& outline, const QString& lookupKey = QString() );
     ~QgsSvgCacheEntry();
 
+    //! Absolute path to SVG file
     QString file;
+    //! Lookup key used by QgsSvgCache's hashtable (relative or absolute path). Needed for removal from the hashtable
+    QString lookupKey;
     double size; //size in pixels (cast to int for QImage)
     double outlineWidth;
     double widthScaleFactor;
diff --git a/python/core/symbology-ng/qgsvectorcolorrampv2.sip b/python/core/symbology-ng/qgsvectorcolorrampv2.sip
index 55551a5..4d177c7 100644
--- a/python/core/symbology-ng/qgsvectorcolorrampv2.sip
+++ b/python/core/symbology-ng/qgsvectorcolorrampv2.sip
@@ -6,9 +6,15 @@ class QgsVectorColorRampV2
 
 %ConvertToSubClassCode
   if (sipCpp->type() == "gradient")
-  {
     sipClass = sipClass_QgsVectorGradientColorRampV2;
-  }
+  else if (sipCpp->type() == "random")
+    sipClass = sipClass_QgsVectorRandomColorRampV2;
+  else if (sipCpp->type() == "randomcolors")
+    sipClass = sipClass_QgsRandomColorsV2;
+  else if (sipCpp->type() == "colorbrewer")
+    sipClass = sipClass_QgsVectorColorBrewerColorRampV2;
+  else if (sipCpp->type() == "cpt-city")
+    sipClass = sipClass_QgsCptCityColorRampV2;
   else
     sipClass = 0;
 %End
@@ -110,6 +116,13 @@ class QgsVectorRandomColorRampV2 : QgsVectorColorRampV2
 
     virtual QgsStringMap properties() const;
 
+    /** Get a list of random colors
+     * @note added in 2.4 */
+    static QList<QColor> randomColors( int count,
+                                       int hueMax = DEFAULT_RANDOM_HUE_MAX, int hueMin = DEFAULT_RANDOM_HUE_MIN,
+                                       int satMax = DEFAULT_RANDOM_SAT_MAX, int satMin = DEFAULT_RANDOM_SAT_MIN,
+                                       int valMax = DEFAULT_RANDOM_VAL_MAX, int valMin = DEFAULT_RANDOM_VAL_MIN );
+
     void updateColors();
 
     int count() const;
diff --git a/python/plugins/db_manager/db_plugins/postgis/plugin.py b/python/plugins/db_manager/db_plugins/postgis/plugin.py
index bec3060..19bb013 100644
--- a/python/plugins/db_manager/db_plugins/postgis/plugin.py
+++ b/python/plugins/db_manager/db_plugins/postgis/plugin.py
@@ -27,308 +27,351 @@ from PyQt4.QtCore import QSettings, Qt, QRegExp
 from PyQt4.QtGui import QIcon, QAction, QApplication, QMessageBox
 from qgis.gui import QgsMessageBar
 
-from ..plugin import ConnectionError, InvalidDataException, DBPlugin, Database, Schema, Table, VectorTable, RasterTable, TableField, TableConstraint, TableIndex, TableTrigger, TableRule
+from ..plugin import ConnectionError, InvalidDataException, DBPlugin, Database, Schema, Table, VectorTable, RasterTable, \
+    TableField, TableConstraint, TableIndex, TableTrigger, TableRule
 
 try:
-        from . import resources_rc
+    from . import resources_rc
 except ImportError:
-        pass
+    pass
 
 import re
 
+
 def classFactory():
-        return PostGisDBPlugin
+    return PostGisDBPlugin
+
 
 class PostGisDBPlugin(DBPlugin):
 
-        @classmethod
-        def icon(self):
-                return QIcon(":/db_manager/postgis/icon")
+    @classmethod
+    def icon(self):
+        return QIcon(":/db_manager/postgis/icon")
+
+    @classmethod
+    def typeName(self):
+        return 'postgis'
+
+    @classmethod
+    def typeNameString(self):
+        return 'PostGIS'
 
-        @classmethod
-        def typeName(self):
-                return 'postgis'
+    @classmethod
+    def providerName(self):
+        return 'postgres'
 
-        @classmethod
-        def typeNameString(self):
-                return 'PostGIS'
+    @classmethod
+    def connectionSettingsKey(self):
+        return '/PostgreSQL/connections'
 
-        @classmethod
-        def providerName(self):
-                return 'postgres'
+    def databasesFactory(self, connection, uri):
+        return PGDatabase(connection, uri)
 
-        @classmethod
-        def connectionSettingsKey(self):
-                return '/PostgreSQL/connections'
+    def connect(self, parent=None):
+        conn_name = self.connectionName()
+        settings = QSettings()
+        settings.beginGroup(u"/%s/%s" % (self.connectionSettingsKey(), conn_name))
 
-        def databasesFactory(self, connection, uri):
-                return PGDatabase(connection, uri)
+        if not settings.contains("database"):  # non-existent entry?
+            raise InvalidDataException(self.tr('There is no defined database connection "%s".') % conn_name)
 
-        def connect(self, parent=None):
-                conn_name = self.connectionName()
-                settings = QSettings()
-                settings.beginGroup( u"/%s/%s" % (self.connectionSettingsKey(), conn_name) )
+        from qgis.core import QgsDataSourceURI
 
-                if not settings.contains( "database" ): # non-existent entry?
-                        raise InvalidDataException( self.tr('There is no defined database connection "%s".') % conn_name )
+        uri = QgsDataSourceURI()
 
-                from qgis.core import QgsDataSourceURI
-                uri = QgsDataSourceURI()
+        settingsList = ["service", "host", "port", "database", "username", "password"]
+        service, host, port, database, username, password = map(lambda x: settings.value(x, "", type=str), settingsList)
 
-                settingsList = ["service", "host", "port", "database", "username", "password"]
-                service, host, port, database, username, password = map(lambda x: settings.value(x, "", type=str), settingsList)
+        useEstimatedMetadata = settings.value("estimatedMetadata", False, type=bool)
+        sslmode = settings.value("sslmode", QgsDataSourceURI.SSLprefer, type=int)
 
-                useEstimatedMetadata = settings.value("estimatedMetadata", False, type=bool)
-                sslmode = settings.value("sslmode", QgsDataSourceURI.SSLprefer, type=int)
+        settings.endGroup()
 
-                settings.endGroup()
+        if service:
+            uri.setConnection(service, database, username, password, sslmode)
+        else:
+            uri.setConnection(host, port, database, username, password, sslmode)
 
-                if service:
-                        uri.setConnection(service, database, username, password, sslmode)
-                else:
-                        uri.setConnection(host, port, database, username, password, sslmode)
+        uri.setUseEstimatedMetadata(useEstimatedMetadata)
 
-                uri.setUseEstimatedMetadata(useEstimatedMetadata)
+        try:
+            return self.connectToUri(uri)
+        except ConnectionError as e:
+            return False
 
-                try:
-                        return self.connectToUri(uri)
-                except ConnectionError, e:
-                        return False
 
 class PGDatabase(Database):
-        def __init__(self, connection, uri):
-                Database.__init__(self, connection, uri)
 
-        def connectorsFactory(self, uri):
-                return PostGisDBConnector(uri)
+    def __init__(self, connection, uri):
+        Database.__init__(self, connection, uri)
 
-        def dataTablesFactory(self, row, db, schema=None):
-                return PGTable(row, db, schema)
+    def connectorsFactory(self, uri):
+        return PostGisDBConnector(uri)
 
-        def vectorTablesFactory(self, row, db, schema=None):
-                return PGVectorTable(row, db, schema)
+    def dataTablesFactory(self, row, db, schema=None):
+        return PGTable(row, db, schema)
 
-        def rasterTablesFactory(self, row, db, schema=None):
-                return PGRasterTable(row, db, schema)
+    def vectorTablesFactory(self, row, db, schema=None):
+        return PGVectorTable(row, db, schema)
 
-        def schemasFactory(self, row, db):
-                return PGSchema(row, db)
+    def rasterTablesFactory(self, row, db, schema=None):
+        return PGRasterTable(row, db, schema)
 
-        def sqlResultModel(self, sql, parent):
-                from .data_model import PGSqlResultModel
-                return PGSqlResultModel(self, sql, parent)
+    def schemasFactory(self, row, db):
+        return PGSchema(row, db)
 
+    def sqlResultModel(self, sql, parent):
+        from .data_model import PGSqlResultModel
 
-        def registerDatabaseActions(self, mainWindow):
-                Database.registerDatabaseActions(self, mainWindow)
+        return PGSqlResultModel(self, sql, parent)
 
-                # add a separator
-                separator = QAction(self)
-                separator.setSeparator(True)
-                mainWindow.registerAction( separator, self.tr("&Table") )
+    def registerDatabaseActions(self, mainWindow):
+        Database.registerDatabaseActions(self, mainWindow)
 
-                action = QAction(self.tr("Run &Vacuum Analyze"), self)
-                mainWindow.registerAction( action, self.tr("&Table"), self.runVacuumAnalyzeActionSlot )
+        # add a separator
+        separator = QAction(self)
+        separator.setSeparator(True)
+        mainWindow.registerAction(separator, self.tr("&Table"))
 
-        def runVacuumAnalyzeActionSlot(self, item, action, parent):
-                QApplication.restoreOverrideCursor()
-                try:
-                        if not isinstance(item, Table) or item.isView:
-                                parent.infoBar.pushMessage(self.tr("Select a table for vacuum analyze."), QgsMessageBar.INFO, parent.iface.messageTimeout())
-                                return
-                finally:
-                        QApplication.setOverrideCursor(Qt.WaitCursor)
+        action = QAction(self.tr("Run &Vacuum Analyze"), self)
+        mainWindow.registerAction(action, self.tr("&Table"), self.runVacuumAnalyzeActionSlot)
 
-                item.runVacuumAnalyze()
+    def runVacuumAnalyzeActionSlot(self, item, action, parent):
+        QApplication.restoreOverrideCursor()
+        try:
+            if not isinstance(item, Table) or item.isView:
+                parent.infoBar.pushMessage(self.tr("Select a table for vacuum analyze."), QgsMessageBar.INFO,
+                                           parent.iface.messageTimeout())
+                return
+        finally:
+            QApplication.setOverrideCursor(Qt.WaitCursor)
+
+        item.runVacuumAnalyze()
 
 
 class PGSchema(Schema):
-        def __init__(self, row, db):
-                Schema.__init__(self, db)
-                self.oid, self.name, self.owner, self.perms, self.comment = row
+
+    def __init__(self, row, db):
+        Schema.__init__(self, db)
+        self.oid, self.name, self.owner, self.perms, self.comment = row
 
 
 class PGTable(Table):
-        def __init__(self, row, db, schema=None):
-                Table.__init__(self, db, schema)
-                self.name, schema_name, self.isView, self.owner, self.estimatedRowCount, self.pages, self.comment = row
-                self.estimatedRowCount = int(self.estimatedRowCount)
 
-        def runVacuumAnalyze(self):
-                self.aboutToChange()
-                self.database().connector.runVacuumAnalyze( (self.schemaName(), self.name) )
-                # TODO: change only this item, not re-create all the tables in the schema/database
-                self.schema().refresh() if self.schema() else self.database().refresh()
+    def __init__(self, row, db, schema=None):
+        Table.__init__(self, db, schema)
+        self.name, schema_name, self.isView, self.owner, self.estimatedRowCount, self.pages, self.comment = row
+        self.estimatedRowCount = int(self.estimatedRowCount)
 
-        def runAction(self, action):
-                action = unicode(action)
+    def runVacuumAnalyze(self):
+        self.aboutToChange()
+        self.database().connector.runVacuumAnalyze((self.schemaName(), self.name))
+        # TODO: change only this item, not re-create all the tables in the schema/database
+        self.schema().refresh() if self.schema() else self.database().refresh()
 
-                if action.startswith( "vacuumanalyze/" ):
-                        if action == "vacuumanalyze/run":
-                                self.runVacuumAnalyze()
-                                return True
+    def runAction(self, action):
+        action = unicode(action)
 
-                elif action.startswith( "rule/" ):
-                        parts = action.split('/')
-                        rule_name = parts[1]
-                        rule_action = parts[2]
+        if action.startswith("vacuumanalyze/"):
+            if action == "vacuumanalyze/run":
+                self.runVacuumAnalyze()
+                return True
 
-                        msg = u"Do you want to %s rule %s?" % (rule_action, rule_name)
+        elif action.startswith("rule/"):
+            parts = action.split('/')
+            rule_name = parts[1]
+            rule_action = parts[2]
 
-                        QApplication.restoreOverrideCursor()
+            msg = u"Do you want to %s rule %s?" % (rule_action, rule_name)
 
-                        try:
-                                if QMessageBox.question(None, self.tr("Table rule"), msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.No:
-                                        return False
-                        finally:
-                                QApplication.setOverrideCursor(Qt.WaitCursor)
+            QApplication.restoreOverrideCursor()
 
-                        if rule_action == "delete":
-                                self.aboutToChange()
-                                self.database().connector.deleteTableRule(rule_name, (self.schemaName(), self.name))
-                                self.refreshRules()
-                                return True
+            try:
+                if QMessageBox.question(None, self.tr("Table rule"), msg,
+                                        QMessageBox.Yes | QMessageBox.No) == QMessageBox.No:
+                    return False
+            finally:
+                QApplication.setOverrideCursor(Qt.WaitCursor)
 
-                return Table.runAction(self, action)
+            if rule_action == "delete":
+                self.aboutToChange()
+                self.database().connector.deleteTableRule(rule_name, (self.schemaName(), self.name))
+                self.refreshRules()
+                return True
+
+        return Table.runAction(self, action)
+
+    def tableFieldsFactory(self, row, table):
+        return PGTableField(row, table)
 
-        def tableFieldsFactory(self, row, table):
-                return PGTableField(row, table)
+    def tableConstraintsFactory(self, row, table):
+        return PGTableConstraint(row, table)
 
-        def tableConstraintsFactory(self, row, table):
-                return PGTableConstraint(row, table)
+    def tableIndexesFactory(self, row, table):
+        return PGTableIndex(row, table)
 
-        def tableIndexesFactory(self, row, table):
-                return PGTableIndex(row, table)
+    def tableTriggersFactory(self, row, table):
+        return PGTableTrigger(row, table)
 
-        def tableTriggersFactory(self, row, table):
-                return PGTableTrigger(row, table)
+    def tableRulesFactory(self, row, table):
+        return PGTableRule(row, table)
 
-        def tableRulesFactory(self, row, table):
-                return PGTableRule(row, table)
+    def info(self):
+        from .info_model import PGTableInfo
 
-        def info(self):
-                from .info_model import PGTableInfo
-                return PGTableInfo(self)
+        return PGTableInfo(self)
 
-        def tableDataModel(self, parent):
-                from .data_model import PGTableDataModel
-                return PGTableDataModel(self, parent)
+    def tableDataModel(self, parent):
+        from .data_model import PGTableDataModel
+
+        return PGTableDataModel(self, parent)
 
 
 class PGVectorTable(PGTable, VectorTable):
-        def __init__(self, row, db, schema=None):
-                PGTable.__init__(self, row[:-4], db, schema)
-                VectorTable.__init__(self, db, schema)
-                self.geomColumn, self.geomType, self.geomDim, self.srid = row[-4:]
 
-        def info(self):
-                from .info_model import PGVectorTableInfo
-                return PGVectorTableInfo(self)
+    def __init__(self, row, db, schema=None):
+        PGTable.__init__(self, row[:-4], db, schema)
+        VectorTable.__init__(self, db, schema)
+        self.geomColumn, self.geomType, self.geomDim, self.srid = row[-4:]
+
+    def info(self):
+        from .info_model import PGVectorTableInfo
+
+        return PGVectorTableInfo(self)
+
+    def runAction(self, action):
+        if PGTable.runAction(self, action):
+            return True
+        return VectorTable.runAction(self, action)
 
-        def runAction(self, action):
-                if PGTable.runAction(self, action):
-                        return True
-                return VectorTable.runAction(self, action)
 
 class PGRasterTable(PGTable, RasterTable):
-        def __init__(self, row, db, schema=None):
-                PGTable.__init__(self, row[:-6], db, schema)
-                RasterTable.__init__(self, db, schema)
-                self.geomColumn, self.pixelType, self.pixelSizeX, self.pixelSizeY, self.isExternal, self.srid = row[-6:]
-                self.geomType = 'RASTER'
-
-        def info(self):
-                from .info_model import PGRasterTableInfo
-                return PGRasterTableInfo(self)
-
-        def gdalUri(self):
-                uri = self.database().uri()
-                schema = ( u'schema=%s' % self.schemaName() ) if self.schemaName() else ''
-                dbname = ( u'dbname=%s' % uri.database() ) if uri.database() else ''
-                host = ( u'host=%s' % uri.host() ) if uri.host() else ''
-                user = ( u'user=%s' % uri.username() ) if uri.username() else ''
-                passw = ( u'password=%s' % uri.password() ) if uri.password() else ''
-                port = ( u'port=%s' % uri.port() ) if uri.port() else ''
-
-                # Find first raster field
-                col = ''
-                for fld in self.fields():
-                  if fld.dataType == "raster":
-                          col = u'column=%s' % fld.name
-                          break
-
-                gdalUri = u'PG: %s %s %s %s %s mode=2 %s %s table=%s' % \
-                    (dbname, host, user, passw, port, schema, col, self.name)
-
-                return gdalUri
-
-        def mimeUri(self):
-                uri = u"raster:gdal:%s:%s" % (self.name, re.sub(":", "\:", self.gdalUri()))
-                return uri
-
-        def toMapLayer(self):
-                from qgis.core import QgsRasterLayer, QgsContrastEnhancement
-                rl = QgsRasterLayer(self.gdalUri(), self.name)
-                if rl.isValid():
-                        rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
-                return rl
+
+    def __init__(self, row, db, schema=None):
+        PGTable.__init__(self, row[:-6], db, schema)
+        RasterTable.__init__(self, db, schema)
+        self.geomColumn, self.pixelType, self.pixelSizeX, self.pixelSizeY, self.isExternal, self.srid = row[-6:]
+        self.geomType = 'RASTER'
+
+    def info(self):
+        from .info_model import PGRasterTableInfo
+
+        return PGRasterTableInfo(self)
+
+    def gdalUri(self, uri=None):
+        if not uri:
+            uri = self.database().uri()
+        schema = (u'schema=%s' % self.schemaName()) if self.schemaName() else ''
+        dbname = (u'dbname=%s' % uri.database()) if uri.database() else ''
+        host = (u'host=%s' % uri.host()) if uri.host() else ''
+        user = (u'user=%s' % uri.username()) if uri.username() else ''
+        passw = (u'password=%s' % uri.password()) if uri.password() else ''
+        port = (u'port=%s' % uri.port()) if uri.port() else ''
+
+        # Find first raster field
+        col = ''
+        for fld in self.fields():
+            if fld.dataType == "raster":
+                col = u'column=%s' % fld.name
+                break
+
+        gdalUri = u'PG: %s %s %s %s %s mode=2 %s %s table=%s' % \
+                  (dbname, host, user, passw, port, schema, col, self.name)
+
+        return gdalUri
+
+    def mimeUri(self):
+        # QGIS has no provider for PGRasters, let's use GDAL
+        uri = u"raster:gdal:%s:%s" % (self.name, re.sub(":", "\:", self.gdalUri()))
+        return uri
+
+    def toMapLayer(self):
+        from qgis.core import QgsRasterLayer, QgsContrastEnhancement, QgsDataSourceURI, QgsCredentials
+
+        rl = QgsRasterLayer(self.gdalUri(), self.name)
+        if not rl.isValid():
+            err = rl.error().summary()
+            uri = QgsDataSourceURI(self.database().uri())
+            conninfo = uri.connectionInfo()
+            username = uri.username()
+            password = uri.password()
+
+            for i in range(3):
+                (ok, username, password) = QgsCredentials.instance().get(conninfo, username, password, err)
+                if ok:
+                    uri.setUsername(username)
+                    uri.setPassword(password)
+                    rl = QgsRasterLayer(self.gdalUri(uri), self.name)
+                    if rl.isValid():
+                        break
+
+        if rl.isValid():
+            rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
+        return rl
+
 
 class PGTableField(TableField):
-        def __init__(self, row, table):
-                TableField.__init__(self, table)
-                self.num, self.name, self.dataType, self.charMaxLen, self.modifier, self.notNull, self.hasDefault, self.default, typeStr = row
-                self.primaryKey = False
-
-                # get modifier (e.g. "precision,scale") from formatted type string
-                trimmedTypeStr = typeStr.strip()
-                regex = QRegExp( "\((.+)\)$" )
-                startpos = regex.indexIn( trimmedTypeStr )
-                if startpos >= 0:
-                        self.modifier = regex.cap(1).strip()
-                else:
-                        self.modifier = None
-
-                # find out whether fields are part of primary key
-                for con in self.table().constraints():
-                        if con.type == TableConstraint.TypePrimaryKey and self.num in con.columns:
-                                self.primaryKey = True
-                                break
+
+    def __init__(self, row, table):
+        TableField.__init__(self, table)
+        self.num, self.name, self.dataType, self.charMaxLen, self.modifier, self.notNull, self.hasDefault, self.default, typeStr = row
+        self.primaryKey = False
+
+        # get modifier (e.g. "precision,scale") from formatted type string
+        trimmedTypeStr = typeStr.strip()
+        regex = QRegExp("\((.+)\)$")
+        startpos = regex.indexIn(trimmedTypeStr)
+        if startpos >= 0:
+            self.modifier = regex.cap(1).strip()
+        else:
+            self.modifier = None
+
+        # find out whether fields are part of primary key
+        for con in self.table().constraints():
+            if con.type == TableConstraint.TypePrimaryKey and self.num in con.columns:
+                self.primaryKey = True
+                break
 
 
 class PGTableConstraint(TableConstraint):
-        def __init__(self, row, table):
-                TableConstraint.__init__(self, table)
-                self.name, constr_type_str, self.isDefferable, self.isDeffered, columns = row[:5]
-                self.columns = map(int, columns.split(' '))
-
-                if constr_type_str in TableConstraint.types:
-                        self.type = TableConstraint.types[constr_type_str]
-                else:
-                        self.type = TableConstraint.TypeUnknown
-
-                if self.type == TableConstraint.TypeCheck:
-                        self.checkSource = row[5]
-                elif self.type == TableConstraint.TypeForeignKey:
-                        self.foreignTable = row[6]
-                        self.foreignOnUpdate = TableConstraint.onAction[row[7]]
-                        self.foreignOnDelete = TableConstraint.onAction[row[8]]
-                        self.foreignMatchType = TableConstraint.matchTypes[row[9]]
-                        self.foreignKeys = row[10]
+
+    def __init__(self, row, table):
+        TableConstraint.__init__(self, table)
+        self.name, constr_type_str, self.isDefferable, self.isDeffered, columns = row[:5]
+        self.columns = map(int, columns.split(' '))
+
+        if constr_type_str in TableConstraint.types:
+            self.type = TableConstraint.types[constr_type_str]
+        else:
+            self.type = TableConstraint.TypeUnknown
+
+        if self.type == TableConstraint.TypeCheck:
+            self.checkSource = row[5]
+        elif self.type == TableConstraint.TypeForeignKey:
+            self.foreignTable = row[6]
+            self.foreignOnUpdate = TableConstraint.onAction[row[7]]
+            self.foreignOnDelete = TableConstraint.onAction[row[8]]
+            self.foreignMatchType = TableConstraint.matchTypes[row[9]]
+            self.foreignKeys = row[10]
 
 
 class PGTableIndex(TableIndex):
-        def __init__(self, row, table):
-                TableIndex.__init__(self, table)
-                self.name, columns, self.isUnique = row
-                self.columns = map(int, columns.split(' '))
+
+    def __init__(self, row, table):
+        TableIndex.__init__(self, table)
+        self.name, columns, self.isUnique = row
+        self.columns = map(int, columns.split(' '))
 
 
 class PGTableTrigger(TableTrigger):
-        def __init__(self, row, table):
-                TableTrigger.__init__(self, table)
-                self.name, self.function, self.type, self.enabled = row
+
+    def __init__(self, row, table):
+        TableTrigger.__init__(self, table)
+        self.name, self.function, self.type, self.enabled = row
+
 
 class PGTableRule(TableRule):
-        def __init__(self, row, table):
-                TableRule.__init__(self, table)
-                self.name, self.definition = row
+
+    def __init__(self, row, table):
+        TableRule.__init__(self, table)
+        self.name, self.definition = row
diff --git a/python/plugins/processing/algs/qgis/VectorGrid.py b/python/plugins/processing/algs/qgis/VectorGrid.py
index e9fca3b..98b245f 100644
--- a/python/plugins/processing/algs/qgis/VectorGrid.py
+++ b/python/plugins/processing/algs/qgis/VectorGrid.py
@@ -90,7 +90,7 @@ class VectorGrid(GeoAlgorithm):
             fields.append(QgsField('coord', QVariant.Double, '', 24, 15))
             fieldCount = 2
             writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
-                fields, QGis.WKBPolygon, mapCRS)
+                fields, QGis.WKBLineString, mapCRS)
 
         feat = QgsFeature()
         feat.initAttributes(fieldCount)
diff --git a/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging(Global).txt b/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging(Global).txt
index e7cd177..0eee0d1 100644
--- a/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging(Global).txt
+++ b/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging(Global).txt
@@ -1,22 +1,19 @@
 Ordinary Kriging (Global)
 statistics_kriging
-ParameterVector|SHAPES|Points|0|False
-ParameterTableField|FIELD|Attribute|SHAPES|-1|False
-ParameterBoolean|BVARIANCE              |Create Variance Grid|True
+ParameterVector|POINTS|Points|0|False
+ParameterTableField|ZFIELD|Attribute|SHAPES|-1|False
 Hardcoded|-TARGET 0
-ParameterSelection|MODEL|Variogram Model|[0] Spherical Model;[1] Exponential Model;[2] Gaussian Model;[3] Linear Regression;[4] Exponential Regression;[5] Power Function Regression
-ParameterBoolean|BLOCK                  |Block Kriging|True
+ParameterSelection|TQUALITY|Type of Quality Measure|[0] standard deviation;[1] variance
+ParameterBoolean|LOG|Logarithmic Transformation|True
+ParameterBoolean|BLOCK|Block Kriging|True
 ParameterNumber|DBLOCK|Block Size|1|None|100
-ParameterBoolean|BLOG                   |Logarithmic Transformation|True
-ParameterNumber|NUGGET|Nugget|None|None|0.0
-ParameterNumber|SILL|Sill|None|None|0.0
-ParameterNumber|RANGE|Range|None|None|0.0
-ParameterNumber|LIN_B|Linear Regression|None|None|1.0
-ParameterNumber|EXP_B|Exponential Regression|None|None|0.1
-ParameterNumber|POW_A|Power Function - A|None|None|1.0
-ParameterNumber|POW_B|Power Function - B|None|None|0.5
-ParameterNumber|USER_CELL_SIZE|Grid Size|0|None|1.0
-ParameterBoolean|USER_FIT_EXTENT        |Fit Extent|True
-Extent USER_X_EXTENT_MIN USER_X_EXTENT_MAX USER_Y_EXTENT_MIN USER_Y_EXTENT_MIN
-OutputRaster|GRID|Grid
-OutputRaster|VARIANCE|Variance
+ParameterNumber|VAR_MAXDIST|Maximum Distance|None|None|-1.0
+ParameterNumber|VAR_NCLASSES|Lag Distance Classes|1|None|100
+ParameterNumber|VAR_NSKIP|Skip|1|None|1
+ParameterString|VAR_MODEL|Variogram Model|a + b * x
+ParameterBoolean|USER_BVARIANCE|Create Quality Grid|True
+Extent USER_XMIN USER_XMAX USER_YMIN USER_YMAX
+ParameterNumber|USER_SIZE|Grid Size|0|None|100.0
+ParameterSelection|USER_FIT|Search Direction|[0] nodes;[1] cells
+OutputRaster|USER_GRID|Grid
+OutputRaster|USER_VARIANCE|Variance
\ No newline at end of file
diff --git a/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging.txt b/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging.txt
index 920408f..71b10a1 100644
--- a/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging.txt
+++ b/python/plugins/processing/algs/saga/description/2.1.2/OrdinaryKriging.txt
@@ -4,8 +4,8 @@ ParameterVector|POINTS|Points|0|False
 ParameterTableField|ZFIELD|Attribute|POINTS|-1|False
 Hardcoded|-TARGET 0
 ParameterSelection|TQUALITY|Type of Quality Measure|[0] standard deviation;[1] variance
-ParameterBoolean|LOG                   |Logarithmic Transformation|True
-ParameterBoolean|BLOCK                  |Block Kriging|True
+ParameterBoolean|LOG|Logarithmic Transformation|True
+ParameterBoolean|BLOCK|Block Kriging|True
 ParameterNumber|DBLOCK|Block Size|0|None|100
 ParameterNumber|VAR_MAXDIST|Maximum Distance|None|None|-1.0
 ParameterNumber|VAR_NCLASSES|Lag Distance Classes|1|None|100
@@ -17,9 +17,9 @@ ParameterSelection|SEARCH_POINTS_ALL|Number of Points|[0] maximum number of near
 ParameterNumber|SEARCH_POINTS_MIN|Minimum|1|None|4
 ParameterNumber|SEARCH_POINTS_MAX|Maximum|1|None|20
 ParameterSelection|SEARCH_DIRECTION|Search Direction|[0] all directions;[1] quadrants
-ParameterBoolean|USER_BVARIANCE              |Create Quality Grid|True
+ParameterBoolean|USER_BVARIANCE|Create Quality Grid|True
 Extent USER_XMIN USER_XMAX USER_YMIN USER_YMAX
-ParameterNumber|USER_SIZE|Cellsize|0|None|1.0
+ParameterNumber|USER_SIZE|Cellsize|0|None|100.0
 ParameterSelection|USER_FIT|Search Direction|[0] nodes;[1] cells
 OutputRaster|USER_GRID|Grid
-OutputRaster|USER_VARIANCE|Variance
+OutputRaster|USER_VARIANCE|Variance
\ No newline at end of file
diff --git a/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging(Global).txt b/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging(Global).txt
index 1c8736c..8be4054 100644
--- a/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging(Global).txt
+++ b/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging(Global).txt
@@ -1,24 +1,22 @@
 Universal Kriging (Global)
 statistics_kriging
-ParameterVector|SHAPES|Points|0|False
-ParameterTableField|FIELD|Attribute|SHAPES|-1|False
-ParameterBoolean|BVARIANCE              |Create Variance Grid|True
+ParameterVector|POINTS|Points|0|False
+ParameterTableField|ZFIELD|Attribute|SHAPES|-1|False
 Hardcoded|-TARGET 0
-ParameterSelection|MODEL|Variogram Model|[0] Spherical Model;[1] Exponential Model;[2] Gaussian Model;[3] Linear Regression;[4] Exponential Regression;[5] Power Function Regression
+ParameterSelection|TQUALITY|Type of Quality Measure|[0] standard deviation;[1] variance
+ParameterBoolean|LOG|Logarithmic Transformation|True
 ParameterBoolean|BLOCK|Block Kriging|True
 ParameterNumber|DBLOCK|Block Size|1|None|100
-ParameterBoolean|BLOG|Logarithmic Transformation|True
-ParameterNumber|NUGGET|Nugget|None|None|0.0
-ParameterNumber|SILL|Sill|None|None|0.0
-ParameterNumber|RANGE|Range|None|None|0.0
-ParameterNumber|LIN_B|Linear Regression|None|None|1
-ParameterNumber|EXP_B|Exponential Regression|None|None|0.5
-ParameterNumber|POW_A|Power Function - A|None|None|1.0
-ParameterNumber|POW_B|Power Function - B|None|None|0.1
-ParameterMultipleInput|GRIDS|Grids|3|False
+ParameterNumber|VAR_MAXDIST|Maximum Distance|None|None|-1.0
+ParameterNumber|VAR_NCLASSES|Lag Distance Classes|1|None|100
+ParameterNumber|VAR_NSKIP|Skip|1|None|1
+ParameterString|VAR_MODEL|Variogram Model|a + b * x
+ParameterMultipleInput|GRIDS|Input Grids|3|True
 ParameterSelection|INTERPOL|Grid Interpolation|[0] Nearest Neighbor;[1] Bilinear Interpolation;[2] Inverse Distance Interpolation;[3] Bicubic Spline Interpolation;[4] B-Spline Interpolation
-ParameterNumber|USER_CELL_SIZE|Grid Size|0|None|1.0
-ParameterBoolean|USER_FIT_EXTENT        |Fit Extent|True
-Extent USER_X_EXTENT_MIN USER_X_EXTENT_MAX USER_Y_EXTENT_MIN USER_Y_EXTENT_MIN
-OutputRaster|GRID|Grid
-OutputRaster|VARIANCE|Variance
+ParameterBoolean|COORDS|Coordinates|False
+ParameterBoolean|USER_BVARIANCE|Create Quality Grid|True
+Extent USER_XMIN USER_XMAX USER_YMIN USER_YMAX
+ParameterNumber|USER_SIZE|Grid Size|0|None|100.0
+ParameterSelection|USER_FIT|Search Direction|[0] nodes;[1] cells
+OutputRaster|USER_GRID|Grid
+OutputRaster|USER_VARIANCE|Variance
diff --git a/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging.txt b/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging.txt
index d3417f5..62431e7 100644
--- a/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging.txt
+++ b/python/plugins/processing/algs/saga/description/2.1.2/UniversalKriging.txt
@@ -1,27 +1,28 @@
 Universal Kriging
 statistics_kriging
-ParameterVector|SHAPES|Points|0|False
-ParameterTableField|FIELD|Attribute|SHAPES|-1|False
-ParameterBoolean|BVARIANCE              |Create Variance Grid|True
+ParameterVector|POINTS|Points|0|False
+ParameterTableField|ZFIELD|Attribute|POINTS|-1|False
 Hardcoded|-TARGET 0
-ParameterSelection|MODEL|Variogram Model|[0] Spherical Model;[1] Exponential Model;[2] Gaussian Model;[3] Linear Regression;[4] Exponential Regression;[5] Power Function Regression
-ParameterBoolean|BLOCK                  |Block Kriging|True
+ParameterSelection|TQUALITY|Type of Quality Measure|[0] standard deviation;[1] variance
+ParameterBoolean|LOG|Logarithmic Transformation|True
+ParameterBoolean|BLOCK|Block Kriging|True
 ParameterNumber|DBLOCK|Block Size|0|None|100
-ParameterBoolean|BLOG                   |Logarithmic Transformation|True
-ParameterNumber|NUGGET|Nugget|None|None|0.0
-ParameterNumber|SILL|Sill|None|None|0.0
-ParameterNumber|RANGE|Range|None|None|0.0
-ParameterNumber|LIN_B|Linear Regression|None|None|1.0
-ParameterNumber|EXP_B|Exponential Regression|None|None|0.1
-ParameterNumber|POW_A|Power Function - A|None|None|1
-ParameterNumber|POW_B|Power Function - B|None|None|0.5
-ParameterMultipleInput|GRIDS|Grids|3.0|False
+ParameterNumber|VAR_MAXDIST|Maximum Distance|None|None|-1.0
+ParameterNumber|VAR_NCLASSES|Lag Distance Classes|1|None|100
+ParameterNumber|VAR_NSKIP|Skip|1|None|1
+ParameterString|VAR_MODEL|Variogram Model|a + b * x
+ParameterMultipleInput|GRIDS|Input Grids|3|True
 ParameterSelection|INTERPOL|Grid Interpolation|[0] Nearest Neighbor;[1] Bilinear Interpolation;[2] Inverse Distance Interpolation;[3] Bicubic Spline Interpolation;[4] B-Spline Interpolation
-ParameterNumber|NPOINTS_MIN|Min.Number of m_Points|None|None|4
-ParameterNumber|NPOINTS_MAX|Max. Number of m_Points|None|None|20
-ParameterNumber|MAXRADIUS|Maximum Search Radius (map units)|None|None|1000.0
-ParameterNumber|USER_CELL_SIZE|Grid Size|0|None|1.0
-ParameterBoolean|USER_FIT_EXTENT        |Fit Extent|True
-Extent USER_X_EXTENT_MIN USER_X_EXTENT_MAX USER_Y_EXTENT_MIN USER_Y_EXTENT_MIN
-OutputRaster|GRID|Grid
-OutputRaster|VARIANCE|Variance
+ParameterBoolean|COORDS|Coordinates|False
+ParameterSelection|SEARCH_RANGE|Search Range|[0] local;[1] global
+ParameterNumber|SEARCH_RADIUS|Maximum Search Distance|0|None|1000
+ParameterSelection|SEARCH_POINTS_ALL|Number of Points|[0] maximum number of nearest points;[1] all points within search distance
+ParameterNumber|SEARCH_POINTS_MIN|Minimum|1|None|4
+ParameterNumber|SEARCH_POINTS_MAX|Maximum|1|None|20
+ParameterSelection|SEARCH_DIRECTION|Search Direction|[0] all directions;[1] quadrants
+ParameterBoolean|USER_BVARIANCE|Create Quality Grid|True
+Extent USER_XMIN USER_XMAX USER_YMIN USER_YMAX
+ParameterNumber|USER_SIZE|Grid Size|0|None|100.0
+ParameterSelection|USER_FIT|Search Direction|[0] nodes;[1] cells
+OutputRaster|USER_GRID|Grid
+OutputRaster|USER_VARIANCE|Variance
diff --git a/resources/function_help/lpad b/resources/function_help/lpad
index b751f90..00a4fd8 100644
--- a/resources/function_help/lpad
+++ b/resources/function_help/lpad
@@ -10,8 +10,8 @@ using the fill character.
 <br>
 <code>length</code> - is int. The length of the new string.
 <br>
-<code>fill</code> - is char. The character to padd the remaining space with. 
+<code>fill</code> - is char. The character to pad the remaining space with.
 
 <h4>Example</h4>
 <!-- Show example of function.-->
-<code>lpad('Hello', 10, 'x') → 'Helloxxxxx'</code><br>
+<code>lpad('Hello', 10, 'x') → 'xxxxxHello'</code><br>
diff --git a/resources/function_help/rpad b/resources/function_help/rpad
index 326ac2f..a9c61d5 100644
--- a/resources/function_help/rpad
+++ b/resources/function_help/rpad
@@ -10,9 +10,9 @@ using the fill character.
 <br>
 <code>width</code> - is int. The length of the new string.
 <br>
-<code>fill</code> - is char. The character to padd the remaining space with. 
+<code>fill</code> - is char. The character to pad the remaining space with.
 
 <h4>Example</h4>
 <!-- Show example of function.-->
-<code>rpad('Hello', 10, 'x') → 'xxxxxHello'</code><br>
+<code>rpad('Hello', 10, 'x') → 'Helloxxxxx'</code><br>
 
diff --git a/scripts/release.pl b/scripts/release.pl
index 7966ed6..78a3b0c 100755
--- a/scripts/release.pl
+++ b/scripts/release.pl
@@ -125,8 +125,10 @@ if( $domajor ) {
 	pod2usage("No version change");
 }
 
-pod2usage("Splash images/splash/splash-$newmajor.$newminor.png not found") unless -r "images/splash/splash-$newmajor.$newminor.png";
-pod2usage("NSIS image ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp not found") unless -r "ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp";
+unless( $dopoint ) {
+	pod2usage("Splash images/splash/splash-$newmajor.$newminor.png not found") unless -r "images/splash/splash-$newmajor.$newminor.png";
+	pod2usage("NSIS image ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp not found") unless -r "ms-windows/Installer-Files/WelcomeFinishPage-$newmajor.$newminor.bmp";
+}
 
 print "Last pull rebase...\n";
 run( "git pull --rebase", "git pull rebase failed" );
diff --git a/src/app/composer/qgscomposer.cpp b/src/app/composer/qgscomposer.cpp
index eb375c0..5937592 100644
--- a/src/app/composer/qgscomposer.cpp
+++ b/src/app/composer/qgscomposer.cpp
@@ -1866,6 +1866,12 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
 
     mView->setPaintingEnabled( false );
 
+    int worldFilePageNo = -1;
+    if ( mComposition->generateWorldFile() && mComposition->worldFileMap() )
+    {
+      worldFilePageNo = mComposition->worldFileMap()->page() - 1;
+    }
+
     for ( int i = 0; i < mComposition->numPages(); ++i )
     {
       if ( !mComposition->shouldExportPage( i + 1 ) )
@@ -1885,16 +1891,19 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
         return;
       }
       bool saveOk;
+      QString outputFilePath;
       if ( i == 0 )
       {
-        saveOk = image.save( fileNExt.first, fileNExt.second.toLocal8Bit().constData() );
+        outputFilePath = fileNExt.first;
       }
       else
       {
         QFileInfo fi( fileNExt.first );
-        QString outputFilePath = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
-        saveOk = image.save( outputFilePath, fileNExt.second.toLocal8Bit().constData() );
+        outputFilePath = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
       }
+
+      saveOk = image.save( outputFilePath, fileNExt.second.toLocal8Bit().constData() );
+
       if ( !saveOk )
       {
         QMessageBox::warning( this, tr( "Image export error" ),
@@ -1904,21 +1913,20 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
         mView->setPaintingEnabled( true );
         return;
       }
-    }
 
-    //
-    // Write the world file if asked to
-    if ( mComposition->generateWorldFile() )
-    {
-      double a, b, c, d, e, f;
-      mComposition->computeWorldFileParameters( a, b, c, d, e, f );
+      if ( i == worldFilePageNo )
+      {
+        // should generate world file for this page
+        double a, b, c, d, e, f;
+        mComposition->computeWorldFileParameters( a, b, c, d, e, f );
 
-      QFileInfo fi( fileNExt.first );
-      // build the world file name
-      QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
-                              + fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";
+        QFileInfo fi( outputFilePath );
+        // build the world file name
+        QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
+                                + fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";
 
-      writeWorldFile( worldFileName, a, b, c, d, e, f );
+        writeWorldFile( worldFileName, a, b, c, d, e, f );
+      }
     }
 
     mView->setPaintingEnabled( true );
@@ -1946,6 +1954,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
     QFileDialog dlg( this, tr( "Directory where to save image files" ) );
     dlg.setFileMode( QFileDialog::Directory );
     dlg.setOption( QFileDialog::ShowDirsOnly, true );
+    dlg.setDirectory( lastUsedDir );
 
     //
     // Build an augmented FileDialog with a combo box to select the output format
@@ -2043,6 +2052,12 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
 
       QString filename = QDir( dir ).filePath( atlasMap->currentFilename() ) + fileExt;
 
+      int worldFilePageNo = -1;
+      if ( mComposition->generateWorldFile() && mComposition->worldFileMap() )
+      {
+        worldFilePageNo = mComposition->worldFileMap()->page() - 1;
+      }
+
       for ( int i = 0; i < mComposition->numPages(); ++i )
       {
         if ( !mComposition->shouldExportPage( i + 1 ) )
@@ -2070,21 +2085,20 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
           QApplication::restoreOverrideCursor();
           return;
         }
-      }
 
-      //
-      // Write the world file if asked to
-      if ( mComposition->generateWorldFile() )
-      {
-        double a, b, c, d, e, f;
-        mComposition->computeWorldFileParameters( a, b, c, d, e, f );
+        if ( i == worldFilePageNo )
+        {
+          // should generate world file for this page
+          double a, b, c, d, e, f;
+          mComposition->computeWorldFileParameters( a, b, c, d, e, f );
 
-        QFileInfo fi( filename );
-        // build the world file name
-        QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
-                                + fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";
+          QFileInfo fi( imageFilename );
+          // build the world file name
+          QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
+                                  + fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";
 
-        writeWorldFile( worldFileName, a, b, c, d, e, f );
+          writeWorldFile( worldFileName, a, b, c, d, e, f );
+        }
       }
     }
     atlasMap->endRender();
diff --git a/src/app/composer/qgscomposerscalebarwidget.cpp b/src/app/composer/qgscomposerscalebarwidget.cpp
index 52879ec..5e7aa68 100644
--- a/src/app/composer/qgscomposerscalebarwidget.cpp
+++ b/src/app/composer/qgscomposerscalebarwidget.cpp
@@ -596,6 +596,11 @@ void QgsComposerScaleBarWidget::on_mUnitsComboBox_currentIndexChanged( int index
   }
 
   mComposerScaleBar->update();
+
+  mUnitLabelLineEdit->setText( mComposerScaleBar->unitLabeling() );
+  mSegmentSizeSpinBox->setValue( mComposerScaleBar->numUnitsPerSegment() );
+  mMapUnitsPerBarUnitSpinBox->setValue( mComposerScaleBar->numMapUnitsPerScaleBarUnit() );
+
   connectUpdateSignal();
   mComposerScaleBar->endCommand();
 }
diff --git a/src/app/ogr/qgsopenvectorlayerdialog.cpp b/src/app/ogr/qgsopenvectorlayerdialog.cpp
index be87d2e..5b26920 100644
--- a/src/app/ogr/qgsopenvectorlayerdialog.cpp
+++ b/src/app/ogr/qgsopenvectorlayerdialog.cpp
@@ -271,7 +271,9 @@ void QgsOpenVectorLayerDialog::on_buttonSelectSrc_clicked()
 {
   if ( radioSrcFile->isChecked() )
   {
-    inputSrcDataset->setText( openFile().join( ";" ) );
+    QStringList selected = openFile();
+    if ( selected.count() > 0 )
+      inputSrcDataset->setText( selected.join( ";" ) );
   }
   else if ( radioSrcDirectory->isChecked() )
   {
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index c8b140b..dc1af67 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -864,6 +864,7 @@ QgisApp::QgisApp()
     , mToolPopupOverviews( 0 )
     , mToolPopupDisplay( 0 )
     , mMapCanvas( 0 )
+    , mOverviewCanvas( 0 )
     , mLayerTreeView( 0 )
     , mLayerTreeCanvasBridge( 0 )
     , mMapLayerOrder( 0 )
@@ -2282,25 +2283,33 @@ void QgisApp::createCanvasTools()
 void QgisApp::createOverview()
 {
   // overview canvas
-  QgsMapOverviewCanvas* overviewCanvas = new QgsMapOverviewCanvas( NULL, mMapCanvas );
-  overviewCanvas->setWhatsThis( tr( "Map overview canvas. This canvas can be used to display a locator map that shows the current extent of the map canvas. The current extent is shown as a red rectangle. Any layer on the map can be added to the overview canvas." ) );
+  mOverviewCanvas = new QgsMapOverviewCanvas( NULL, mMapCanvas );
+
+  //set canvas color to default
+  QSettings settings;
+  int red = settings.value( "/qgis/default_canvas_color_red", 255 ).toInt();
+  int green = settings.value( "/qgis/default_canvas_color_green", 255 ).toInt();
+  int blue = settings.value( "/qgis/default_canvas_color_blue", 255 ).toInt();
+  mOverviewCanvas->setBackgroundColor( QColor( red, green, blue ) );
+
+  mOverviewCanvas->setWhatsThis( tr( "Map overview canvas. This canvas can be used to display a locator map that shows the current extent of the map canvas. The current extent is shown as a red rectangle. Any layer on the map can be added to the overview canvas." ) );
 
   QBitmap overviewPanBmp = QBitmap::fromData( QSize( 16, 16 ), pan_bits );
   QBitmap overviewPanBmpMask = QBitmap::fromData( QSize( 16, 16 ), pan_mask_bits );
   mOverviewMapCursor = new QCursor( overviewPanBmp, overviewPanBmpMask, 0, 0 ); //set upper left corner as hot spot - this is better when extent marker is small; hand won't cover the marker
-  overviewCanvas->setCursor( *mOverviewMapCursor );
+  mOverviewCanvas->setCursor( *mOverviewMapCursor );
 //  QVBoxLayout *myOverviewLayout = new QVBoxLayout;
 //  myOverviewLayout->addWidget(overviewCanvas);
 //  overviewFrame->setLayout(myOverviewLayout);
   mOverviewDock = new QDockWidget( tr( "Overview" ), this );
   mOverviewDock->setObjectName( "Overview" );
   mOverviewDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
-  mOverviewDock->setWidget( overviewCanvas );
+  mOverviewDock->setWidget( mOverviewCanvas );
   addDockWidget( Qt::LeftDockWidgetArea, mOverviewDock );
   // add to the Panel submenu
   mPanelMenu->addAction( mOverviewDock->toggleViewAction() );
 
-  mMapCanvas->enableOverviewMode( overviewCanvas );
+  mMapCanvas->enableOverviewMode( mOverviewCanvas );
 
   // moved here to set anti aliasing to both map canvas and overview
   QSettings mySettings;
@@ -3631,6 +3640,7 @@ void QgisApp::fileNew( bool thePromptToSaveFlag, bool forceBlank )
   prj->writeEntry( "Gui", "/CanvasColorGreenPart", myGreen );
   prj->writeEntry( "Gui", "/CanvasColorBluePart", myBlue );
   mMapCanvas->setCanvasColor( QColor( myRed, myGreen, myBlue ) );
+  mOverviewCanvas->setBackgroundColor( QColor( myRed, myGreen, myBlue ) );
 
   prj->dirty( false );
 
@@ -4008,7 +4018,14 @@ bool QgisApp::addProject( QString projectFile )
   int  myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
   QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt );
   mMapCanvas->setCanvasColor( myColor ); //this is fill color before rendering starts
+  mOverviewCanvas->setBackgroundColor( myColor );
+
   QgsDebugMsg( "Canvas background color restored..." );
+  myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
+  myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
+  myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
+  myColor = QColor( myRedInt, myGreenInt, myBlueInt );
+  mMapCanvas->setSelectionColor( myColor ); //this is selection color before rendering starts
 
   //load project scales
   bool projectScales = QgsProject::instance()->readBoolEntry( "Scales", "/useProjectScales" );
@@ -5883,14 +5900,36 @@ void QgisApp::mergeAttributesOfSelectedFeatures()
 
   vl->beginEditCommand( tr( "Merged feature attributes" ) );
 
-  const QgsAttributes &merged = d.mergedAttributes();
+  QgsAttributes merged = d.mergedAttributes();
+  QSet<int> toSkip = d.skippedAttributeIndexes();
 
-  foreach ( QgsFeatureId fid, vl->selectedFeaturesIds() )
+  bool firstFeature = true;
+  Q_FOREACH ( QgsFeatureId fid, vl->selectedFeaturesIds() )
   {
     for ( int i = 0; i < merged.count(); ++i )
     {
-      vl->changeAttributeValue( fid, i, merged.at( i ) );
+      if ( toSkip.contains( i ) )
+        continue;
+
+      QVariant val = merged.at( i );
+      // convert to destination data type
+      if ( ! vl->pendingFields()[i].convertCompatible( val ) )
+      {
+        if ( firstFeature )
+        {
+          //only warn on first feature
+          messageBar()->pushMessage(
+            tr( "Invalid result" ),
+            tr( "Could not store value '%1' in field of type %2" ).arg( merged.at( i ).toString(), vl->pendingFields()[i].typeName() ),
+            QgsMessageBar::WARNING );
+        }
+      }
+      else
+      {
+        vl->changeAttributeValue( fid, i, val );
+      }
     }
+    firstFeature = false;
   }
 
   vl->endEditCommand();
@@ -6005,7 +6044,22 @@ void QgisApp::mergeSelectedFeatures()
   //create new feature
   QgsFeature newFeature;
   newFeature.setGeometry( unionGeom );
-  newFeature.setAttributes( d.mergedAttributes() );
+
+  QgsAttributes attrs = d.mergedAttributes();
+  for ( int i = 0; i < attrs.count(); ++i )
+  {
+    QVariant val = attrs.at( i );
+    // convert to destination data type
+    if ( ! vl->pendingFields()[i].convertCompatible( val ) )
+    {
+      messageBar()->pushMessage(
+        tr( "Invalid result" ),
+        tr( "Could not store value '%1' in field of type %2" ).arg( attrs.at( i ).toString(), vl->pendingFields()[i].typeName() ),
+        QgsMessageBar::WARNING );
+    }
+    attrs[i] = val;
+  }
+  newFeature.setAttributes( attrs );
 
   QgsFeatureIds::const_iterator feature_it = featureIdsAfter.constBegin();
   for ( ; feature_it != featureIdsAfter.constEnd(); ++feature_it )
@@ -9086,12 +9140,6 @@ void QgisApp::projectProperties()
   // Display the modal dialog box.
   pp->exec();
 
-  int  myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorRedPart", 255 );
-  int  myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorGreenPart", 255 );
-  int  myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
-  QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt );
-  mMapCanvas->setCanvasColor( myColor ); // this is fill color before rendering onto canvas
-
   qobject_cast<QgsMeasureTool*>( mMapTools.mMeasureDist )->updateSettings();
   qobject_cast<QgsMeasureTool*>( mMapTools.mMeasureArea )->updateSettings();
   qobject_cast<QgsMapToolMeasureAngle*>( mMapTools.mMeasureAngle )->updateSettings();
diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h
index 8815efd..deb6214 100644
--- a/src/app/qgisapp.h
+++ b/src/app/qgisapp.h
@@ -55,6 +55,7 @@ class QgsMapLayer;
 class QgsMapTip;
 class QgsMapTool;
 class QgsMapToolAdvancedDigitizing;
+class QgsMapOverviewCanvas;
 class QgsPoint;
 class QgsProviderRegistry;
 class QgsPythonUtils;
@@ -432,6 +433,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
     //! return CAD dock widget
     QgsAdvancedDigitizingDockWidget *cadDockWidget() { return mAdvancedDigitizingDockWidget; }
 
+    //! Returns map overview canvas
+    QgsMapOverviewCanvas* mapOverviewCanvas() { return mOverviewCanvas; }
+
     //! show layer properties
     void showLayerProperties( QgsMapLayer *ml );
 
@@ -1534,6 +1538,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
     QMenu *mToolPopupDisplay;
     //! Map canvas
     QgsMapCanvas *mMapCanvas;
+    //! Overview map canvas
+    QgsMapOverviewCanvas *mOverviewCanvas;
     //! Table of contents (legend) for the map
     QgsLayerTreeView *mLayerTreeView;
     //! Helper class that connects layer tree with map canvas
diff --git a/src/app/qgsattributetabledialog.cpp b/src/app/qgsattributetabledialog.cpp
index 7fac260..8dff22a 100644
--- a/src/app/qgsattributetabledialog.cpp
+++ b/src/app/qgsattributetabledialog.cpp
@@ -438,7 +438,6 @@ void QgsAttributeTableDialog::filterShowAll()
   mFilterQuery->setVisible( false );
   mApplyFilterButton->setVisible( false );
   mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowAll );
-  updateTitle();
 }
 
 void QgsAttributeTableDialog::filterSelected()
@@ -707,7 +706,6 @@ void QgsAttributeTableDialog::filterQueryChanged( const QString& query )
   }
 
   setFilterExpression( str );
-  updateTitle();
 }
 
 void QgsAttributeTableDialog::filterQueryAccepted()
@@ -786,4 +784,5 @@ void QgsAttributeTableDialog::setFilterExpression( QString filterString )
     QgisApp::instance()->messageBar()->pushMessage( tr( "Error filtering" ), filterExpression.evalErrorString(), QgsMessageBar::WARNING, QgisApp::instance()->messageTimeout() );
     return;
   }
+  mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
 }
diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp
index 5f45b49..224e93d 100644
--- a/src/app/qgsidentifyresultsdialog.cpp
+++ b/src/app/qgsidentifyresultsdialog.cpp
@@ -1571,7 +1571,7 @@ void QgsIdentifyResultsDialog::featureForm()
   if ( !featItem )
     return;
 
-  int fid = STRING_TO_FID( featItem->data( 0, Qt::UserRole ) );
+  QgsFeatureId fid = STRING_TO_FID( featItem->data( 0, Qt::UserRole ) );
   int idx = featItem->data( 0, Qt::UserRole + 1 ).toInt();
 
   QgsFeature f;
diff --git a/src/app/qgsmaptoolcapture.cpp b/src/app/qgsmaptoolcapture.cpp
index 9fb23b5..1d9ec72 100644
--- a/src/app/qgsmaptoolcapture.cpp
+++ b/src/app/qgsmaptoolcapture.cpp
@@ -259,6 +259,13 @@ void QgsMapToolCapture::canvasKeyPressEvent( QKeyEvent* e )
     // Override default shortcut management in MapCanvas
     e->ignore();
   }
+  else if ( e->key() == Qt::Key_Escape )
+  {
+    stopCapturing();
+
+    // Override default shortcut management in MapCanvas
+    e->ignore();
+  }
 }
 
 void QgsMapToolCapture::startCapturing()
diff --git a/src/app/qgsmaptoolfillring.cpp b/src/app/qgsmaptoolfillring.cpp
index 47167de..f6b4a73 100644
--- a/src/app/qgsmaptoolfillring.cpp
+++ b/src/app/qgsmaptoolfillring.cpp
@@ -79,7 +79,10 @@ void QgsMapToolFillRing::canvasMapReleaseEvent( QgsMapMouseEvent * e )
     closePolygon();
 
     vlayer->beginEditCommand( tr( "Ring added and filled" ) );
-    int addRingReturnCode = vlayer->addRing( points() );
+    QList< QgsPoint > pointList = points();
+
+    QgsFeatureId modifiedFid;
+    int addRingReturnCode = vlayer->addRing( pointList, &modifiedFid );
     if ( addRingReturnCode != 0 )
     {
       QString errorMessage;
@@ -122,42 +125,29 @@ void QgsMapToolFillRing::canvasMapReleaseEvent( QgsMapMouseEvent * e )
       yMin = std::numeric_limits<double>::max();
       yMax = -std::numeric_limits<double>::max();
 
-      for ( QList<QgsPoint>::const_iterator it = points().constBegin(); it != points().constEnd(); ++it )
+      Q_FOREACH ( const QgsPoint& point, pointList )
       {
-        if ( it->x() < xMin )
-        {
-          xMin = it->x();
-        }
-        if ( it->x() > xMax )
-        {
-          xMax = it->x();
-        }
-        if ( it->y() < yMin )
-        {
-          yMin = it->y();
-        }
-        if ( it->y() > yMax )
-        {
-          yMax = it->y();
-        }
+        xMin = qMin( xMin, point.x() );
+        xMax = qMax( xMax, point.x() );
+        yMin = qMin( yMin, point.y() );
+        yMax = qMax( yMax, point.y() );
       }
+
       bBox.setXMinimum( xMin );
       bBox.setYMinimum( yMin );
       bBox.setXMaximum( xMax );
       bBox.setYMaximum( yMax );
 
-      QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
+      QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterFid( modifiedFid ) );
 
       QgsFeature f;
       bool res = false;
-      while ( fit.nextFeature( f ) )
+      if ( fit.nextFeature( f ) )
       {
         //create QgsFeature with wkb representation
         QgsFeature* ft = new QgsFeature( vlayer->pendingFields(), 0 );
 
-        QgsGeometry *g;
-        g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
-        ft->setGeometry( g );
+        ft->setGeometry( QgsGeometry::fromPolygon( QgsPolygon() << pointList.toVector() ) );
         ft->setAttributes( f.attributes() );
 
         if ( QgsApplication::keyboardModifiers() == Qt::ControlModifier )
diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp
index 15066b5..8f7bc4b 100644
--- a/src/app/qgsmergeattributesdialog.cpp
+++ b/src/app/qgsmergeattributesdialog.cpp
@@ -585,8 +585,6 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
     return QgsAttributes();
   }
 
-  QgsFields fields = mVectorLayer->pendingFields();
-
   QgsAttributes results( mTableWidget->columnCount() );
   for ( int i = 0; i < mTableWidget->columnCount(); i++ )
   {
@@ -603,7 +601,7 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
     if ( idx >= results.count() )
       results.resize( idx + 1 ); // make sure the results vector is long enough (maybe not necessary)
 
-    if ( comboBox->itemData( comboBox->currentIndex() ) != "skip" )
+    if ( comboBox->itemData( comboBox->currentIndex() ).toString() != "skip" )
     {
       results[idx] = currentItem->data( Qt::DisplayRole );
     }
@@ -615,3 +613,25 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
 
   return results;
 }
+
+QSet<int> QgsMergeAttributesDialog::skippedAttributeIndexes() const
+{
+  QSet<int> skipped;
+  for ( int i = 0; i < mTableWidget->columnCount(); ++i )
+  {
+    QComboBox *comboBox = qobject_cast<QComboBox *>( mTableWidget->cellWidget( 0, i ) );
+    if ( !comboBox )
+    {
+      //something went wrong, better skip this attribute
+      skipped << i;
+      continue;
+    }
+
+    if ( comboBox->itemData( comboBox->currentIndex() ).toString() == "skip" )
+    {
+      skipped << i;
+    }
+  }
+
+  return skipped;
+}
diff --git a/src/app/qgsmergeattributesdialog.h b/src/app/qgsmergeattributesdialog.h
index 8a020fb..df33209 100644
--- a/src/app/qgsmergeattributesdialog.h
+++ b/src/app/qgsmergeattributesdialog.h
@@ -37,6 +37,11 @@ class APP_EXPORT QgsMergeAttributesDialog: public QDialog, private Ui::QgsMergeA
     ~QgsMergeAttributesDialog();
     QgsAttributes mergedAttributes() const;
 
+    /** Returns a list of attribute indexes which should be skipped when merging (eg, attributes
+     * which have been set to "skip"
+     */
+    QSet<int> skippedAttributeIndexes() const;
+
   private slots:
     void comboValueChanged( const QString & text );
     void selectedRowChanged();
diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp
index 38345da..c58957b 100644
--- a/src/app/qgsprojectproperties.cpp
+++ b/src/app/qgsprojectproperties.cpp
@@ -49,6 +49,7 @@
 #include "qgscolorschemeregistry.h"
 #include "qgssymbollayerv2utils.h"
 #include "qgscolordialog.h"
+#include "qgsmapoverviewcanvas.h"
 
 //qt includes
 #include <QInputDialog>
@@ -271,7 +272,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
   mWMSUrlLineEdit->setText( QgsProject::instance()->readEntry( "WMSUrl", "/", "" ) );
   mWMSFees->setText( QgsProject::instance()->readEntry( "WMSFees", "/", "" ) );
   mWMSAccessConstraints->setText( QgsProject::instance()->readEntry( "WMSAccessConstraints", "/", "" ) );
-  mWMSKeywordList->setText( QgsProject::instance()->readListEntry( "WMSKeywordList", "/" ).join( "," ) );
+  mWMSKeywordList->setText( QgsProject::instance()->readListEntry( "WMSKeywordList", "/" ).join( ", " ) );
 
   // WMS GetFeatureInfo precision
   int WMSprecision = QgsProject::instance()->readNumEntry( "WMSPrecision", "/", -1 );
@@ -678,6 +679,8 @@ void QgsProjectProperties::apply()
   QgsProject::instance()->writeEntry( "Gui", "/CanvasColorGreenPart", myColor.green() );
   QgsProject::instance()->writeEntry( "Gui", "/CanvasColorBluePart", myColor.blue() );
   mMapCanvas->setCanvasColor( myColor );
+  QgisApp::instance()->mapOverviewCanvas()->setBackgroundColor( myColor );
+  QgisApp::instance()->mapOverviewCanvas()->refresh();
 
   //save project scales
   QStringList myScales;
@@ -734,7 +737,8 @@ void QgsProjectProperties::apply()
   QStringList keywordStringList = mWMSKeywordList->text().split( "," );
   if ( keywordStringList.size() > 0 )
   {
-    QgsProject::instance()->writeEntry( "WMSKeywordList", "/", mWMSKeywordList->text().split( "," ) );
+    keywordStringList.replaceInStrings( QRegExp( "^\\s+" ), "" ).replaceInStrings( QRegExp( "\\s+$" ), "" );
+    QgsProject::instance()->writeEntry( "WMSKeywordList", "/", keywordStringList );
   }
   else
   {
diff --git a/src/app/qgssnappingdialog.cpp b/src/app/qgssnappingdialog.cpp
index 7475eeb..4d04694 100644
--- a/src/app/qgssnappingdialog.cpp
+++ b/src/app/qgssnappingdialog.cpp
@@ -505,5 +505,6 @@ void QgsSnappingDialog::setSnappingMode()
     mSnapModeComboBox->setCurrentIndex( 1 );
   else // "advanced" or empty (backward compatibility)
     mSnapModeComboBox->setCurrentIndex( 2 );
+  onSnappingModeIndexChanged( mSnapModeComboBox->currentIndex() );
   mSnapModeComboBox->blockSignals( false );
 }
diff --git a/src/app/qgstipfactory.cpp b/src/app/qgstipfactory.cpp
index 75d43d0..2ff98b8 100644
--- a/src/app/qgstipfactory.cpp
+++ b/src/app/qgstipfactory.cpp
@@ -57,7 +57,7 @@ QgsTipFactory::QgsTipFactory() : QObject()
   myTip.setTitle( tr( "QGIS Mailing lists" ) );
   myTip.setContent( tr( "If you need help using QGIS"
                         " we have a 'users' mailing list where users help each other with issues"
-                        " related to using our sofware. We also have a 'developers' mailing list."
+                        " related to using our software. We also have a 'developers' mailing list."
                         " for those wanting help and to discuss things relating to the QGIS code base."
                         " Details on how to subscribe are in the <a href=\"http://qgis.org/en/site/forusers/support.html#mailing-lists\">community section</a> of"
                         " the QGIS home page."
diff --git a/src/core/composer/qgscomposerscalebar.cpp b/src/core/composer/qgscomposerscalebar.cpp
index 18ef07b..1202fdb 100644
--- a/src/core/composer/qgscomposerscalebar.cpp
+++ b/src/core/composer/qgscomposerscalebar.cpp
@@ -209,14 +209,24 @@ double QgsComposerScaleBar::mapWidth() const
     da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
     da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
 
-    double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
-    if ( mUnits == QgsComposerScaleBar::Feet )
-    {
-      measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters );
-    }
-    else if ( mUnits == QgsComposerScaleBar::NauticalMiles )
+    QGis::UnitType units = QGis::Meters;
+    double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ),
+                                     QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ),
+                                     units );
+    switch ( mUnits )
     {
-      measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters );
+      case QgsComposerScaleBar::Feet:
+        measure /= QGis::fromUnitToUnitFactor( QGis::Feet, units );
+        break;
+      case QgsComposerScaleBar::NauticalMiles:
+        measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, units );
+        break;
+      case QgsComposerScaleBar::Meters:
+        measure /= QGis::fromUnitToUnitFactor( QGis::Meters, units );
+        break;
+      case QgsComposerScaleBar::MapUnits:
+        //avoid warning
+        break;
     }
     return measure;
   }
diff --git a/src/core/composer/qgscomposition.cpp b/src/core/composer/qgscomposition.cpp
index c3dda8b..2573229 100644
--- a/src/core/composer/qgscomposition.cpp
+++ b/src/core/composer/qgscomposition.cpp
@@ -2827,35 +2827,38 @@ QGraphicsView *QgsComposition::graphicsView() const
 
 void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const
 {
-  //
-  // Word file parameters : affine transformation parameters from pixel coordinates to map coordinates
+  // World file parameters : affine transformation parameters from pixel coordinates to map coordinates
 
   if ( !mWorldFileMap )
   {
     return;
   }
 
-  QRectF brect = mWorldFileMap->mapRectToScene( mWorldFileMap->rect() );
-  QgsRectangle extent = *mWorldFileMap->currentMapExtent();
+  double destinationHeight = paperHeight();
+  double destinationWidth = paperWidth();
+
+  QRectF mapItemSceneRect = mWorldFileMap->mapRectToScene( mWorldFileMap->rect() );
+  QgsRectangle mapExtent = *mWorldFileMap->currentMapExtent();
 
   double alpha = mWorldFileMap->mapRotation() / 180 * M_PI;
 
-  double xr = extent.width() / brect.width();
-  double yr = extent.height() / brect.height();
+  double xRatio = mapExtent.width() / mapItemSceneRect.width();
+  double yRatio = mapExtent.height() / mapItemSceneRect.height();
 
-  double XC = extent.center().x();
-  double YC = extent.center().y();
+  double xCenter = mapExtent.center().x();
+  double yCenter = mapExtent.center().y();
 
-  // get the extent for the page
-  double xmin = extent.xMinimum() - mWorldFileMap->pos().x() * xr;
-  double ymax = extent.yMaximum() + mWorldFileMap->pos().y() * yr;
-  QgsRectangle paperExtent( xmin, ymax - paperHeight() * yr, xmin + paperWidth() * xr, ymax );
+  // get the extent (in map units) for the page
+  QPointF mapItemPosOnPage = mWorldFileMap->pagePos();
+  double xmin = mapExtent.xMinimum() - mapItemPosOnPage.x() * xRatio;
+  double ymax = mapExtent.yMaximum() + mapItemPosOnPage.y() * yRatio;
+  QgsRectangle paperExtent( xmin, ymax - destinationHeight * yRatio, xmin + destinationWidth * xRatio, ymax );
 
   double X0 = paperExtent.xMinimum();
   double Y0 = paperExtent.yMinimum();
 
-  int widthPx = ( int )( printResolution() * paperWidth() / 25.4 );
-  int heightPx = ( int )( printResolution() * paperHeight() / 25.4 );
+  int widthPx = ( int )( printResolution() * destinationWidth / 25.4 );
+  int heightPx = ( int )( printResolution() * destinationHeight / 25.4 );
 
   double Ww = paperExtent.width() / widthPx;
   double Hh = paperExtent.height() / heightPx;
@@ -2873,10 +2876,10 @@ void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c
   double r[6];
   r[0] = cos( alpha );
   r[1] = -sin( alpha );
-  r[2] = XC * ( 1 - cos( alpha ) ) + YC * sin( alpha );
+  r[2] = xCenter * ( 1 - cos( alpha ) ) + yCenter * sin( alpha );
   r[3] = sin( alpha );
   r[4] = cos( alpha );
-  r[5] = - XC * sin( alpha ) + YC * ( 1 - cos( alpha ) );
+  r[5] = - xCenter * sin( alpha ) + yCenter * ( 1 - cos( alpha ) );
 
   // result = rotation x scaling = rotation(scaling(X))
   a = r[0] * s[0] + r[1] * s[3];
diff --git a/src/core/qgis.h b/src/core/qgis.h
index 392e42d..82b5934 100644
--- a/src/core/qgis.h
+++ b/src/core/qgis.h
@@ -351,6 +351,14 @@ inline bool qgsDoubleNearSig( double a, double b, int significantDigits = 10 )
          qRound( ar * pow( 10.0, significantDigits ) ) == qRound( br * pow( 10.0, significantDigits ) );
 }
 
+//
+// a round function which returns a double to guard against overflows
+//
+inline double qgsRound( double x )
+{
+  return x < 0.0 ? std::ceil( x - 0.5 ) : std::floor( x + 0.5 );
+}
+
 bool qgsVariantLessThan( const QVariant& lhs, const QVariant& rhs );
 
 bool qgsVariantGreaterThan( const QVariant& lhs, const QVariant& rhs );
diff --git a/src/core/qgsdistancearea.cpp b/src/core/qgsdistancearea.cpp
index b0697e3..4ecc860 100644
--- a/src/core/qgsdistancearea.cpp
+++ b/src/core/qgsdistancearea.cpp
@@ -461,7 +461,14 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint> &points )
 
 double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
 {
+  QGis::UnitType units;
+  return measureLine( p1, p2, units );
+}
+
+double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units )
+{
   double result;
+  units = mCoordTransform->sourceCrs().mapUnits();
 
   try
   {
@@ -470,6 +477,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
     QgsDebugMsgLevel( QString( "Measuring from %1 to %2" ).arg( p1.toString( 4 ) ).arg( p2.toString( 4 ) ), 3 );
     if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
     {
+      units = QGis::Meters;
       QgsDebugMsgLevel( QString( "Ellipsoidal calculations is enabled, using ellipsoid %1" ).arg( mEllipsoid ), 4 );
       QgsDebugMsgLevel( QString( "From proj4 : %1" ).arg( mCoordTransform->sourceCrs().toProj4() ), 4 );
       QgsDebugMsgLevel( QString( "To   proj4 : %1" ).arg( mCoordTransform->destCRS().toProj4() ), 4 );
diff --git a/src/core/qgsdistancearea.h b/src/core/qgsdistancearea.h
index 5c43c22..955e40d 100644
--- a/src/core/qgsdistancearea.h
+++ b/src/core/qgsdistancearea.h
@@ -95,9 +95,23 @@ class CORE_EXPORT QgsDistanceArea
     //! measures line
     double measureLine( const QList<QgsPoint>& points );
 
-    //! measures line with one segment
+    /** Measures length of line with one segment
+     * @param p1 start of line
+     * @param p2 end of line
+     * @returns distance in meters, or map units if cartesian calculation was performed
+     */
     double measureLine( const QgsPoint& p1, const QgsPoint& p2 );
 
+    /** Measures length of line with one segment and returns units of distance.
+     * @param p1 start of line
+     * @param p2 end of line
+     * @param units will be set to units of measure
+     * @returns calculated distance between points. Distance units are stored in units parameter.
+     * @note backported from QGIS 2.12 (where it is const)
+     * @note not available in python bindings
+     */
+    double measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units );
+
     //! measures polygon area
     double measurePolygon( const QList<QgsPoint>& points );
 
diff --git a/src/core/qgserror.h b/src/core/qgserror.h
index ae37556..78827c4 100644
--- a/src/core/qgserror.h
+++ b/src/core/qgserror.h
@@ -108,7 +108,7 @@ class CORE_EXPORT QgsError
      */
     QString message( QgsErrorMessage::Format theFormat = QgsErrorMessage::Html ) const;
 
-    /** Short error descriprion, usually the first error in chain, the real error.
+    /** Short error description, usually the first error in chain, the real error.
      *  @return error description
      */
     QString summary() const;
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index c271856..8a9fc23 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -1095,20 +1095,17 @@ static QVariant fcnGeomFromWKT( const QVariantList& values, const QgsFeature*, Q
 {
   QString wkt = getStringValue( values.at( 0 ), parent );
   QgsGeometry* geom = QgsGeometry::fromWkt( wkt );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  else
-    return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnGeomFromGML( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QString gml = getStringValue( values.at( 0 ), parent );
   QgsGeometry* geom = QgsOgcUtils::geometryFromGML( gml );
-
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  else
-    return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 
 static QVariant fcnGeomArea( const QVariantList&, const QgsFeature* f, QgsExpression* parent )
@@ -1134,14 +1131,9 @@ static QVariant fcnBounds( const QVariantList& values, const QgsFeature*, QgsExp
 {
   QgsGeometry geom = getGeometry( values.at( 0 ), parent );
   QgsGeometry* geomBounds = QgsGeometry::fromRect( geom.boundingBox() );
-  if ( geomBounds )
-  {
-    return QVariant::fromValue( *geomBounds );
-  }
-  else
-  {
-    return QVariant();
-  }
+  QVariant result = geomBounds ? QVariant::fromValue( *geomBounds ) : QVariant();
+  delete geomBounds;
+  return result;
 }
 
 static QVariant fcnBoundsWidth( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
@@ -1240,34 +1232,34 @@ static QVariant fcnBuffer( const QVariantList& values, const QgsFeature*, QgsExp
     seg = getIntValue( values.at( 2 ), parent );
 
   QgsGeometry* geom = fGeom.buffer( dist, seg );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnCentroid( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry* geom = fGeom.centroid();
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnConvexHull( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry* geom = fGeom.convexHull();
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnDifference( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
   QgsGeometry* geom = fGeom.difference( &sGeom );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnDistance( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
@@ -1280,27 +1272,27 @@ static QVariant fcnIntersection( const QVariantList& values, const QgsFeature*,
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
   QgsGeometry* geom = fGeom.intersection( &sGeom );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnSymDifference( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
   QgsGeometry* geom = fGeom.symDifference( &sGeom );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnCombine( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
   QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
   QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
   QgsGeometry* geom = fGeom.combine( &sGeom );
-  if ( geom )
-    return QVariant::fromValue( *geom );
-  return QVariant();
+  QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant();
+  delete geom;
+  return result;
 }
 static QVariant fcnGeomToWKT( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
 {
diff --git a/src/core/qgsfeaturestore.cpp b/src/core/qgsfeaturestore.cpp
index 05caaf3..cc7668d 100644
--- a/src/core/qgsfeaturestore.cpp
+++ b/src/core/qgsfeaturestore.cpp
@@ -40,9 +40,10 @@ QgsFeatureStore::~QgsFeatureStore()
 void QgsFeatureStore::setFields( const QgsFields & fields )
 {
   mFields = fields;
-  foreach ( QgsFeature feature, mFeatures )
+  QgsFeatureList::iterator it = mFeatures.begin();
+  for ( ; it != mFeatures.end(); ++it )
   {
-    feature.setFields( &mFields );
+    ( *it ).setFields( &mFields );
   }
 }
 
diff --git a/src/core/qgsfeaturestore.h b/src/core/qgsfeaturestore.h
index 13f4fef..abe737d 100644
--- a/src/core/qgsfeaturestore.h
+++ b/src/core/qgsfeaturestore.h
@@ -45,7 +45,7 @@ class CORE_EXPORT QgsFeatureStore
     /** Get fields list */
     QgsFields& fields() { return mFields; }
 
-    /** Set fields. Resets feauters fields to pointer to new internal fields. */
+    /** Set fields. Resets feature's fields to pointer to new internal fields. */
     void setFields( const QgsFields & fields );
 
     /** Get crs */
diff --git a/src/core/qgsfield.cpp b/src/core/qgsfield.cpp
index bc207b3..4365d5d 100644
--- a/src/core/qgsfield.cpp
+++ b/src/core/qgsfield.cpp
@@ -18,6 +18,7 @@
 
 #include <QSettings>
 #include <QtCore/qmath.h>
+#include "qgis.h"
 
 #if 0
 QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
@@ -143,6 +144,30 @@ bool QgsField::convertCompatible( QVariant& v ) const
     return false;
   }
 
+  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
+  //work around this by first converting to double, and then checking whether the double is convertible to int
+  if ( mType == QVariant::Int && v.canConvert( QVariant::Double ) )
+  {
+    bool ok = false;
+    double dbl = v.toDouble( &ok );
+    if ( !ok )
+    {
+      //couldn't convert to number
+      v = QVariant( mType );
+      return false;
+    }
+
+    double round = qgsRound( dbl );
+    if ( round  > INT_MAX || round < -INT_MAX )
+    {
+      //double too large to fit in int
+      v = QVariant( mType );
+      return false;
+    }
+    v = QVariant( qRound( dbl ) );
+    return true;
+  }
+
   if ( !v.convert( mType ) )
   {
     v = QVariant( mType );
@@ -239,11 +264,16 @@ int QgsFields::fieldNameIndex( const QString& fieldName ) const
 {
   for ( int idx = 0; idx < count(); ++idx )
   {
+    if ( mFields[idx].field.name() == fieldName )
+      return idx;
+  }
+
+  for ( int idx = 0; idx < count(); ++idx )
+  {
     if ( QString::compare( mFields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
-    {
       return idx;
-    }
   }
+
   return -1;
 }
 
diff --git a/src/core/qgsfield.h b/src/core/qgsfield.h
index 0fab69c..6236ab3 100644
--- a/src/core/qgsfield.h
+++ b/src/core/qgsfield.h
@@ -238,8 +238,8 @@ class CORE_EXPORT QgsFields
     //! Look up field's index from name. Returns -1 on error
     int indexFromName( const QString& name ) const { return mNameToIndex.value( name, -1 ); }
 
-    //! Look up field's index from name - case insensitive
-    //! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
+    //! Look up field's index from name
+    //! also looks up case-insensitive if there is no match otherwise
     //! @note added in 2.4
     int fieldNameIndex( const QString& fieldName ) const;
 
diff --git a/src/core/qgsmaplayer.cpp b/src/core/qgsmaplayer.cpp
index 5babf69..815cf4f 100644
--- a/src/core/qgsmaplayer.cpp
+++ b/src/core/qgsmaplayer.cpp
@@ -1370,6 +1370,7 @@ void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg )
   // Create the root element
   QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
   root.setAttribute( "version", "1.1.0" );
+  root.setAttribute( "units", "mm" ); // default qgsmaprenderer is Millimeters
   root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
   root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
   root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
diff --git a/src/core/qgsmapunitscale.h b/src/core/qgsmapunitscale.h
index 336e2bf..d850913 100644
--- a/src/core/qgsmapunitscale.h
+++ b/src/core/qgsmapunitscale.h
@@ -21,17 +21,35 @@
 #include <QtCore>
 #include "qgsrendercontext.h"
 
+/**
+ * \class QgsMapUnitScale
+ * \brief Struct for storing maximum and minimum scales for measurements in map units
+ *
+ * For measurements in map units, a minimum and a maximum scale can be defined.
+ * Outside this range, the measurements aren't scaled anymore proportionally to
+ * the map scale.
+ */
+
 class CORE_EXPORT QgsMapUnitScale
 {
   public:
-    QgsMapUnitScale() : minScale( 0.0 ), maxScale( 0.0 ) {}
-    QgsMapUnitScale( float _minScale, float _maxScale ) : minScale( _minScale ), maxScale( _maxScale ) {}
+
+    /** Constructor for QgsMapUnitScale
+     * @param minScale minimum allowed scale, or 0.0 if no minimum scale set
+     * @param maxScale maximum allowed scale, or 0.0 if no maximum scale set
+     */
+    QgsMapUnitScale( double minScale = 0.0, double maxScale = 0.0 ) : minScale( minScale ), maxScale( maxScale ) {}
 
     /** The minimum scale, or 0.0 if unset */
     double minScale;
     /** The maximum scale, or 0.0 if unset */
     double maxScale;
 
+    /** Computes a map units per pixel scaling factor, respecting the minimum and maximum scales
+     * set for the object.
+     * @param c render context
+     * @returns map units per pixel, limited between minimum and maximum scales
+     */
     double computeMapUnitsPerPixel( const QgsRenderContext& c ) const
     {
       double mup = c.mapToPixel().mapUnitsPerPixel();
diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp
index cf01124..0155d2d 100644
--- a/src/core/qgspallabeling.cpp
+++ b/src/core/qgspallabeling.cpp
@@ -4458,6 +4458,7 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
       {
         // draw label's text, QPainterPath method
         QPainterPath path;
+        path.setFillRule( Qt::WindingFill );
         path.addText( 0, 0, tmpLyr.textFont, component.text() );
 
         // store text's drawing in QPicture for drop shadow call
@@ -4526,6 +4527,7 @@ void QgsPalLabeling::drawLabelBuffer( QgsRenderContext& context,
                    ( tmpLyr.bufferSizeInMapUnits ? QgsPalLayerSettings::MapUnits : QgsPalLayerSettings::MM ), true, tmpLyr.bufferSizeMapUnitScale );
 
   QPainterPath path;
+  path.setFillRule( Qt::WindingFill );
   path.addText( 0, 0, tmpLyr.textFont, component.text() );
   QPen pen( tmpLyr.bufferColor );
   pen.setWidthF( penSize );
diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp
index 494a437..0cc87d6 100644
--- a/src/core/qgsvectorfilewriter.cpp
+++ b/src/core/qgsvectorfilewriter.cpp
@@ -69,6 +69,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
 )
     : mDS( NULL )
     , mLayer( NULL )
+    , mOgrRef( NULL )
     , mGeom( NULL )
     , mError( NoError )
     , mCodec( 0 )
@@ -258,12 +259,11 @@ QgsVectorFileWriter::QgsVectorFileWriter(
   }
 
   // consider spatial reference system of the layer
-  OGRSpatialReferenceH ogrRef = NULL;
   if ( srs )
   {
     QString srsWkt = srs->toWkt();
     QgsDebugMsg( "WKT to save as is " + srsWkt );
-    ogrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
+    mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
   }
 
   // datasource created, now create the output layer
@@ -283,7 +283,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
   // disable encoding conversion of OGR Shapefile layer
   CPLSetConfigOption( "SHAPE_ENCODING", "" );
 
-  mLayer = OGR_DS_CreateLayer( mDS, TO8F( layerName ), ogrRef, wkbType, options );
+  mLayer = OGR_DS_CreateLayer( mDS, TO8F( layerName ), mOgrRef, wkbType, options );
 
   if ( options )
   {
@@ -316,8 +316,6 @@ QgsVectorFileWriter::QgsVectorFileWriter(
         QgsDebugMsg( "Couldn't open file " + layerName + ".qpj" );
       }
     }
-
-    OSRDestroySpatialReference( ogrRef );
   }
 
   if ( mLayer == NULL )
@@ -337,6 +335,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
 
   mFields = fields;
   mAttrIdxToOgrIdx.clear();
+  QSet<int> existingIdxs;
 
   for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
   {
@@ -445,7 +444,8 @@ QgsVectorFileWriter::QgsVectorFileWriter(
     OGR_Fld_Destroy( fld );
 
     int ogrIdx = OGR_FD_GetFieldIndex( defn, mCodec->fromUnicode( name ) );
-    if ( ogrIdx < 0 )
+    QgsDebugMsg( QString( "returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
+    if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
     {
 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
       // if we didn't find our new column, assume it's name was truncated and
@@ -478,6 +478,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
       }
     }
 
+    existingIdxs.insert( ogrIdx );
     mAttrIdxToOgrIdx.insert( fldIdx, ogrIdx );
   }
 
@@ -1386,7 +1387,7 @@ QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()
 
   layerOptions.insert( "LAUNDER", new BoolOption(
                          QObject::tr( "Controls whether layer and field names will be laundered for easier use "
-                                      "in SQLite. Laundered names will be convered to lower case and some special "
+                                      "in SQLite. Laundered names will be converted to lower case and some special "
                                       "characters(' - #) will be changed to underscores." ),
                          true  // Default value
                        ) );
@@ -1807,6 +1808,11 @@ QgsVectorFileWriter::~QgsVectorFileWriter()
   {
     OGR_DS_Destroy( mDS );
   }
+
+  if ( mOgrRef )
+  {
+    OSRDestroySpatialReference( mOgrRef );
+  }
 }
 
 QgsVectorFileWriter::WriterError
@@ -2594,7 +2600,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
         if ( !styleString.isEmpty() )
         {
           OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
-          if ( ! writeFeature( mLayer, ogrFeature ) )
+          if ( !writeFeature( mLayer, ogrFeature ) )
           {
             ++nErrors;
           }
diff --git a/src/core/qgsvectorfilewriter.h b/src/core/qgsvectorfilewriter.h
index e8bbe8c..85fc173 100644
--- a/src/core/qgsvectorfilewriter.h
+++ b/src/core/qgsvectorfilewriter.h
@@ -275,6 +275,7 @@ class CORE_EXPORT QgsVectorFileWriter
 
     OGRDataSourceH mDS;
     OGRLayerH mLayer;
+    OGRSpatialReferenceH mOgrRef;
     OGRGeometryH mGeom;
 
     QgsFields mFields;
diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp
index 9209bc7..9063308 100644
--- a/src/core/qgsvectorlayer.cpp
+++ b/src/core/qgsvectorlayer.cpp
@@ -1065,13 +1065,13 @@ bool QgsVectorLayer::deleteSelectedFeatures( int* deletedCount )
   return deleted == count;
 }
 
-int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
+int QgsVectorLayer::addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId )
 {
   if ( !mEditBuffer || !mDataProvider )
     return 6;
 
   QgsVectorLayerEditUtils utils( this );
-  return utils.addRing( ring );
+  return utils.addRing( ring, featureId );
 }
 
 int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
@@ -2928,6 +2928,10 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
   }
 
   QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
+  if ( origin == QgsFields::OriginUnknown )
+  {
+    return;
+  }
 
   if ( origin == QgsFields::OriginProvider ) //a provider field
   {
@@ -3018,6 +3022,10 @@ QVariant QgsVectorLayer::minimumValue( int index )
   }
 
   QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
+  if ( origin == QgsFields::OriginUnknown )
+  {
+    return QVariant();
+  }
 
   if ( origin == QgsFields::OriginProvider ) //a provider field
   {
@@ -3080,6 +3088,10 @@ QVariant QgsVectorLayer::maximumValue( int index )
   }
 
   QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
+  if ( origin == QgsFields::OriginUnknown )
+  {
+    return QVariant();
+  }
 
   if ( origin == QgsFields::OriginProvider ) //a provider field
   {
diff --git a/src/core/qgsvectorlayer.h b/src/core/qgsvectorlayer.h
index 487aeb5..a5797fd 100644
--- a/src/core/qgsvectorlayer.h
+++ b/src/core/qgsvectorlayer.h
@@ -958,7 +958,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
      */
     bool deleteSelectedFeatures( int *deletedCount = 0 );
 
-    /**Adds a ring to polygon/multipolygon features
+    /** Adds a ring to polygon/multipolygon features
+     * @param ring ring to add
+     * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter
      @return
        0 in case of success,
        1 problem with feature type,
@@ -967,7 +969,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
        4 ring crosses existing rings,
        5 no feature found where ring can be inserted
        6 layer not editable */
-    int addRing( const QList<QgsPoint>& ring );
+    int addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId = 0 );
 
     /**Adds a new part polygon to a multipart feature
      @return
diff --git a/src/core/qgsvectorlayereditbuffer.cpp b/src/core/qgsvectorlayereditbuffer.cpp
index a80a9d9..2294705 100644
--- a/src/core/qgsvectorlayereditbuffer.cpp
+++ b/src/core/qgsvectorlayereditbuffer.cpp
@@ -258,6 +258,26 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors )
   int cap = provider->capabilities();
   bool success = true;
 
+  //
+  // update geometries
+  //
+  if ( !mChangedGeometries.isEmpty() )
+  {
+    if (( cap & QgsVectorDataProvider::ChangeGeometries ) && provider->changeGeometryValues( mChangedGeometries ) )
+    {
+      commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
+
+      emit committedGeometriesChanges( L->id(), mChangedGeometries );
+
+      mChangedGeometries.clear();
+    }
+    else
+    {
+      commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
+      success = false;
+    }
+  }
+
   QgsFields oldFields = L->pendingFields();
 
   //
@@ -500,26 +520,6 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors )
     success = false;
   }
 
-  //
-  // update geometries
-  //
-  if ( success && !mChangedGeometries.isEmpty() )
-  {
-    if (( cap & QgsVectorDataProvider::ChangeGeometries ) && provider->changeGeometryValues( mChangedGeometries ) )
-    {
-      commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
-
-      emit committedGeometriesChanges( L->id(), mChangedGeometries );
-
-      mChangedGeometries.clear();
-    }
-    else
-    {
-      commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
-      success = false;
-    }
-  }
-
   if ( !success && provider->hasErrors() )
   {
     commitErrors << tr( "\n  Provider errors:" );
diff --git a/src/core/qgsvectorlayereditutils.cpp b/src/core/qgsvectorlayereditutils.cpp
index 0cf9fbb..a8bc891 100644
--- a/src/core/qgsvectorlayereditutils.cpp
+++ b/src/core/qgsvectorlayereditutils.cpp
@@ -97,7 +97,7 @@ bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVert
 }
 
 
-int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring )
+int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId )
 {
   if ( !L->hasGeometryType() )
     return 5;
@@ -125,7 +125,8 @@ int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring )
     if ( addRingReturnCode == 0 )
     {
       L->editBuffer()->changeGeometry( f.id(), f.geometry() );
-
+      if ( featureId )
+        *featureId = f.id();
       //setModified( true, true );
       break;
     }
diff --git a/src/core/qgsvectorlayereditutils.h b/src/core/qgsvectorlayereditutils.h
index 7ce5b01..0caa241 100644
--- a/src/core/qgsvectorlayereditutils.h
+++ b/src/core/qgsvectorlayereditutils.h
@@ -47,6 +47,8 @@ class CORE_EXPORT QgsVectorLayerEditUtils
     bool deleteVertex( QgsFeatureId atFeatureId, int atVertex );
 
     /** Adds a ring to polygon/multipolygon features
+     * @param ring ring to add
+     * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter
      @return
        0 in case of success,
        1 problem with feature type,
@@ -54,7 +56,7 @@ class CORE_EXPORT QgsVectorLayerEditUtils
        3 ring not valid,
        4 ring crosses existing rings,
        5 no feature found where ring can be inserted*/
-    int addRing( const QList<QgsPoint>& ring );
+    int addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId = 0 );
 
     /** Adds a new part polygon to a multipart feature
      @return
diff --git a/src/core/symbology-ng/qgsellipsesymbollayerv2.cpp b/src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
index 224af8c..cded616 100644
--- a/src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
+++ b/src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
@@ -26,22 +26,23 @@
 #include <QDomElement>
 
 QgsEllipseSymbolLayerV2::QgsEllipseSymbolLayerV2()
-    : mSymbolName( "circle" )
+    : QgsMarkerSymbolLayerV2()
+    , mSymbolName( "circle" )
     , mSymbolWidth( 4 )
     , mSymbolWidthUnit( QgsSymbolV2::MM )
     , mSymbolHeight( 3 )
     , mSymbolHeightUnit( QgsSymbolV2::MM )
-    , mFillColor( Qt::white )
     , mOutlineColor( Qt::black )
     , mOutlineStyle( Qt::SolidLine )
     , mOutlineWidth( 0 )
     , mOutlineWidthUnit( QgsSymbolV2::MM )
 {
+  mColor = Qt::white;
   mPen.setColor( mOutlineColor );
   mPen.setStyle( mOutlineStyle );
   mPen.setWidth( 1.0 );
   mPen.setJoinStyle( Qt::MiterJoin );
-  mBrush.setColor( mFillColor );
+  mBrush.setColor( mColor );
   mBrush.setStyle( Qt::SolidPattern );
   mOffset = QPointF( 0, 0 );
 
@@ -340,7 +341,7 @@ void QgsEllipseSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
   mPen.setColor( mOutlineColor );
   mPen.setStyle( mOutlineStyle );
   mPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
-  mBrush.setColor( mFillColor );
+  mBrush.setColor( mColor );
   prepareExpressions( context.fields(), context.renderContext().rendererScale() );
 }
 
@@ -372,7 +373,7 @@ void QgsEllipseSymbolLayerV2::writeSldMarker( QDomDocument &doc, QDomElement &el
   QDomElement graphicElem = doc.createElement( "se:Graphic" );
   element.appendChild( graphicElem );
 
-  QgsSymbolLayerV2Utils::wellKnownMarkerToSld( doc, graphicElem, mSymbolName, mFillColor, mOutlineColor, mOutlineStyle, mOutlineWidth, mSymbolWidth );
+  QgsSymbolLayerV2Utils::wellKnownMarkerToSld( doc, graphicElem, mSymbolName, mColor, mOutlineColor, mOutlineStyle, mOutlineWidth, mSymbolWidth );
 
   // store w/h factor in a <VendorOption>
   double widthHeightFactor = mSymbolWidth / mSymbolHeight;
@@ -481,7 +482,7 @@ QgsStringMap QgsEllipseSymbolLayerV2::properties() const
   map["outline_width"] = QString::number( mOutlineWidth );
   map["outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOutlineWidthUnit );
   map["outline_width_map_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( mOutlineWidthMapUnitScale );
-  map["color"] = QgsSymbolLayerV2Utils::encodeColor( mFillColor );
+  map["color"] = QgsSymbolLayerV2Utils::encodeColor( mColor );
   map["outline_color"] = QgsSymbolLayerV2Utils::encodeColor( mOutlineColor );
   map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
   map["offset_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOffsetUnit );
@@ -656,7 +657,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
   }
 
   //fill color
-  QColor fc = mFillColor;
+  QColor fc = mColor;
   QgsExpression* fillColorExpression = expression( "fill_color" );
   if ( fillColorExpression )
   {
diff --git a/src/core/symbology-ng/qgsellipsesymbollayerv2.h b/src/core/symbology-ng/qgsellipsesymbollayerv2.h
index 473dfc3..22d7550 100644
--- a/src/core/symbology-ng/qgsellipsesymbollayerv2.h
+++ b/src/core/symbology-ng/qgsellipsesymbollayerv2.h
@@ -57,8 +57,8 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
     void setOutlineWidth( double w ) { mOutlineWidth = w; }
     double outlineWidth() const { return mOutlineWidth; }
 
-    void setFillColor( const QColor& c ) override { mFillColor = c;}
-    QColor fillColor() const override { return mFillColor; }
+    void setFillColor( const QColor& c ) override { setColor( c ); }
+    QColor fillColor() const override { return color(); }
 
     void setOutlineColor( const QColor& c ) override { mOutlineColor = c; }
     QColor outlineColor() const override { return mOutlineColor; }
@@ -95,7 +95,6 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
     double mSymbolHeight;
     QgsSymbolV2::OutputUnit mSymbolHeightUnit;
     QgsMapUnitScale mSymbolHeightMapUnitScale;
-    QColor mFillColor;
     QColor mOutlineColor;
     Qt::PenStyle mOutlineStyle;
     double mOutlineWidth;
diff --git a/src/core/symbology-ng/qgsfillsymbollayerv2.cpp b/src/core/symbology-ng/qgsfillsymbollayerv2.cpp
index a997ee8..22ca897 100644
--- a/src/core/symbology-ng/qgsfillsymbollayerv2.cpp
+++ b/src/core/symbology-ng/qgsfillsymbollayerv2.cpp
@@ -1961,7 +1961,7 @@ void QgsSVGFillSymbolLayer::applyPattern( QBrush& brush, const QString& svgFileP
 void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
 {
 
-  applyPattern( mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth, mSvgOutlineWidthUnit, context, mPatternWidthMapUnitScale, mSvgOutlineWidthMapUnitScale );
+  applyPattern( mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit, mColor, mSvgOutlineColor, mSvgOutlineWidth, mSvgOutlineWidthUnit, context, mPatternWidthMapUnitScale, mSvgOutlineWidthMapUnitScale );
 
   if ( mOutline )
   {
@@ -1995,7 +1995,7 @@ QgsStringMap QgsSVGFillSymbolLayer::properties() const
   map.insert( "angle", QString::number( mAngle ) );
 
   //svg parameters
-  map.insert( "color", QgsSymbolLayerV2Utils::encodeColor( mSvgFillColor ) );
+  map.insert( "color", QgsSymbolLayerV2Utils::encodeColor( mColor ) );
   map.insert( "outline_color", QgsSymbolLayerV2Utils::encodeColor( mSvgOutlineColor ) );
   map.insert( "outline_width", QString::number( mSvgOutlineWidth ) );
 
@@ -2017,7 +2017,7 @@ QgsSymbolLayerV2* QgsSVGFillSymbolLayer::clone() const
   if ( !mSvgFilePath.isEmpty() )
   {
     clonedLayer = new QgsSVGFillSymbolLayer( mSvgFilePath, mPatternWidth, mAngle );
-    clonedLayer->setSvgFillColor( mSvgFillColor );
+    clonedLayer->setSvgFillColor( mColor );
     clonedLayer->setSvgOutlineColor( mSvgOutlineColor );
     clonedLayer->setSvgOutlineWidth( mSvgOutlineWidth );
   }
@@ -2061,7 +2061,7 @@ void QgsSVGFillSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, QgsS
 
   if ( !mSvgFilePath.isEmpty() )
   {
-    QgsSymbolLayerV2Utils::externalGraphicToSld( doc, graphicElem, mSvgFilePath, "image/svg+xml", mSvgFillColor, mPatternWidth );
+    QgsSymbolLayerV2Utils::externalGraphicToSld( doc, graphicElem, mSvgFilePath, "image/svg+xml", mColor, mPatternWidth );
   }
   else
   {
@@ -2186,7 +2186,7 @@ void QgsSVGFillSymbolLayer::applyDataDefinedSettings( const QgsSymbolV2RenderCon
   {
     svgFile = svgFileExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
   }
-  QColor svgFillColor = mSvgFillColor;
+  QColor svgFillColor = mColor;
   if ( fillColorExpression )
   {
     svgFillColor = QgsSymbolLayerV2Utils::decodeColor( fillColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
@@ -2225,7 +2225,7 @@ void QgsSVGFillSymbolLayer::storeViewBox()
 void QgsSVGFillSymbolLayer::setDefaultSvgParams()
 {
   //default values
-  mSvgFillColor = QColor( 0, 0, 0 );
+  mColor = QColor( 0, 0, 0 );
   mSvgOutlineColor = QColor( 0, 0, 0 );
   mSvgOutlineWidth = 0.3;
 
@@ -2242,7 +2242,7 @@ void QgsSVGFillSymbolLayer::setDefaultSvgParams()
 
   if ( hasFillParam )
   {
-    mSvgFillColor = defaultFillColor;
+    mColor = defaultFillColor;
   }
   if ( hasOutlineParam )
   {
diff --git a/src/core/symbology-ng/qgsfillsymbollayerv2.h b/src/core/symbology-ng/qgsfillsymbollayerv2.h
index c7d6308..39c362b 100644
--- a/src/core/symbology-ng/qgsfillsymbollayerv2.h
+++ b/src/core/symbology-ng/qgsfillsymbollayerv2.h
@@ -801,8 +801,9 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
     void setPatternWidth( double width ) { mPatternWidth = width;}
     double patternWidth() const { return mPatternWidth; }
 
-    void setSvgFillColor( const QColor& c ) { mSvgFillColor = c; }
-    QColor svgFillColor() const { return mSvgFillColor; }
+    void setSvgFillColor( const QColor& c ) { setColor( c );  }
+    QColor svgFillColor() const { return color(); }
+
     void setSvgOutlineColor( const QColor& c ) { mSvgOutlineColor = c; }
     QColor svgOutlineColor() const { return mSvgOutlineColor; }
     void setSvgOutlineWidth( double w ) { mSvgOutlineWidth = w; }
@@ -843,7 +844,6 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
 
     //param(fill), param(outline), param(outline-width) are going
     //to be replaced in memory
-    QColor mSvgFillColor;
     QColor mSvgOutlineColor;
     double mSvgOutlineWidth;
     QgsSymbolV2::OutputUnit mSvgOutlineWidthUnit;
diff --git a/src/core/symbology-ng/qgsmarkersymbollayerv2.cpp b/src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
index 2b01815..68887b7 100644
--- a/src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
+++ b/src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
@@ -1053,7 +1053,7 @@ QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2( QString name, double size,
   mScaleMethod = scaleMethod;
   mOutlineWidth = 1.0;
   mOutlineWidthUnit = QgsSymbolV2::MM;
-  mFillColor = QColor( Qt::black );
+  mColor = QColor( Qt::black );
   mOutlineColor = QColor( Qt::black );
 }
 
@@ -1337,7 +1337,7 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
     outlineWidth = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
   }
 
-  QColor fillColor = mFillColor;
+  QColor fillColor = mColor;
   QgsExpression* fillExpression = expression( "fill" );
   if ( fillExpression )
   {
@@ -1428,7 +1428,7 @@ QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
   map["offset_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOffsetUnit );
   map["offset_map_unit_scale"] = QgsSymbolLayerV2Utils::encodeMapUnitScale( mOffsetMapUnitScale );
   map["scale_method"] = QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod );
-  map["color"] = mFillColor.name();
+  map["color"] = mColor.name();
   map["outline_color"] = mOutlineColor.name();
   map["outline_width"] = QString::number( mOutlineWidth );
   map["outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOutlineWidthUnit );
@@ -1443,7 +1443,7 @@ QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
 QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::clone() const
 {
   QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( mPath, mSize, mAngle );
-  m->setFillColor( mFillColor );
+  m->setFillColor( mColor );
   m->setOutlineColor( mOutlineColor );
   m->setOutlineWidth( mOutlineWidth );
   m->setOutlineWidthUnit( mOutlineWidthUnit );
@@ -1496,7 +1496,7 @@ void QgsSvgMarkerSymbolLayerV2::writeSldMarker( QDomDocument &doc, QDomElement &
   QDomElement graphicElem = doc.createElement( "se:Graphic" );
   element.appendChild( graphicElem );
 
-  QgsSymbolLayerV2Utils::externalGraphicToSld( doc, graphicElem, mPath, "image/svg+xml", mFillColor, mSize );
+  QgsSymbolLayerV2Utils::externalGraphicToSld( doc, graphicElem, mPath, "image/svg+xml", mColor, mSize );
 
   // <Rotation>
   QString angleFunc;
@@ -1634,7 +1634,7 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
     outlineWidth = outlineWidthExpression->evaluate( *f ).toDouble();
   }
 
-  QColor fillColor = mFillColor;
+  QColor fillColor = mColor;
   QgsExpression *fillExpression = expression( "fill" );
   if ( fillExpression )
   {
diff --git a/src/core/symbology-ng/qgsmarkersymbollayerv2.h b/src/core/symbology-ng/qgsmarkersymbollayerv2.h
index 857604f..3b31233 100644
--- a/src/core/symbology-ng/qgsmarkersymbollayerv2.h
+++ b/src/core/symbology-ng/qgsmarkersymbollayerv2.h
@@ -179,8 +179,8 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
     QString path() const { return mPath; }
     void setPath( QString path );
 
-    QColor fillColor() const override { return mFillColor; }
-    void setFillColor( const QColor& c ) override { mFillColor = c; }
+    QColor fillColor() const override { return color(); }
+    void setFillColor( const QColor& color ) override { setColor( color ); }
 
     QColor outlineColor() const override { return mOutlineColor; }
     void setOutlineColor( const QColor& c ) override { mOutlineColor = c; }
@@ -207,7 +207,6 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
 
     //param(fill), param(outline), param(outline-width) are going
     //to be replaced in memory
-    QColor mFillColor;
     QColor mOutlineColor;
     double mOutlineWidth;
     QgsSymbolV2::OutputUnit mOutlineWidthUnit;
diff --git a/src/core/symbology-ng/qgsrulebasedrendererv2.cpp b/src/core/symbology-ng/qgsrulebasedrendererv2.cpp
index 552b645..ddb65e7 100644
--- a/src/core/symbology-ng/qgsrulebasedrendererv2.cpp
+++ b/src/core/symbology-ng/qgsrulebasedrendererv2.cpp
@@ -449,7 +449,7 @@ void QgsRuleBasedRendererV2::Rule::setNormZLevels( const QMap<int, int>& zLevels
     for ( int i = 0; i < mSymbol->symbolLayerCount(); i++ )
     {
       int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
-      mSymbolNormZLevels.append( normLevel );
+      mSymbolNormZLevels.insert( normLevel );
     }
   }
 
diff --git a/src/core/symbology-ng/qgsrulebasedrendererv2.h b/src/core/symbology-ng/qgsrulebasedrendererv2.h
index 39a7edb..9dea9d5 100644
--- a/src/core/symbology-ng/qgsrulebasedrendererv2.h
+++ b/src/core/symbology-ng/qgsrulebasedrendererv2.h
@@ -200,7 +200,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
         // temporary
         QgsExpression* mFilter;
         // temporary while rendering
-        QList<int> mSymbolNormZLevels;
+        QSet<int> mSymbolNormZLevels;
         RuleList mActiveChildren;
     };
 
diff --git a/src/core/symbology-ng/qgssvgcache.cpp b/src/core/symbology-ng/qgssvgcache.cpp
index 26eb223..f21c1a8 100644
--- a/src/core/symbology-ng/qgssvgcache.cpp
+++ b/src/core/symbology-ng/qgssvgcache.cpp
@@ -51,8 +51,9 @@ QgsSvgCacheEntry::QgsSvgCacheEntry()
 {
 }
 
-QgsSvgCacheEntry::QgsSvgCacheEntry( const QString& f, double s, double ow, double wsf, double rsf, const QColor& fi, const QColor& ou )
+QgsSvgCacheEntry::QgsSvgCacheEntry( const QString& f, double s, double ow, double wsf, double rsf, const QColor& fi, const QColor& ou, const QString& lk )
     : file( f )
+    , lookupKey( lk.isEmpty() ? f : lk )
     , size( s )
     , outlineWidth( ow )
     , widthScaleFactor( wsf )
@@ -197,7 +198,7 @@ QgsSvgCacheEntry* QgsSvgCache::insertSVG( const QString& file, double size, cons
   // The file may be relative path (e.g. if path is data defined)
   QString path = QgsSymbolLayerV2Utils::symbolNameToPath( file );
 
-  QgsSvgCacheEntry* entry = new QgsSvgCacheEntry( path, size, outlineWidth, widthScaleFactor, rasterScaleFactor, fill, outline );
+  QgsSvgCacheEntry* entry = new QgsSvgCacheEntry( path, size, outlineWidth, widthScaleFactor, rasterScaleFactor, fill, outline, file );
 
   replaceParamsAndCacheSvg( entry );
 
@@ -226,6 +227,9 @@ QgsSvgCacheEntry* QgsSvgCache::insertSVG( const QString& file, double size, cons
 void QgsSvgCache::containsParams( const QString& path, bool& hasFillParam, QColor& defaultFillColor, bool& hasOutlineParam, QColor& defaultOutlineColor,
                                   bool& hasOutlineWidthParam, double& defaultOutlineWidth ) const
 {
+  hasFillParam = false;
+  hasOutlineParam = false;
+  hasOutlineWidthParam = false;
   defaultFillColor = QColor( Qt::black );
   defaultOutlineColor = QColor( Qt::black );
   defaultOutlineWidth = 1.0;
@@ -724,7 +728,7 @@ void QgsSvgCache::trimToMaximumSize()
     entry = entry->nextEntry;
 
     takeEntryFromList( bkEntry );
-    mEntryLookup.remove( bkEntry->file, bkEntry );
+    mEntryLookup.remove( bkEntry->lookupKey, bkEntry );
     mTotalSize -= bkEntry->dataSize();
     delete bkEntry;
   }
diff --git a/src/core/symbology-ng/qgssvgcache.h b/src/core/symbology-ng/qgssvgcache.h
index 5bccdeb..d06ef0f 100644
--- a/src/core/symbology-ng/qgssvgcache.h
+++ b/src/core/symbology-ng/qgssvgcache.h
@@ -41,11 +41,15 @@ class CORE_EXPORT QgsSvgCacheEntry
      * @param rasterScaleFactor raster scale factor
      * @param fill color of fill
      * @param outline color of outline
+     * @param lookupKey the key string used in QgsSvgCache for quick lookup of this entry (relative or absolute path)
      */
-    QgsSvgCacheEntry( const QString& file, double size, double outlineWidth, double widthScaleFactor, double rasterScaleFactor, const QColor& fill, const QColor& outline );
+    QgsSvgCacheEntry( const QString& file, double size, double outlineWidth, double widthScaleFactor, double rasterScaleFactor, const QColor& fill, const QColor& outline, const QString& lookupKey = QString() );
     ~QgsSvgCacheEntry();
 
+    //! Absolute path to SVG file
     QString file;
+    //! Lookup key used by QgsSvgCache's hashtable (relative or absolute path). Needed for removal from the hashtable
+    QString lookupKey;
     double size; //size in pixels (cast to int for QImage)
     double outlineWidth;
     double widthScaleFactor;
diff --git a/src/core/symbology-ng/qgssymbollayerv2.cpp b/src/core/symbology-ng/qgssymbollayerv2.cpp
index c2397cc..ccc2dc2 100644
--- a/src/core/symbology-ng/qgssymbollayerv2.cpp
+++ b/src/core/symbology-ng/qgssymbollayerv2.cpp
@@ -467,7 +467,9 @@ void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points,
     return;
   }
 
-  if ( rings == NULL )
+  // polygons outlines are sometimes rendered wrongly with drawPolygon, when
+  // clipped (see #13343), so use drawPath instead.
+  if ( !rings && p->pen().style() == Qt::NoPen )
   {
     // simple polygon without holes
     p->drawPolygon( points );
@@ -479,11 +481,14 @@ void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points,
     QPolygonF outerRing = points;
     path.addPolygon( outerRing );
 
-    QList<QPolygonF>::const_iterator it = rings->constBegin();
-    for ( ; it != rings->constEnd(); ++it )
+    if ( rings )
     {
-      QPolygonF ring = *it;
-      path.addPolygon( ring );
+      QList<QPolygonF>::const_iterator it = rings->constBegin();
+      for ( ; it != rings->constEnd(); ++it )
+      {
+        QPolygonF ring = *it;
+        path.addPolygon( ring );
+      }
     }
 
     p->drawPath( path );
diff --git a/src/core/symbology-ng/qgssymbollayerv2utils.cpp b/src/core/symbology-ng/qgssymbollayerv2utils.cpp
index 93d985c..c64cd81 100644
--- a/src/core/symbology-ng/qgssymbollayerv2utils.cpp
+++ b/src/core/symbology-ng/qgssymbollayerv2utils.cpp
@@ -750,7 +750,11 @@ QList<QPolygonF> offsetLine( QPolygonF polyline, double dist, QGis::GeometryType
 
       if ( QGis::flatType( tempGeometry->wkbType() ) == QGis::WKBLineString )
       {
-        resultLine.append( makeOffsetGeometry( tempGeometry->asPolyline() ) );
+        QgsPolyline line = tempGeometry->asPolyline();
+        // Reverse the line if offset was negative, see
+        // http://hub.qgis.org/issues/13811
+        if ( dist < 0 ) std::reverse(line.begin(), line.end() );
+        resultLine.append( makeOffsetGeometry( line ) );
         delete tempGeometry;
         return resultLine;
       }
diff --git a/src/core/symbology-ng/qgsvectorcolorrampv2.cpp b/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
index 9b55cd3..b770d83 100644
--- a/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
+++ b/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
@@ -289,13 +289,13 @@ QgsVectorColorRampV2* QgsVectorRandomColorRampV2::create( const QgsStringMap& pr
 double QgsVectorRandomColorRampV2::value( int index ) const
 {
   if ( mColors.size() < 1 ) return 0;
-  return index / mColors.size() - 1;
+  return ( double )index / ( mColors.size() - 1 );
 }
 
 QColor QgsVectorRandomColorRampV2::color( double value ) const
 {
   int colorCnt = mColors.count();
-  int colorIdx = ( int )( value * colorCnt );
+  int colorIdx = ( int )( value * ( colorCnt - 1 ) );
 
   if ( colorIdx >= 0 && colorIdx < colorCnt )
     return mColors.at( colorIdx );
@@ -346,7 +346,7 @@ QList<QColor> QgsVectorRandomColorRampV2::randomColors( int count,
     currentHueAngle += 137.50776;
     //scale hue to between hueMax and hueMin
     h = qBound( 0, qRound(( fmod( currentHueAngle, 360.0 ) / 360.0 ) * ( safeHueMax - safeHueMin ) + safeHueMin ), 359 );
-    s = qBound( 0, ( qrand() % ( safeSatMax - safeSatMin + 1 ) ) + safeValMax, 255 );
+    s = qBound( 0, ( qrand() % ( safeSatMax - safeSatMin + 1 ) ) + safeSatMin, 255 );
     v = qBound( 0, ( qrand() % ( safeValMax - safeValMin + 1 ) ) + safeValMin, 255 );
     colors.append( QColor::fromHsv( h, s, v ) );
   }
@@ -372,7 +372,7 @@ QgsRandomColorsV2::~QgsRandomColorsV2()
 
 int QgsRandomColorsV2::count() const
 {
-  return INT_MAX;
+  return -1;
 }
 
 double QgsRandomColorsV2::value( int index ) const
@@ -395,7 +395,7 @@ QColor QgsRandomColorsV2::color( double value ) const
   }
 
   //can't use precalculated hues, use a totally random hue
-  int h = 1 + ( int )( 360.0 * qrand() / ( RAND_MAX + 1.0 ) );
+  int h = ( int )( 360.0 * qrand() / ( RAND_MAX + 1.0 ) );
   int s = ( qrand() % ( DEFAULT_RANDOM_SAT_MAX - DEFAULT_RANDOM_SAT_MIN + 1 ) ) + DEFAULT_RANDOM_SAT_MIN;
   int v = ( qrand() % ( maxVal - minVal + 1 ) ) + minVal;
   return QColor::fromHsv( h, s, v );
@@ -487,7 +487,7 @@ QList<int> QgsVectorColorBrewerColorRampV2::listSchemeVariants( QString schemeNa
 double QgsVectorColorBrewerColorRampV2::value( int index ) const
 {
   if ( mPalette.size() < 1 ) return 0;
-  return index / mPalette.size() - 1;
+  return ( double )index / ( mPalette.size() - 1 );
 }
 
 QColor QgsVectorColorBrewerColorRampV2::color( double value ) const
diff --git a/src/core/symbology-ng/qgsvectorcolorrampv2.h b/src/core/symbology-ng/qgsvectorcolorrampv2.h
index c04d4c4..62d6d1a 100644
--- a/src/core/symbology-ng/qgsvectorcolorrampv2.h
+++ b/src/core/symbology-ng/qgsvectorcolorrampv2.h
@@ -28,10 +28,12 @@ class CORE_EXPORT QgsVectorColorRampV2
 
     virtual ~QgsVectorColorRampV2() {}
 
-    // Number of defined colors
+    /** Returns number of defined colors, or -1 if undefined
+     */
     virtual int count() const = 0;
 
-    // Relative value (0,1) of color at index
+    /** Returns relative value between [0,1] of color at specified index
+     */
     virtual double value( int index ) const = 0;
 
     virtual QColor color( double value ) const = 0;
diff --git a/src/gui/attributetable/qgsattributetablefiltermodel.cpp b/src/gui/attributetable/qgsattributetablefiltermodel.cpp
index cd12058..99b8444 100644
--- a/src/gui/attributetable/qgsattributetablefiltermodel.cpp
+++ b/src/gui/attributetable/qgsattributetablefiltermodel.cpp
@@ -189,8 +189,9 @@ bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModel
       {
         const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
         const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
+        const QList<QgsFeatureId> changedGeometries = editBuffer->changedGeometries().keys();
         const QgsFeatureId fid = masterModel()->rowToId( sourceRow );
-        return addedFeatures.contains( fid ) || changedFeatures.contains( fid );
+        return addedFeatures.contains( fid ) || changedFeatures.contains( fid ) || changedGeometries.contains( fid );
       }
       return false;
     }
diff --git a/src/gui/attributetable/qgsattributetablemodel.cpp b/src/gui/attributetable/qgsattributetablemodel.cpp
index db5f8bd..9fa5c7b 100644
--- a/src/gui/attributetable/qgsattributetablemodel.cpp
+++ b/src/gui/attributetable/qgsattributetablemodel.cpp
@@ -27,6 +27,7 @@
 #include "qgsmaplayerregistry.h"
 #include "qgsrendererv2.h"
 #include "qgsvectorlayer.h"
+#include "qgsvectordataprovider.h"
 
 #include <QVariant>
 
@@ -560,7 +561,9 @@ Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
   Qt::ItemFlags flags = QAbstractItemModel::flags( index );
 
   if ( layer()->isEditable() &&
-       layer()->fieldEditable( mAttributes[ index.column()] ) )
+       layer()->fieldEditable( mAttributes[ index.column()] ) &&
+       (( layer()->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
+        FID_IS_NEW( rowToId( index.row() ) ) ) )
     flags |= Qt::ItemIsEditable;
 
   return flags;
diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp
index 15f92af..1fcd814 100644
--- a/src/gui/qgsattributeform.cpp
+++ b/src/gui/qgsattributeform.cpp
@@ -22,6 +22,7 @@
 #include "qgsproject.h"
 #include "qgspythonrunner.h"
 #include "qgsrelationwidgetwrapper.h"
+#include "qgsvectordataprovider.h"
 
 #include <QDir>
 #include <QFileInfo>
@@ -323,7 +324,9 @@ void QgsAttributeForm::synchronizeEnabledState()
     QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
     if ( eww )
     {
-      fieldEditable = mLayer->fieldEditable( eww->fieldIdx() );
+      fieldEditable = mLayer->fieldEditable( eww->fieldIdx() ) &&
+                      (( mLayer->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
+                       FID_IS_NEW( mFeature.id() ) );
     }
     ww->setEnabled( isEditable && fieldEditable );
   }
diff --git a/src/gui/qgsmapoverviewcanvas.cpp b/src/gui/qgsmapoverviewcanvas.cpp
index 6711d00..4a196b6 100644
--- a/src/gui/qgsmapoverviewcanvas.cpp
+++ b/src/gui/qgsmapoverviewcanvas.cpp
@@ -74,6 +74,7 @@ QgsMapOverviewCanvas::QgsMapOverviewCanvas( QWidget * parent, QgsMapCanvas* mapC
     , mMapCanvas( mapCanvas )
     , mJob( 0 )
 {
+  setAutoFillBackground( true );
   setObjectName( "theOverviewCanvas" );
   mPanningWidget = new QgsPanningWidget( this );
 
diff --git a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
index 3d57488..3cede3c 100644
--- a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
+++ b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
@@ -350,6 +350,17 @@ void QgsSingleBandPseudoColorRendererWidget::on_mColorRampComboBox_currentIndexC
   Q_UNUSED( index );
   QSettings settings;
   settings.setValue( "/Raster/defaultPalette", mColorRampComboBox->currentText() );
+
+  QgsVectorColorRampV2* ramp = mColorRampComboBox->currentColorRamp();
+  if ( !ramp )
+    return;
+
+  bool enableContinuous = ( ramp->count() > 0 );
+  mClassificationModeComboBox->setEnabled( enableContinuous );
+  if ( !enableContinuous )
+  {
+    mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( EqualInterval ) );
+  }
 }
 
 void QgsSingleBandPseudoColorRendererWidget::populateColormapTreeWidget( const QList<QgsColorRampShader::ColorRampItem>& colorRampItems )
diff --git a/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp b/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp
index 448e8b7..2a6eb03 100644
--- a/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp
+++ b/src/gui/symbology-ng/qgspointdisplacementrendererwidget.cpp
@@ -88,7 +88,7 @@ QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVecto
   QStringList::const_iterator it = rendererList.constBegin();
   for ( ; it != rendererList.constEnd(); ++it )
   {
-    if ( *it != "pointDisplacement" )
+    if ( *it != "pointDisplacement" && *it != "heatmapRenderer" && *it != "invertedPolygonRenderer" )
     {
       QgsRendererV2AbstractMetadata* m = QgsRendererV2Registry::instance()->rendererMetadata( *it );
       mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
@@ -97,8 +97,10 @@ QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVecto
 
   mCircleColorButton->setColorDialogTitle( tr( "Select color" ) );
   mCircleColorButton->setContext( "symbology" );
+  mCircleColorButton->setAllowAlpha( true );
   mLabelColorButton->setContext( "symbology" );
   mLabelColorButton->setColorDialogTitle( tr( "Select color" ) );
+  mLabelColorButton->setAllowAlpha( true );
 
   mCircleWidthSpinBox->setValue( mRenderer->circleWidth() );
   mCircleColorButton->setColor( mRenderer->circleColor() );
diff --git a/src/gui/symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp b/src/gui/symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
index d35c188..32ca0a1 100644
--- a/src/gui/symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
+++ b/src/gui/symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
@@ -101,8 +101,9 @@ void QgsVectorGradientColorRampV2Dialog::on_btnInformation_pressed()
   tableInfo->setRowCount( mRamp->info().count() );
   tableInfo->setColumnCount( 2 );
   int i = 0;
-  for ( QgsStringMap::const_iterator it = mRamp->info().constBegin();
-        it != mRamp->info().constEnd(); ++it )
+  QgsStringMap rampInfo = mRamp->info();
+  for ( QgsStringMap::const_iterator it = rampInfo.constBegin();
+        it != rampInfo.constEnd(); ++it )
   {
     if ( it.key().startsWith( "cpt-city" ) )
       continue;
diff --git a/src/plugins/grass/qgsgrassmodule.cpp b/src/plugins/grass/qgsgrassmodule.cpp
index b6b8a92..f399228 100644
--- a/src/plugins/grass/qgsgrassmodule.cpp
+++ b/src/plugins/grass/qgsgrassmodule.cpp
@@ -70,6 +70,10 @@ QString QgsGrassModule::findExec( QString file )
 #ifdef WIN32
     mExecPath = path.split( ";" );
     mExecPath.prepend( QgsGrass::shortPath( QgsApplication::applicationDirPath() ) );
+#elif defined(Q_OS_MACX)
+    mExecPath = path.split( ":" );
+    mExecPath.prepend( QgsApplication::applicationDirPath() + "/bin");
+    mExecPath.prepend( QgsApplication::applicationDirPath() + "/grass/bin");
 #else
     mExecPath = path.split( ":" );
     mExecPath.prepend( QgsApplication::applicationDirPath() );
diff --git a/src/plugins/heatmap/heatmap.cpp b/src/plugins/heatmap/heatmap.cpp
index f9ae7c2..ae424f0 100644
--- a/src/plugins/heatmap/heatmap.cpp
+++ b/src/plugins/heatmap/heatmap.cpp
@@ -202,7 +202,7 @@ void Heatmap::run()
     QgsDebugMsg( QString( "Radius Field index received: %1" ).arg( rField ) );
 
     // If not using map units, then calculate a conversion factor to convert the radii to map units
-    if ( d.radiusUnit() == HeatmapGui::Meters )
+    if ( d.radiusUnit() == HeatmapGui::LayerUnits )
     {
       radiusToMapUnits = mapUnitsOf( 1, inputLayer->crs() );
     }
@@ -363,9 +363,9 @@ void Heatmap::run()
  *
  */
 
-double Heatmap::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs )
+double Heatmap::mapUnitsOf( double layerdist, const QgsCoordinateReferenceSystem &layerCrs )
 {
-  // Worker to transform metres input to mapunits
+  // Worker to transform layer input to mapunits
   QgsDistanceArea da;
   da.setSourceCrs( layerCrs.srsid() );
   da.setEllipsoid( layerCrs.ellipsoidAcronym() );
@@ -373,7 +373,7 @@ double Heatmap::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs
   {
     da.setEllipsoidalMode( true );
   }
-  return meters / da.measureLine( QgsPoint( 0.0, 0.0 ), QgsPoint( 0.0, 1.0 ) );
+  return layerdist / da.measureLine( QgsPoint( 0.0, 0.0 ), QgsPoint( 0.0, 1.0 ) );
 }
 
 int Heatmap::bufferSize( double radius, double cellsize )
diff --git a/src/plugins/heatmap/heatmap.h b/src/plugins/heatmap/heatmap.h
index 43eb2d9..e65fcb6 100644
--- a/src/plugins/heatmap/heatmap.h
+++ b/src/plugins/heatmap/heatmap.h
@@ -102,8 +102,8 @@ class Heatmap: public QObject, public QgisPlugin
   private:
     double mDecay;
 
-    //! Worker to convert meters to map units
-    double mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs );
+    //! Worker to convert layer to map units
+    double mapUnitsOf( double dist, const QgsCoordinateReferenceSystem& layerCrs );
     //! Worker to calculate buffer size in pixels
     int bufferSize( double radius, double cellsize );
     //! Calculate the value given to a point width a given distance for a specified kernel shape
diff --git a/src/plugins/heatmap/heatmapgui.cpp b/src/plugins/heatmap/heatmapgui.cpp
index cd1671b..5a9ac17 100644
--- a/src/plugins/heatmap/heatmapgui.cpp
+++ b/src/plugins/heatmap/heatmapgui.cpp
@@ -361,11 +361,11 @@ double HeatmapGui::estimateRadius()
 
   double estimate = maxExtent / 30;
 
-  if ( mBufferUnitCombo->currentIndex() == HeatmapGui::Meters )
+  if ( mBufferUnitCombo->currentIndex() == HeatmapGui::LayerUnits )
   {
-    // metres selected, so convert estimate from map units
+    // layer units selected, so convert estimate from map units
     QgsCoordinateReferenceSystem layerCrs = inputLayer->crs();
-    estimate = estimate / mapUnitsOf( 1, layerCrs );
+    estimate /= mapUnitsOf( 1, layerCrs );
   }
 
   // Make estimate pretty by rounding off to first digit only (eg 356->300, 0.567->0.5)
@@ -447,7 +447,7 @@ void HeatmapGui::updateBBox()
     int idx = inputLayer->pendingFields().indexFromName( mRadiusFieldCombo->currentField() );
     double maxInField = inputLayer->maximumValue( idx ).toDouble();
 
-    if ( mRadiusFieldUnitCombo->currentIndex() == HeatmapGui::Meters )
+    if ( mRadiusFieldUnitCombo->currentIndex() == HeatmapGui::LayerUnits )
     {
       radiusInMapUnits = mapUnitsOf( maxInField, layerCrs );
     }
@@ -459,7 +459,7 @@ void HeatmapGui::updateBBox()
   else
   {
     double radiusValue = mBufferSizeLineEdit->text().toDouble();
-    if ( mBufferUnitCombo->currentIndex() == HeatmapGui::Meters )
+    if ( mBufferUnitCombo->currentIndex() == HeatmapGui::LayerUnits )
     {
       radiusInMapUnits = mapUnitsOf( radiusValue, layerCrs );
     }
@@ -481,9 +481,9 @@ void HeatmapGui::updateBBox()
   updateSize();
 }
 
-double HeatmapGui::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs ) const
+double HeatmapGui::mapUnitsOf( double dist, const QgsCoordinateReferenceSystem& layerCrs ) const
 {
-  // converter function to transform metres input to mapunits
+  // converter function to transform layer input to mapunits
   // so that bounding box can be updated
   QgsDistanceArea da;
   da.setSourceCrs( layerCrs.srsid() );
@@ -493,8 +493,8 @@ double HeatmapGui::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layer
     da.setEllipsoidalMode( true );
   }
   double unitDistance = da.measureLine( QgsPoint( 0.0, 0.0 ), QgsPoint( 0.0, 1.0 ) );
-  QgsDebugMsg( QString( "Converted %1 meters to %2 mapunits" ).arg( meters ).arg( meters / unitDistance ) );
-  return  meters / unitDistance;
+  QgsDebugMsg( QString( "Converted %1 layer to %2 map units" ).arg( dist ).arg( dist / unitDistance ) );
+  return  dist / unitDistance;
 }
 /*
  *
@@ -515,7 +515,7 @@ bool HeatmapGui::variableRadius() const
 double HeatmapGui::radius() const
 {
   double radius = mBufferSizeLineEdit->text().toDouble();
-  if ( mBufferUnitCombo->currentIndex() == HeatmapGui::Meters )
+  if ( mBufferUnitCombo->currentIndex() == HeatmapGui::LayerUnits )
   {
     radius = mapUnitsOf( radius, inputVectorLayer()->crs() );
   }
diff --git a/src/plugins/heatmap/heatmapgui.h b/src/plugins/heatmap/heatmapgui.h
index 1882827..ea125fa 100644
--- a/src/plugins/heatmap/heatmapgui.h
+++ b/src/plugins/heatmap/heatmapgui.h
@@ -33,7 +33,7 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
     // Should have been private, made public to be used in heatmap.cpp
     enum mBufferType
     {
-      Meters,
+      LayerUnits,
       MapUnits
     };
 
@@ -46,7 +46,7 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
     /** Returns the fixed radius value */
     double radius() const;
 
-    /** Return the radius Unit (meters/map units) */
+    /** Return the radius unit (layer/map units) */
     int radiusUnit() const;
 
     /** Return the selected kernel shape */
@@ -119,8 +119,8 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
     /** Update the LineEdits cellsize and row&col values  */
     void updateSize();
 
-    /** Convert Maters value to the corresponding map units based on Layer projection */
-    double mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs ) const;
+    /** Convert layer distance value to the corresponding map units based on layer projection */
+    double mapUnitsOf( double dist, const QgsCoordinateReferenceSystem& layerCrs ) const;
 
     /** Estimate a reasonable starting value for the radius field */
     double estimateRadius();
diff --git a/src/plugins/heatmap/heatmapguibase.ui b/src/plugins/heatmap/heatmapguibase.ui
index 11b02ce..ace6df6 100644
--- a/src/plugins/heatmap/heatmapguibase.ui
+++ b/src/plugins/heatmap/heatmapguibase.ui
@@ -89,7 +89,7 @@
       <widget class="QComboBox" name="mBufferUnitCombo">
        <item>
         <property name="text">
-         <string>meters</string>
+         <string>layer units</string>
         </property>
        </item>
        <item>
@@ -269,7 +269,7 @@
           </property>
           <item>
            <property name="text">
-            <string>meters</string>
+            <string>layer units</string>
            </property>
           </item>
           <item>
diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp
index d04525b..2bd6784 100644
--- a/src/providers/ogr/qgsogrprovider.cpp
+++ b/src/providers/ogr/qgsogrprovider.cpp
@@ -370,7 +370,7 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
   QgsDebugMsg( "mSubsetString: " + mSubsetString );
   CPLSetConfigOption( "OGR_ORGANIZE_POLYGONS", "ONLY_CCW" );  // "SKIP" returns MULTIPOLYGONs for multiringed POLYGONs
 
-  if ( mFilePath.startsWith( "MySQL:" ) && !mLayerName.isEmpty() )
+  if ( mFilePath.startsWith( "MySQL:" ) && !mLayerName.isEmpty() && !mFilePath.endsWith( ",tables=" + mLayerName ) )
   {
     mFilePath += ",tables=" + mLayerName;
   }
diff --git a/src/providers/oracle/qgsoracleprovider.cpp b/src/providers/oracle/qgsoracleprovider.cpp
index 3a63558..77280e6 100644
--- a/src/providers/oracle/qgsoracleprovider.cpp
+++ b/src/providers/oracle/qgsoracleprovider.cpp
@@ -694,7 +694,7 @@ bool QgsOracleProvider::loadFields()
 
       if ( !mHasSpatialIndex )
       {
-        mHasSpatialIndex = qry.exec( QString( "SELECT %2 FROM %1 WHERE sdo_filter(%2,mdsys.sdo_geometry(2003,%3,NULL,mdsys.sdo_elem_info_array(1,1003,3),mdsys.sdo_ordinate_array(1,1,-1,-1)))='TRUE'" )
+        mHasSpatialIndex = qry.exec( QString( "SELECT %2 FROM %1 WHERE sdo_filter(%2,mdsys.sdo_geometry(2003,%3,NULL,mdsys.sdo_elem_info_array(1,1003,3),mdsys.sdo_ordinate_array(-1,-1,1,1)))='TRUE'" )
                                      .arg( mQuery )
                                      .arg( quotedIdentifier( mGeometryColumn ) )
                                      .arg( mSrid < 1 ? "NULL" : QString::number( mSrid ) ) );
diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp
index 5db4b98..78a1731 100644
--- a/src/providers/postgres/qgspostgresprovider.cpp
+++ b/src/providers/postgres/qgspostgresprovider.cpp
@@ -128,11 +128,15 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
     return;
   }
 
+  // NOTE: mValid would be true after true return from
+  // getGeometryDetails, see http://hub.qgis.org/issues/13781
+
   if ( mSpatialColType == sctTopoGeometry )
   {
     if ( !getTopoLayerInfo() ) // gets topology name and layer id
     {
       QgsMessageLog::logMessage( tr( "invalid PostgreSQL topology layer" ), tr( "PostGIS" ) );
+      mValid = false;
       disconnectDb();
       return;
     }
@@ -1103,6 +1107,9 @@ bool QgsPostgresProvider::determinePrimaryKey()
           if ( res.PQntuples() == 1 )
           {
             mPrimaryKeyType = pktTid;
+
+            QgsMessageLog::logMessage( tr( "Primary key is ctid - changing of existing features disabled (%1; %2)" ).arg( mGeometryColumn ).arg( mQuery ) );
+            mEnabledCapabilities &= ~( QgsVectorDataProvider::DeleteFeatures | QgsVectorDataProvider::ChangeAttributeValues | QgsVectorDataProvider::ChangeGeometries );
           }
           else
           {
diff --git a/src/server/qgshttprequesthandler.cpp b/src/server/qgshttprequesthandler.cpp
index 11d9961..825c452 100644
--- a/src/server/qgshttprequesthandler.cpp
+++ b/src/server/qgshttprequesthandler.cpp
@@ -131,7 +131,6 @@ void QgsHttpRequestHandler::sendHeaders()
       printf( it.value().toLocal8Bit() );
       printf( "\n" );
     }
-    printf( "\n" );
   }
   printf( "\n" );
   mHeaders.clear();
diff --git a/src/server/qgsserverprojectparser.cpp b/src/server/qgsserverprojectparser.cpp
index 0fd5b38..78e9bcc 100644
--- a/src/server/qgsserverprojectparser.cpp
+++ b/src/server/qgsserverprojectparser.cpp
@@ -17,6 +17,7 @@
 
 #include "qgsserverprojectparser.h"
 #include "qgsapplication.h"
+#include "qgsproject.h"
 #include "qgsconfigcache.h"
 #include "qgsconfigparserutils.h"
 #include "qgscrscache.h"
@@ -61,8 +62,8 @@ QgsServerProjectParser::QgsServerProjectParser( QDomDocument* xmlDoc, const QStr
       }
     }
 
-    mRestrictedLayers = findRestrictedLayers();
     mUseLayerIDs = findUseLayerIDs();
+    mRestrictedLayers = findRestrictedLayers();
 
     mCustomLayerOrder.clear();
 
@@ -76,6 +77,12 @@ QgsServerProjectParser::QgsServerProjectParser( QDomDocument* xmlDoc, const QStr
       }
     }
   }
+  // Setting the QgsProject instance fileName
+  // to help converting relative pathes to absolute
+  if ( mProjectPath != "" )
+  {
+    QgsProject::instance()->setFileName( mProjectPath );
+  }
 }
 
 QgsServerProjectParser::QgsServerProjectParser()
@@ -169,6 +176,8 @@ QgsMapLayer* QgsServerProjectParser::createLayerFromElement( const QDomElement&
   QDomElement dataSourceElem = elem.firstChildElement( "datasource" );
   QString uri = dataSourceElem.text();
   QString absoluteUri;
+  // If QgsProject instance fileName is set,
+  // Is converting relative pathes to absolute still relevant ?
   if ( !dataSourceElem.isNull() )
   {
     //convert relative pathes to absolute ones if necessary
@@ -1059,6 +1068,28 @@ QSet<QString> QgsServerProjectParser::findRestrictedLayers() const
       }
     }
   }
+  
+  // wmsLayerRestrictionValues contains LayerIDs
+  if ( mUseLayerIDs )
+  {
+    QDomNodeList legendLayerList = legendElem.elementsByTagName( "legendlayer" );
+    for ( int i = 0; i < legendLayerList.size(); ++i )
+    {
+      //get name
+      QDomElement layerElem = legendLayerList.at( i ).toElement();
+      QString layerName = layerElem.attribute( "name" );
+      if ( restrictedLayerSet.contains( layerName ) ) //match: add layer id
+      {
+        // get legend layer file element
+        QDomNodeList layerfileList = layerElem.elementsByTagName( "legendlayerfile" );
+        if ( layerfileList.size() > 0 )
+        {
+          // add layer id
+          restrictedLayerSet.insert( layerfileList.at( 0 ).toElement().attribute( "layerid" ) );
+        }
+      }
+    }
+  }
   return restrictedLayerSet;
 }
 
diff --git a/src/server/qgswfsserver.cpp b/src/server/qgswfsserver.cpp
index 6d3e425..3056b41 100644
--- a/src/server/qgswfsserver.cpp
+++ b/src/server/qgswfsserver.cpp
@@ -504,10 +504,10 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
 
         //map extent
         searchRect = layer->extent();
-        searchRect.set( searchRect.xMinimum() - 0.000001
-                        , searchRect.yMinimum() - 0.000001
-                        , searchRect.xMaximum() + 0.000001
-                        , searchRect.yMaximum() + 0.000001 );
+        searchRect.set( searchRect.xMinimum() - 1. / pow( 10., layerPrec )
+                        , searchRect.yMinimum() - 1. / pow( 10., layerPrec )
+                        , searchRect.xMaximum() + 1. / pow( 10., layerPrec )
+                        , searchRect.yMaximum() + 1. / pow( 10., layerPrec ) );
         layerCrs = layer->crs();
 
         QgsFeatureIterator fit = layer->getFeatures(
@@ -843,10 +843,10 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
       if ( bboxOk )
         searchRect.set( minx, miny, maxx, maxy );
       else
-        searchRect.set( searchRect.xMinimum() - 0.000001,
-                        searchRect.yMinimum() - 0.000001,
-                        searchRect.xMaximum() + 0.000001,
-                        searchRect.yMaximum() + 0.000001 );
+        searchRect.set( searchRect.xMinimum() - 1. / pow( 10., layerPrec ),
+                        searchRect.yMinimum() - 1. / pow( 10., layerPrec ),
+                        searchRect.xMaximum() + 1. / pow( 10., layerPrec ),
+                        searchRect.yMaximum() + 1. / pow( 10., layerPrec ) );
       layerCrs = layer->crs();
 
       long featCounter = 0;
@@ -1723,7 +1723,10 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoord
     else
     {
       fStr += "\"";
-      fStr +=  val.toString().replace( QString( "\"" ), QString( "\\\"" ) );
+      fStr +=  val.toString()
+               .replace( '"', "\\\"" )
+               .replace( '\r', "\\r" )
+               .replace( '\n', "\\n" );
       fStr += "\"";
     }
     fStr += "\n";
diff --git a/src/server/qgswmsconfigparser.cpp b/src/server/qgswmsconfigparser.cpp
index 9d1a908..8154198 100644
--- a/src/server/qgswmsconfigparser.cpp
+++ b/src/server/qgswmsconfigparser.cpp
@@ -132,24 +132,34 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
     if ( !layers.isEmpty() )
     {
       QStringList layerSet;
-      QStringList wmsLayerList = layers.split( "," );
+      QStringList wmsLayerList = layers.split( ",", QString::SkipEmptyParts );
       QStringList wmsStyleList;
 
       if ( !styles.isEmpty() )
       {
-        wmsStyleList = styles.split( "," );
+        wmsStyleList = styles.split( ",", QString::SkipEmptyParts );
       }
 
       for ( int i = 0; i < wmsLayerList.size(); ++i )
       {
+        QString wmsLayer = wmsLayerList.at( i );
         QString styleName;
         if ( wmsStyleList.size() > i )
         {
           styleName = wmsStyleList.at( i );
         }
+        
+        bool allowCaching = true;
+        if ( wmsLayerList.count( wmsLayer ) > 1 )
+        {
+          allowCaching = false;
+        }
 
-        foreach ( QgsMapLayer *layer, mapLayerFromStyle( wmsLayerList.at( i ), styleName ) )
+        QList<QgsMapLayer*> layerList = mapLayerFromStyle( wmsLayer, styleName, allowCaching );
+        int listIndex;
+        for ( listIndex = layerList.size() - 1; listIndex >= 0; listIndex-- )
         {
+          QgsMapLayer* layer = layerList.at( listIndex );
           if ( layer )
           {
             layerSet.push_back( layer->id() );
diff --git a/src/server/qgswmsprojectparser.cpp b/src/server/qgswmsprojectparser.cpp
index 488d645..98bf602 100644
--- a/src/server/qgswmsprojectparser.cpp
+++ b/src/server/qgswmsprojectparser.cpp
@@ -118,7 +118,7 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName
   }
 
   // can't use layer cache if we are going to apply a non-default style
-  if ( !styleName.isEmpty() )
+  if ( !styleName.isEmpty() && styleName != EMPTY_STYLE_NAME )
     useCache = false;
 
   //does lName refer to a leaf layer
@@ -127,7 +127,7 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName
   if ( layerElemIt != projectLayerElements.constEnd() )
   {
     QgsMapLayer* ml = mProjectParser->createLayerFromElement( layerElemIt.value(), useCache );
-    if ( !styleName.isEmpty() )
+    if ( !styleName.isEmpty() && styleName != EMPTY_STYLE_NAME )
     {
       // try to apply the specified style
       if ( !ml->styleManager()->setCurrentStyle( styleName != EMPTY_STYLE_NAME ? styleName : QString() ) )
@@ -258,7 +258,8 @@ void QgsWMSProjectParser::addLayersFromGroup( const QDomElement& legendGroupElem
   {
     QMap< int, QDomElement > layerOrderList;
     QDomNodeList groupElemChildren = legendGroupElem.childNodes();
-    for ( int i = 0; i < groupElemChildren.size(); ++i )
+    // for rendering layers has to be add from bottom (end) to top (start)
+    for ( int i = groupElemChildren.size()-1; i >= 0 ; --i )
     {
       QDomElement elem = groupElemChildren.at( i ).toElement();
       if ( elem.tagName() == "legendgroup" )
@@ -1537,6 +1538,7 @@ QDomDocument QgsWMSProjectParser::getStyles( QStringList& layerList ) const
   // Create the root element
   QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
   root.setAttribute( "version", "1.1.0" );
+  root.setAttribute( "units", "mm" ); // default qgsmaprenderer is Millimeters
   root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
   root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
   root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
diff --git a/src/server/qgswmsserver.cpp b/src/server/qgswmsserver.cpp
index 81ffba4..c3d6d93 100644
--- a/src/server/qgswmsserver.cpp
+++ b/src/server/qgswmsserver.cpp
@@ -1804,9 +1804,6 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
       throw QgsMapServiceException( "InvalidCRS", "Could not create output CRS" );
       return 5;
     }
-    mMapRenderer->setDestinationCrs( outputCRS );
-    mMapRenderer->setProjectionsEnabled( true );
-    mapUnits = outputCRS.mapUnits();
 
     //read layer coordinate transforms from project file (e.g. ct with special datum shift)
     if ( mConfigParser )
@@ -1819,6 +1816,11 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
         mMapRenderer->addLayerCoordinateTransform( ltIt->first, t.srcAuthId, t.destAuthId, t.srcDatumTransform, t.destDatumTransform );
       }
     }
+    
+    //then set destinationCrs
+    mMapRenderer->setDestinationCrs( outputCRS );
+    mMapRenderer->setProjectionsEnabled( true );
+    mapUnits = outputCRS.mapUnits();
   }
   mMapRenderer->setMapUnits( mapUnits );
 
diff --git a/src/ui/qgsadvanceddigitizingdockwidgetbase.ui b/src/ui/qgsadvanceddigitizingdockwidgetbase.ui
index b55aa6c..76e67c3 100644
--- a/src/ui/qgsadvanceddigitizingdockwidgetbase.ui
+++ b/src/ui/qgsadvanceddigitizingdockwidgetbase.ui
@@ -195,13 +195,24 @@
              <number>3</number>
             </property>
             <item row="2" column="2">
-             <widget class="QLineEdit" name="mXLineEdit"/>
+             <widget class="QLineEdit" name="mXLineEdit">
+              <property name="toolTip">
+               <string>X coordinate</string>
+              </property>
+             </widget>
             </item>
             <item row="0" column="2">
-             <widget class="QLineEdit" name="mDistanceLineEdit"/>
+             <widget class="QLineEdit" name="mDistanceLineEdit">
+              <property name="toolTip">
+               <string>Distance</string>
+              </property>
+             </widget>
             </item>
             <item row="0" column="3">
              <widget class="QToolButton" name="mLockDistanceButton">
+              <property name="toolTip">
+               <string>Lock distance</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -216,6 +227,9 @@
             </item>
             <item row="1" column="3">
              <widget class="QToolButton" name="mLockAngleButton">
+              <property name="toolTip">
+               <string>Lock angle</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -230,6 +244,9 @@
             </item>
             <item row="3" column="3">
              <widget class="QToolButton" name="mLockYButton">
+              <property name="toolTip">
+               <string>Lock y coordinate</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -251,6 +268,9 @@
             </item>
             <item row="3" column="0">
              <widget class="QToolButton" name="mRelativeYButton">
+              <property name="toolTip">
+               <string>Toggles relative y to previous node</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -271,7 +291,11 @@
              </widget>
             </item>
             <item row="1" column="2">
-             <widget class="QLineEdit" name="mAngleLineEdit"/>
+             <widget class="QLineEdit" name="mAngleLineEdit">
+              <property name="toolTip">
+               <string>Angle</string>
+              </property>
+             </widget>
             </item>
             <item row="2" column="1">
              <widget class="QLabel" name="label_3">
@@ -281,10 +305,17 @@
              </widget>
             </item>
             <item row="3" column="2">
-             <widget class="QLineEdit" name="mYLineEdit"/>
+             <widget class="QLineEdit" name="mYLineEdit">
+              <property name="toolTip">
+               <string>Y coordinate</string>
+              </property>
+             </widget>
             </item>
             <item row="2" column="0">
              <widget class="QToolButton" name="mRelativeXButton">
+              <property name="toolTip">
+               <string>Toggles relative x to previous node</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -306,6 +337,9 @@
             </item>
             <item row="2" column="3">
              <widget class="QToolButton" name="mLockXButton">
+              <property name="toolTip">
+               <string>Lock x coordinate</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -320,6 +354,9 @@
             </item>
             <item row="1" column="0">
              <widget class="QToolButton" name="mRelativeAngleButton">
+              <property name="toolTip">
+               <string>Toggles relative angle to previous segment</string>
+              </property>
               <property name="text">
                <string>...</string>
               </property>
@@ -378,8 +415,8 @@
   <tabstop>mLockYButton</tabstop>
  </tabstops>
  <resources>
-  <include location="../../images/images.qrc"/>
   <include location="../plugins/georeferencer/georeferencer.qrc"/>
+  <include location="../../images/images.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/tests/src/core/CMakeLists.txt b/tests/src/core/CMakeLists.txt
index ac7f4b3..bbffec3 100644
--- a/tests/src/core/CMakeLists.txt
+++ b/tests/src/core/CMakeLists.txt
@@ -142,6 +142,7 @@ ADD_QGIS_TEST(colorscheme testqgscolorscheme.cpp)
 ADD_QGIS_TEST(maptopixeltest testqgsmaptopixel.cpp)
 ADD_QGIS_TEST(maprotationtest testqgsmaprotation.cpp)
 ADD_QGIS_TEST(mapsettingstest testqgsmapsettings.cpp)
+ADD_QGIS_TEST(markerlinessymboltest testqgsmarkerlinesymbol.cpp)
 ADD_QGIS_TEST(networkcontentfetcher testqgsnetworkcontentfetcher.cpp )
 ADD_QGIS_TEST(legendrenderertest testqgslegendrenderer.cpp )
 ADD_QGIS_TEST(vectorlayerjoinbuffer testqgsvectorlayerjoinbuffer.cpp )
diff --git a/tests/src/core/testqgscomposermap.cpp b/tests/src/core/testqgscomposermap.cpp
index df6eb1a..2b52e89 100644
--- a/tests/src/core/testqgscomposermap.cpp
+++ b/tests/src/core/testqgscomposermap.cpp
@@ -155,12 +155,23 @@ void TestQgsComposerMap::worldFileGeneration()
   double a, b, c, d, e, f;
   mComposition->computeWorldFileParameters( a, b, c, d, e, f );
 
-  QVERIFY( fabs( a - 4.18048 ) < 0.001 );
-  QVERIFY( fabs( b - 2.41331 ) < 0.001 );
-  QVERIFY( fabs( c - 779444 ) < 1 );
-  QVERIFY( fabs( d - 2.4136 ) < 0.001 );
-  QVERIFY( fabs( e + 4.17997 ) < 0.001 );
-  QVERIFY( fabs( f - 3.34241e+06 ) < 1e+03 );
+  QVERIFY( qgsDoubleNear( a, 4.18048, 0.001 ) );
+  QVERIFY( qgsDoubleNear( b, 2.41331, 0.001 ) );
+  QVERIFY( qgsDoubleNear( c, 779444, 1 ) );
+  QVERIFY( qgsDoubleNear( d, 2.4136, 0.001 ) );
+  QVERIFY( qgsDoubleNear( e, -4.17997, 0.001 ) );
+  QVERIFY( qgsDoubleNear( f, 3.34241e+06, 1e+03 ) );
+
+  //test with map on second page. Parameters should be the same
+  mComposerMap->setItemPosition( 20, 20, QgsComposerItem::UpperLeft, 2 );
+  mComposition->computeWorldFileParameters( a, b, c, d, e, f );
+
+  QVERIFY( qgsDoubleNear( a, 4.18048, 0.001 ) );
+  QVERIFY( qgsDoubleNear( b, 2.41331, 0.001 ) );
+  QVERIFY( qgsDoubleNear( c, 779444, 1 ) );
+  QVERIFY( qgsDoubleNear( d, 2.4136, 0.001 ) );
+  QVERIFY( qgsDoubleNear( e, -4.17997, 0.001 ) );
+  QVERIFY( qgsDoubleNear( f, 3.34241e+06, 1e+03 ) );
 
   mComposition->setGenerateWorldFile( false );
   mComposerMap->setMapRotation( 0.0 );
diff --git a/tests/src/core/testqgsdistancearea.cpp b/tests/src/core/testqgsdistancearea.cpp
index c106a46..8e1ec0a 100644
--- a/tests/src/core/testqgsdistancearea.cpp
+++ b/tests/src/core/testqgsdistancearea.cpp
@@ -34,6 +34,7 @@ class TestQgsDistanceArea: public QObject
     void basic();
     void test_distances();
     void unit_conversions();
+    void measureUnits();
 };
 
 void TestQgsDistanceArea::initTestCase()
@@ -163,11 +164,31 @@ void TestQgsDistanceArea::unit_conversions()
   QString myTxt = QgsDistanceArea::textUnit( inputValue, 7, inputUnit, true, false );
   QString expectedTxt = QLocale::system().toString( 2.4710538146717, 'g', 1 + 7 );
   QVERIFY( myTxt.startsWith( expectedTxt ) ); // Ignore units for now.
-};
+}
+
+void TestQgsDistanceArea::measureUnits()
+{
+  //test regression #13610
+  QgsDistanceArea calc;
+  calc.setEllipsoidalMode( false );
+  calc.setEllipsoid( "NONE" );
+  calc.setSourceCrs( 254L );
+  QGis::UnitType units;
+  QgsPoint p1( 1341683.9854275715, 408256.9562717728 );
+  QgsPoint p2( 1349321.7807031618, 408256.9562717728 );
+
+  double result = calc.measureLine( p1, p2, units );
+  //no OTF, result will be in CRS unit (feet)
+  QCOMPARE( units, QGis::Feet );
+  QVERIFY( qgsDoubleNear( result, 7637.7952755903825, 0.001 ) );
+
+  calc.setEllipsoidalMode( true );
+  calc.setEllipsoid( "WGS84" );
+  result = calc.measureLine( p1, p2, units );
+  //OTF, result will be in meters
+  QCOMPARE( units, QGis::Meters );
+  QVERIFY( qgsDoubleNear( result, 2328.0988253106957, 0.001 ) );
+}
 
 QTEST_MAIN( TestQgsDistanceArea )
 #include "testqgsdistancearea.moc"
-
-
-
-
diff --git a/tests/src/core/testqgsmarkerlinesymbol.cpp b/tests/src/core/testqgsmarkerlinesymbol.cpp
new file mode 100644
index 0000000..fdec55e
--- /dev/null
+++ b/tests/src/core/testqgsmarkerlinesymbol.cpp
@@ -0,0 +1,154 @@
+/***************************************************************************
+     testqgsmarkerlinesymbol.cpp
+     --------------------------------------
+    Date                 : Nov 12  2015
+    Copyright            : (C) 2015 by Sandro Santilli
+    Email                : strk at keybit.net
+ ***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include <QtTest/QtTest>
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QApplication>
+#include <QFileInfo>
+#include <QDir>
+
+//qgis includes...
+#include "qgsrasterlayer.h"
+#include "qgsvectorlayer.h"
+#include "qgsmultibandcolorrenderer.h"
+#include "qgsmaplayerregistry.h"
+#include "qgsapplication.h"
+#include "qgsmaprenderer.h"
+#include "qgspallabeling.h"
+#include "qgsfontutils.h"
+
+//qgis unit test includes
+#include <qgsrenderchecker.h>
+
+/** \ingroup UnitTests
+ * This is a unit test for the Marker Line symbol
+ */
+class TestQgsMarkerLineSymbol : public QObject
+{
+    Q_OBJECT
+  public:
+    TestQgsMarkerLineSymbol()
+        : mLinesLayer( 0 )
+        , mMapSettings( 0 )
+    {
+      mTestDataDir = QString( TEST_DATA_DIR ) + '/';
+    }
+
+    ~TestQgsMarkerLineSymbol();
+
+  private slots:
+    void initTestCase();// will be called before the first testfunction is executed.
+    void cleanupTestCase();// will be called after the last testfunction was executed.
+    void init() {} // will be called before each testfunction is executed.
+    void cleanup() {} // will be called after every testfunction.
+
+    void lineOffset();
+
+  private:
+    bool render( const QString& theFileName );
+
+    QString mTestDataDir;
+    QgsVectorLayer* mLinesLayer;
+    QgsMapSettings *mMapSettings;
+    QString mReport;
+};
+
+//runs before all tests
+void TestQgsMarkerLineSymbol::initTestCase()
+{
+  // init QGIS's paths - true means that all path will be inited from prefix
+  QgsApplication::init();
+  QgsApplication::initQgis();
+
+  mMapSettings = new QgsMapSettings();
+
+  QList<QgsMapLayer *> mapLayers;
+
+  //create a line layer that will be used in all tests...
+  QString myLinesFileName = mTestDataDir + "lines_cardinals.shp";
+  QFileInfo myLinesFileInfo( myLinesFileName );
+  mLinesLayer = new QgsVectorLayer( myLinesFileInfo.filePath(),
+                                    myLinesFileInfo.completeBaseName(), "ogr" );
+  mapLayers << mLinesLayer;
+
+  // Register all layers with the registry
+  QgsMapLayerRegistry::instance()->addMapLayers( mapLayers );
+
+  // This is needed to correctly set rotation center,
+  // the actual size doesn't matter as QgsRenderChecker will
+  // re-set it to the size of the expected image
+  mMapSettings->setOutputSize( QSize( 256, 256 ) );
+
+  mReport += "<h1>Line Marker Symbol Tests</h1>\n";
+
+  QgsFontUtils::loadStandardTestFonts( QStringList() << "Bold" );
+}
+
+TestQgsMarkerLineSymbol::~TestQgsMarkerLineSymbol()
+{
+
+}
+
+//runs after all tests
+void TestQgsMarkerLineSymbol::cleanupTestCase()
+{
+  delete mMapSettings;
+  QgsApplication::exitQgis();
+
+  QString myReportFile = QDir::tempPath() + "/qgistest.html";
+  QFile myFile( myReportFile );
+  if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
+  {
+    QTextStream myQTextStream( &myFile );
+    myQTextStream << mReport;
+    myFile.close();
+  }
+}
+
+void TestQgsMarkerLineSymbol::lineOffset()
+{
+  mMapSettings->setLayers( QStringList() << mLinesLayer->id() );
+
+  // Negative offset on marker line
+  // See http://hub.qgis.org/issues/13811
+
+  QString qml = mTestDataDir + "marker_line_offset.qml";
+  bool success = false;
+  mLinesLayer->loadNamedStyle( qml, success );
+
+  QVERIFY( success );
+  mMapSettings->setExtent( QgsRectangle(-140,-140,140,140) );
+  QVERIFY( render( "line_offset" ) );
+
+  // TODO: -0.0 offset, see 
+  // http://hub.qgis.org/issues/13811#note-1
+}
+
+bool TestQgsMarkerLineSymbol::render( const QString& theTestType )
+{
+  mReport += "<h2>" + theTestType + "</h2>\n";
+  mMapSettings->setOutputDpi( 96 );
+  QgsRenderChecker checker;
+  checker.setControlPathPrefix( "markerlinesymbol" );
+  checker.setControlName( "expected_" + theTestType );
+  checker.setMapSettings( *mMapSettings );
+  bool result = checker.runTest( theTestType );
+  mReport += "\n\n\n" + checker.report();
+  return result;
+}
+
+QTEST_MAIN( TestQgsMarkerLineSymbol )
+#include "testqgsmarkerlinesymbol.moc"
diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt
index 28b4ebd..772011f 100644
--- a/tests/src/python/CMakeLists.txt
+++ b/tests/src/python/CMakeLists.txt
@@ -16,6 +16,7 @@ ADD_PYTHON_TEST(PyQgsLogger test_qgslogger.py)
 ADD_PYTHON_TEST(PyQgsCoordinateTransform test_qgscoordinatetransform.py)
 ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py)
 ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py)
+ADD_PYTHON_TEST(PyQgsMapUnitScale test_qgsmapunitscale.py)
 ADD_PYTHON_TEST(PyQgsSpatialIndex test_qgsspatialindex.py)
 ADD_PYTHON_TEST(PyQgsComposerHtml test_qgscomposerhtml.py)
 ADD_PYTHON_TEST(PyQgsComposition test_qgscomposition.py)
diff --git a/tests/src/python/test_qgsmapunitscale.py b/tests/src/python/test_qgsmapunitscale.py
new file mode 100644
index 0000000..c21cc62
--- /dev/null
+++ b/tests/src/python/test_qgsmapunitscale.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+"""QGIS Unit tests for QgsMapUnitScale.
+
+.. note:: This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+"""
+__author__ = 'Nyall Dawson'
+__date__ = '2015-09'
+__copyright__ = 'Copyright 2015, The QGIS Project'
+# This will get replaced with a git SHA1 when you do a git archive
+__revision__ = '$Format:%H$'
+
+import qgis
+
+from qgis.core import (QgsMapUnitScale, QgsRenderContext, QgsMapSettings, QgsRectangle)
+from PyQt4.QtCore import QSize
+from utilities import (TestCase, unittest)
+
+
+class PyQgsMapUnitScale(TestCase):
+
+    def testConstructor(self):
+        #test creating QgsMapUnitScale
+        c = QgsMapUnitScale()
+        self.assertEqual(c.minScale, 0)
+        self.assertEqual(c.maxScale, 0)
+
+        c = QgsMapUnitScale(0.0001, 0.005)
+        self.assertEqual(c.minScale, 0.0001)
+        self.assertEqual(c.maxScale, 0.005)
+
+    def testEquality(self):
+        #test equality operator
+
+        c1 = QgsMapUnitScale(0.0001, 0.005)
+        c2 = QgsMapUnitScale(0.0001, 0.005)
+        self.assertEqual(c1, c2)
+
+        c2.minScale = 0.0004
+        self.assertNotEqual(c1, c2)
+
+        c2.minScale = 0.0001
+        c2.maxScale = 0.007
+        self.assertNotEqual(c1, c2)
+
+        c2.maxScale = 0.005
+        self.assertEqual(c1, c2)
+
+    def testMapUnitsPerPixel(self):
+        #test computeMapUnitsPerPixel
+
+        ms = QgsMapSettings()
+        ms.setExtent(QgsRectangle(0, 0, 100, 100))
+        ms.setOutputSize(QSize(100, 50))
+        r = QgsRenderContext.fromMapSettings(ms)
+
+        #renderer scale should be about 1:291937841
+
+        #start with no min/max scale
+        c = QgsMapUnitScale()
+
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 2.0, places=5)
+
+        #add a minimum scale less than the renderer scale, so should be no change
+        c.minScale = 1 / 350000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 2.0, places=5)
+
+        #minimum scale greater than the renderer scale, so should be limited to minScale
+        c.minScale = 1 / 150000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 1.0276160, places=5)
+        c.minScale = 1 / 50000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 0.3425386, places=5)
+        c.minScale = 1 / 350000000.0
+
+        #add a maximum scale greater than the renderer scale, so should be no change
+        c.maxScale = 1 / 150000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 2.0, places=5)
+
+        #maximum scale less than the renderer scale, so should be limited to maxScale
+        c.maxScale = 1 / 350000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 2.3977706, places=5)
+        c.maxScale = 1 / 500000000.0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 3.4253867, places=5)
+
+        #test resetting to min/max
+        c.minScale = 0
+        c.maxScale = 0
+        mup = c.computeMapUnitsPerPixel(r)
+        self.assertAlmostEqual(mup, 2.0, places=5)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/testdata/control_images/markerlinesymbol/expected_line_offset/expected_line_offset.png b/tests/testdata/control_images/markerlinesymbol/expected_line_offset/expected_line_offset.png
new file mode 100644
index 0000000..756dad1
Binary files /dev/null and b/tests/testdata/control_images/markerlinesymbol/expected_line_offset/expected_line_offset.png differ
diff --git a/tests/testdata/marker_line_offset.qml b/tests/testdata/marker_line_offset.qml
new file mode 100644
index 0000000..20eb0ea
--- /dev/null
+++ b/tests/testdata/marker_line_offset.qml
@@ -0,0 +1,284 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis version="2.13.0-Master" minimumScale="1" maximumScale="1e+08" simplifyDrawingHints="1" minLabelScale="1" maxLabelScale="1e+08" simplifyDrawingTol="1" simplifyMaxScale="1" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
+  <renderer-v2 attr="LBL" forceraster="0" symbollevels="0" type="categorizedSymbol">
+    <categories>
+      <category render="true" symbol="0" value="East" label="East"/>
+      <category render="true" symbol="1" value="North" label="North"/>
+      <category render="true" symbol="2" value="West" label="West"/>
+      <category render="true" symbol="3" value="South" label="South"/>
+    </categories>
+    <symbols>
+      <symbol alpha="1" clip_to_extent="1" type="line" name="0">
+        <layer pass="0" class="SimpleLine" locked="0">
+          <prop k="capstyle" v="square"/>
+          <prop k="customdash" v="5;2"/>
+          <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="customdash_unit" v="MM"/>
+          <prop k="draw_inside_polygon" v="0"/>
+          <prop k="joinstyle" v="bevel"/>
+          <prop k="line_color" v="203,16,23,255"/>
+          <prop k="line_style" v="solid"/>
+          <prop k="line_width" v="1.2"/>
+          <prop k="line_width_unit" v="MM"/>
+          <prop k="offset" v="0"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="use_custom_dash" v="0"/>
+          <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+        </layer>
+        <layer pass="0" class="MarkerLine" locked="0">
+          <prop k="interval" v="3"/>
+          <prop k="interval_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="interval_unit" v="MM"/>
+          <prop k="offset" v="3"/>
+          <prop k="offset_along_line" v="0"/>
+          <prop k="offset_along_line_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_along_line_unit" v="MM"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="placement" v="lastvertex"/>
+          <prop k="rotate" v="1"/>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="@0 at 1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="203,16,23,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="name" v="filled_arrowhead"/>
+              <prop k="offset" v="2,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,0"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="7"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </layer>
+      </symbol>
+      <symbol alpha="1" clip_to_extent="1" type="line" name="1">
+        <layer pass="0" class="SimpleLine" locked="0">
+          <prop k="capstyle" v="square"/>
+          <prop k="customdash" v="5;2"/>
+          <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="customdash_unit" v="MM"/>
+          <prop k="draw_inside_polygon" v="0"/>
+          <prop k="joinstyle" v="bevel"/>
+          <prop k="line_color" v="0,0,0,255"/>
+          <prop k="line_style" v="solid"/>
+          <prop k="line_width" v="1.2"/>
+          <prop k="line_width_unit" v="MM"/>
+          <prop k="offset" v="0"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="use_custom_dash" v="0"/>
+          <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+        </layer>
+        <layer pass="0" class="MarkerLine" locked="0">
+          <prop k="interval" v="3"/>
+          <prop k="interval_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="interval_unit" v="MM"/>
+          <prop k="offset" v="3"/>
+          <prop k="offset_along_line" v="0"/>
+          <prop k="offset_along_line_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_along_line_unit" v="MM"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="placement" v="lastvertex"/>
+          <prop k="rotate" v="1"/>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="@1 at 1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="0,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="name" v="filled_arrowhead"/>
+              <prop k="offset" v="2,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,0"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="7"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </layer>
+      </symbol>
+      <symbol alpha="1" clip_to_extent="1" type="line" name="2">
+        <layer pass="0" class="SimpleLine" locked="0">
+          <prop k="capstyle" v="square"/>
+          <prop k="customdash" v="5;2"/>
+          <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="customdash_unit" v="MM"/>
+          <prop k="draw_inside_polygon" v="0"/>
+          <prop k="joinstyle" v="bevel"/>
+          <prop k="line_color" v="203,16,23,255"/>
+          <prop k="line_style" v="solid"/>
+          <prop k="line_width" v="1.2"/>
+          <prop k="line_width_unit" v="MM"/>
+          <prop k="offset" v="0"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="use_custom_dash" v="0"/>
+          <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+        </layer>
+        <layer pass="0" class="MarkerLine" locked="0">
+          <prop k="interval" v="3"/>
+          <prop k="interval_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="interval_unit" v="MM"/>
+          <prop k="offset" v="-3"/>
+          <prop k="offset_along_line" v="0"/>
+          <prop k="offset_along_line_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_along_line_unit" v="MM"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="placement" v="lastvertex"/>
+          <prop k="rotate" v="1"/>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="@2 at 1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="203,16,23,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="name" v="filled_arrowhead"/>
+              <prop k="offset" v="2,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,0"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="7"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </layer>
+      </symbol>
+      <symbol alpha="1" clip_to_extent="1" type="line" name="3">
+        <layer pass="0" class="SimpleLine" locked="0">
+          <prop k="capstyle" v="square"/>
+          <prop k="customdash" v="5;2"/>
+          <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="customdash_unit" v="MM"/>
+          <prop k="draw_inside_polygon" v="0"/>
+          <prop k="joinstyle" v="bevel"/>
+          <prop k="line_color" v="0,0,0,255"/>
+          <prop k="line_style" v="solid"/>
+          <prop k="line_width" v="1.2"/>
+          <prop k="line_width_unit" v="MM"/>
+          <prop k="offset" v="0"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="use_custom_dash" v="0"/>
+          <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+        </layer>
+        <layer pass="0" class="MarkerLine" locked="0">
+          <prop k="interval" v="3"/>
+          <prop k="interval_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="interval_unit" v="MM"/>
+          <prop k="offset" v="-3"/>
+          <prop k="offset_along_line" v="0"/>
+          <prop k="offset_along_line_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_along_line_unit" v="MM"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="placement" v="lastvertex"/>
+          <prop k="rotate" v="1"/>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="@3 at 1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="0,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="name" v="filled_arrowhead"/>
+              <prop k="offset" v="2,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,0"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="7"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </layer>
+      </symbol>
+    </symbols>
+    <source-symbol>
+      <symbol alpha="1" clip_to_extent="1" type="line" name="0">
+        <layer pass="0" class="SimpleLine" locked="0">
+          <prop k="capstyle" v="square"/>
+          <prop k="customdash" v="5;2"/>
+          <prop k="customdash_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="customdash_unit" v="MM"/>
+          <prop k="draw_inside_polygon" v="0"/>
+          <prop k="joinstyle" v="bevel"/>
+          <prop k="line_color" v="0,0,0,255"/>
+          <prop k="line_style" v="solid"/>
+          <prop k="line_width" v="1.2"/>
+          <prop k="line_width_unit" v="MM"/>
+          <prop k="offset" v="0"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="use_custom_dash" v="0"/>
+          <prop k="width_map_unit_scale" v="0,0,0,0,0,0"/>
+        </layer>
+        <layer pass="0" class="MarkerLine" locked="0">
+          <prop k="interval" v="3"/>
+          <prop k="interval_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="interval_unit" v="MM"/>
+          <prop k="offset" v="-3"/>
+          <prop k="offset_along_line" v="0"/>
+          <prop k="offset_along_line_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_along_line_unit" v="MM"/>
+          <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+          <prop k="offset_unit" v="MM"/>
+          <prop k="placement" v="lastvertex"/>
+          <prop k="rotate" v="1"/>
+          <symbol alpha="1" clip_to_extent="1" type="marker" name="@0 at 1">
+            <layer pass="0" class="SimpleMarker" locked="0">
+              <prop k="angle" v="0"/>
+              <prop k="color" v="0,0,0,255"/>
+              <prop k="horizontal_anchor_point" v="1"/>
+              <prop k="name" v="filled_arrowhead"/>
+              <prop k="offset" v="2,0"/>
+              <prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="offset_unit" v="MM"/>
+              <prop k="outline_color" v="0,0,0,255"/>
+              <prop k="outline_style" v="solid"/>
+              <prop k="outline_width" v="0"/>
+              <prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="outline_width_unit" v="MM"/>
+              <prop k="scale_method" v="area"/>
+              <prop k="size" v="7"/>
+              <prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
+              <prop k="size_unit" v="MM"/>
+              <prop k="vertical_anchor_point" v="1"/>
+            </layer>
+          </symbol>
+        </layer>
+      </symbol>
+    </source-symbol>
+    <colorramp type="randomcolors" name="[source]"/>
+    <invertedcolorramp value="0"/>
+    <rotation/>
+    <sizescale scalemethod="diameter"/>
+  </renderer-v2>
+</qgis>

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



More information about the Pkg-grass-devel mailing list