diff --git a/addons/account/wizard/wizard_tax_adjustments.py b/addons/account/wizard/wizard_tax_adjustments.py
index 8c5002347c01f83e4b3f6b0e0d59fbe0ba02c293..22d2235ef04f7f1d3f11465dc6792f745af3ea24 100644
--- a/addons/account/wizard/wizard_tax_adjustments.py
+++ b/addons/account/wizard/wizard_tax_adjustments.py
@@ -18,24 +18,26 @@ class TaxAdjustments(models.TransientModel):
     debit_account_id = fields.Many2one('account.account', string='Debit account', required=True, domain=[('deprecated', '=', False)])
     credit_account_id = fields.Many2one('account.account', string='Credit account', required=True, domain=[('deprecated', '=', False)])
     amount = fields.Monetary(currency_field='company_currency_id', required=True)
+    adjustment_type = fields.Selection([('debit', 'Adjustment in favor of the Estate'), ('credit', 'Adjustment in your favor')], string="Adjustment Type", store=False, required=True)
     company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.user.company_id.currency_id)
     tax_id = fields.Many2one('account.tax', string='Adjustment Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'none'), ('tax_adjustment', '=', True)], required=True)
 
     @api.multi
     def _create_move(self):
+        adjustment_type = self.env.context.get('adjustment_type', (self.amount > 0.0 and 'debit' or 'credit'))
         debit_vals = {
             'name': self.reason,
-            'debit': self.amount,
+            'debit': abs(self.amount),
             'credit': 0.0,
             'account_id': self.debit_account_id.id,
-            'tax_line_id': self.tax_id.id,
+            'tax_line_id': adjustment_type == 'debit' and self.tax_id.id or False,
         }
         credit_vals = {
             'name': self.reason,
             'debit': 0.0,
-            'credit': self.amount,
+            'credit': abs(self.amount),
             'account_id': self.credit_account_id.id,
-            'tax_line_id': self.tax_id.id,
+            'tax_line_id': adjustment_type == 'credit' and self.tax_id.id or False,
         }
         vals = {
             'journal_id': self.journal_id.id,
@@ -48,6 +50,13 @@ class TaxAdjustments(models.TransientModel):
         return move.id
 
     @api.multi
+    def create_move_debit(self):
+        return self.with_context(adjustment_type='debit').create_move()
+
+    @api.multi
+    def create_move_credit(self):
+        return self.with_context(adjustment_type='credit').create_move()
+
     def create_move(self):
         #create the adjustment move
         move_id = self._create_move()
diff --git a/addons/account/wizard/wizard_tax_adjustments_view.xml b/addons/account/wizard/wizard_tax_adjustments_view.xml
index 3d4ed0a9e9a6a0bb6671b4a1dbe5132f18555e7c..dba164388b90e3c39802d9a59890f998f8f34d1f 100644
--- a/addons/account/wizard/wizard_tax_adjustments_view.xml
+++ b/addons/account/wizard/wizard_tax_adjustments_view.xml
@@ -12,6 +12,7 @@
             <group>
                 <group>
                     <field name="amount"/>
+                    <field name="adjustment_type"/>
                 </group>
                 <group>
                     <field name="tax_id" widget="selection"/>
@@ -26,8 +27,14 @@
                 </group>
             </group>
             <footer>
-                <button name="create_move" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
+              <div attrs="{'invisible': [('adjustment_type', '=', 'credit')]}">
+                <button name="create_move_debit" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
                 <button string="Cancel" class="btn btn-default" special="cancel" />
+              </div>
+              <div attrs="{'invisible': [('adjustment_type', '!=', 'credit')]}">
+                <button name="create_move_credit" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
+                <button string="Cancel" class="btn btn-default" special="cancel" />
+              </div>
             </footer>
         </form>
         </field>
diff --git a/addons/account_asset/models/account_asset.py b/addons/account_asset/models/account_asset.py
index 78cd786cda874ed39746a135dbfb85c4e2807680..52d2c48a0d9b3619c914718a3e7aab62b14f63f4 100644
--- a/addons/account_asset/models/account_asset.py
+++ b/addons/account_asset/models/account_asset.py
@@ -411,7 +411,7 @@ class AccountAssetAsset(models.Model):
     @api.model
     def create(self, vals):
         asset = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals)
-        asset.compute_depreciation_board()
+        asset.sudo().compute_depreciation_board()
         return asset
 
     @api.multi
diff --git a/addons/hr_timesheet/report/report_timesheet_templates.xml b/addons/hr_timesheet/report/report_timesheet_templates.xml
index 141eb0511e88d4ecdda340152bc4ccba69afa766..c706143dd93ac91c5747bb9da3dc7015d00ae02f 100644
--- a/addons/hr_timesheet/report/report_timesheet_templates.xml
+++ b/addons/hr_timesheet/report/report_timesheet_templates.xml
@@ -36,7 +36,7 @@
                                                <span t-field="l.user_id.partner_id.name"/>
                                             </td>
                                             <td >
-                                                <span t-field="l.name"/>
+                                                <span t-field="l.name" t-options="{'widget': 'text'}"/>
                                             </td>
                                             <td t-if="show_task or show_project">
                                                 <t t-if="show_project"><span t-field="l.project_id.name"/></t>
@@ -72,4 +72,4 @@
             name="hr_timesheet.report_timesheet"
             file="report_timesheet"
     />
-</odoo>
\ No newline at end of file
+</odoo>
diff --git a/addons/payment_stripe/models/payment.py b/addons/payment_stripe/models/payment.py
index 6cd4899bfc10cab921134d2210bdda987391c124..ca6a8d5f59202373f37dd584bf1b24edbdec59d7 100644
--- a/addons/payment_stripe/models/payment.py
+++ b/addons/payment_stripe/models/payment.py
@@ -109,7 +109,7 @@ class PaymentTransactionStripe(models.Model):
     @api.multi
     def stripe_s2s_do_transaction(self, **kwargs):
         self.ensure_one()
-        result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref)
+        result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref, email=self.partner_email)
         return self._stripe_s2s_validate_tree(result)
 
     @api.model
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 6e12dc8b114758538177c493231e04672b63b613..25b31fd0b8f55781224d52e2ddb1c095dc4e5891 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1152,7 +1152,8 @@ exports.Orderline = Backbone.Model.extend({
                 if (unit.rounding) {
                     this.quantity    = round_pr(quant, unit.rounding);
                     var decimals = this.pos.dp['Product Unit of Measure'];
-                    this.quantityStr = formats.format_value(round_di(this.quantity, decimals), { type: 'float', digits: [69, decimals]});
+                    this.quantity = round_di(this.quantity, decimals)
+                    this.quantityStr = formats.format_value(this.quantity, { type: 'float', digits: [69, decimals]});
                 } else {
                     this.quantity    = round_pr(quant, 1);
                     this.quantityStr = this.quantity.toFixed(0);
diff --git a/addons/pos_mercury/data/pos_mercury_demo.xml b/addons/pos_mercury/data/pos_mercury_demo.xml
index 5ff1a0d70e434deb43e1a36035ec673a43397bfc..b242868f8df89ba78cdd062513e2eb05a0dbbef9 100644
--- a/addons/pos_mercury/data/pos_mercury_demo.xml
+++ b/addons/pos_mercury/data/pos_mercury_demo.xml
@@ -5,8 +5,8 @@
       <!-- This is a test account for testing with test cards and cannot be used in a live environment -->
       <record id="pos_mercury_configuration" model="pos_mercury.configuration">
         <field name="name">Mercury Demo</field>
-        <field name="merchant_id">334160</field>
-        <field name="merchant_pwd">81303DUR</field>
+        <field name="merchant_id">755847002</field>
+        <field name="merchant_pwd">xyz</field>
       </record>
     </data>
 </odoo>
diff --git a/addons/pos_mercury/models/pos_mercury.py b/addons/pos_mercury/models/pos_mercury.py
index 707f85692e0a8d798b05474bad09907d208a42fa..6af9d437af95319a12b6c058864e9efa84856e35 100644
--- a/addons/pos_mercury/models/pos_mercury.py
+++ b/addons/pos_mercury/models/pos_mercury.py
@@ -4,6 +4,7 @@
 import logging
 
 from odoo import models, fields, api, _
+from odoo.tools.float_utils import float_compare
 
 _logger = logging.getLogger(__name__)
 
@@ -71,8 +72,9 @@ class PosOrder(models.Model):
         statement_id = super(PosOrder, self).add_payment(data)
         statement_lines = self.env['account.bank.statement.line'].search([('statement_id', '=', statement_id),
                                                                          ('pos_statement_id', '=', self.id),
-                                                                         ('journal_id', '=', data['journal']),
-                                                                         ('amount', '=', data['amount'])])
+                                                                         ('journal_id', '=', data['journal'])])
+        statement_lines = statement_lines.filtered(lambda line: float_compare(line.amount, data['amount'],
+                                                                              precision_rounding=line.journal_currency_id.rounding) == 0)
 
         # we can get multiple statement_lines when there are >1 credit
         # card payments with the same amount. In that case it doesn't
diff --git a/addons/pos_mercury/models/pos_mercury_transaction.py b/addons/pos_mercury/models/pos_mercury_transaction.py
index cca78872ac5620db8fc24a05c49e2e4b6630dfd6..4d8da0b9a983ec085153d5a29f05ee8dae8e8dde 100644
--- a/addons/pos_mercury/models/pos_mercury_transaction.py
+++ b/addons/pos_mercury/models/pos_mercury_transaction.py
@@ -63,7 +63,11 @@ class MercuryTransaction(models.Model):
             'SOAPAction': 'http://www.mercurypay.com/CreditTransaction',
         }
 
-        r = urllib2.Request('https://w1.mercurypay.com/ws/ws.asmx', data=xml_transaction, headers=headers)
+        url = 'https://w1.mercurypay.com/ws/ws.asmx'
+        if self.env['ir.config_parameter'].sudo().get_param('pos_mercury.enable_test_env'):
+            url = 'https://w1.mercurycert.net/ws/ws.asmx'
+
+        r = urllib2.Request(url, data=xml_transaction, headers=headers)
         try:
             u = urllib2.urlopen(r, timeout=65)
             response = werkzeug.utils.unescape(u.read())
diff --git a/addons/sale/models/account_invoice.py b/addons/sale/models/account_invoice.py
index 1ed8cda461bc1c8d8b2f9ddd4a6c145ec52bb034..a0b1a51cde1a596a60e6095f60fb27452e95b916 100644
--- a/addons/sale/models/account_invoice.py
+++ b/addons/sale/models/account_invoice.py
@@ -39,6 +39,9 @@ class AccountInvoice(models.Model):
     def _onchange_delivery_address(self):
         addr = self.partner_id.address_get(['delivery'])
         self.partner_shipping_id = addr and addr.get('delivery')
+        if self.env.context.get('type', 'out_invoice') == 'out_invoice':
+            company = self.company_id or self.env.user.company_id
+            self.comment = company.with_context(lang=self.partner_id.lang).sale_note
 
     @api.multi
     def action_invoice_paid(self):
diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py
index ac7d9587d224c74a7526bc8560fa9f48128c7137..c04685a84aaf6b0d22eb3ae88b5b6e709baf90a4 100644
--- a/addons/sale/wizard/sale_make_invoice_advance.py
+++ b/addons/sale/wizard/sale_make_invoice_advance.py
@@ -65,7 +65,7 @@ class SaleAdvancePaymentInv(models.TransientModel):
 
         account_id = False
         if self.product_id.id:
-            account_id = self.product_id.property_account_income_id.id
+            account_id = self.product_id.property_account_income_id.id or self.product_id.categ_id.property_account_income_categ_id.id
         if not account_id:
             inc_acc = ir_property_obj.get('property_account_income_categ_id', 'product.category')
             account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False
diff --git a/addons/stock/report/report_location_barcode.xml b/addons/stock/report/report_location_barcode.xml
index d67481ddbb9178b2809366c7c3603c63bbf75380..a2c306c80b7e81430c4aa456bafc65f58dc0d1ed 100644
--- a/addons/stock/report/report_location_barcode.xml
+++ b/addons/stock/report/report_location_barcode.xml
@@ -9,8 +9,8 @@
 </template>
 
 <template id="report_location_barcode">
-    <t t-call="report.basic_layout">
-        <div t-foreach="[docs[x:x+4] for x in xrange(0, len(docs), 4)]" t-as="page_docs" class="page page_stock_location_barcodes">
+    <t t-call="report.html_container">
+        <div t-foreach="[docs[x:x+4] for x in xrange(0, len(docs), 4)]" t-as="page_docs" class="page article page_stock_location_barcodes">
             <t t-foreach="page_docs" t-as="o">
                 <t t-if="o.barcode"><t t-set="content" t-value="o.barcode"/></t>
                 <t t-if="not o.barcode"><t t-set="content" t-value="o.name"/></t>
diff --git a/addons/stock/wizard/make_procurement.py b/addons/stock/wizard/make_procurement.py
index 3ae8f6d6bf87909ab12f3bbbed113f4248dbdd0a..3bed9047bd9bc7d2fb8d9507bd35d69600ee97a6 100644
--- a/addons/stock/wizard/make_procurement.py
+++ b/addons/stock/wizard/make_procurement.py
@@ -1,9 +1,9 @@
 # -*- coding: utf-8 -*-
 # Part of Odoo. See LICENSE file for full copyright and licensing details.
 
+import datetime
 from odoo import api, fields, models
 
-
 class MakeProcurement(models.TransientModel):
     _name = 'make.procurement'
     _description = 'Make Procurements'
@@ -64,9 +64,14 @@ class MakeProcurement(models.TransientModel):
         """ Creates procurement order for selected product. """
         ProcurementOrder = self.env['procurement.order']
         for wizard in self:
+            # we set the time to noon to avoid the date to be changed because of timezone issues
+            date = fields.Datetime.from_string(wizard.date_planned)
+            date = date + datetime.timedelta(hours=12)
+            date = fields.Datetime.to_string(date)
+
             procurement = ProcurementOrder.create({
                 'name': 'INT: %s' % (self.env.user.login),
-                'date_planned': wizard.date_planned,
+                'date_planned': date,
                 'product_id': wizard.product_id.id,
                 'product_qty': wizard.qty,
                 'product_uom': wizard.uom_id.id,
diff --git a/addons/stock_calendar/models/stock.py b/addons/stock_calendar/models/stock.py
index 31cc89a2cbdcfa19648e1f872d43b3e78dae2c77..4aca294948a5af832342aac05d5671332ef78273 100644
--- a/addons/stock_calendar/models/stock.py
+++ b/addons/stock_calendar/models/stock.py
@@ -51,7 +51,7 @@ class StockWarehouseOrderpoint(models.Model):
                     date = interval[1]
                     res_intervals += [(date, group), ]
         else:
-            return [(now_date, None)]
+            return [(False, None)]
         return res_intervals
 
     def _get_previous_dates(self, start_date=False):
diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py
index a1223d896c873a80762e0004c7ee3b6980364edf..5e5c88031c771c21d0c41157a4f6d9622af122e5 100644
--- a/addons/stock_landed_costs/models/stock_landed_cost.py
+++ b/addons/stock_landed_costs/models/stock_landed_cost.py
@@ -85,11 +85,13 @@ class LandedCost(models.Model):
             raise UserError(_('Cost and adjustments lines do not match. You should maybe recompute the landed costs.'))
 
         for cost in self:
-            move = self.env['account.move'].create({
+            move = self.env['account.move']
+            move_vals = {
                 'journal_id': cost.account_journal_id.id,
                 'date': cost.date,
-                'ref': cost.name
-            })
+                'ref': cost.name,
+                'line_ids': [],
+            }
             for line in cost.valuation_adjustment_lines.filtered(lambda line: line.move_id):
                 per_unit = line.final_cost / line.quantity
                 diff = per_unit - line.former_cost_per_unit
@@ -134,8 +136,9 @@ class LandedCost(models.Model):
                 for quant in line.move_id.quant_ids:
                     if quant.location_id.usage != 'internal':
                         qty_out += quant.qty
-                line._create_accounting_entries(move, qty_out)
-            move.assert_balanced()
+                move_vals['line_ids'] += line._create_accounting_entries(move, qty_out)
+
+            move = move.create(move_vals)
             cost.write({'state': 'done', 'account_move_id': move.id})
             move.post()
         return True
@@ -336,11 +339,10 @@ class AdjustmentLines(models.Model):
         Generate the account.move.line values to track the landed cost.
         Afterwards, for the goods that are already out of stock, we should create the out moves
         """
-        AccountMoveLine = self.env['account.move.line'].with_context(check_move_validity=False, recompute=False)
+        AccountMoveLine = []
 
         base_line = {
             'name': self.name,
-            'move_id': move.id,
             'product_id': self.product_id.id,
             'quantity': self.quantity,
         }
@@ -354,8 +356,8 @@ class AdjustmentLines(models.Model):
             # negative cost, reverse the entry
             debit_line['credit'] = -diff
             credit_line['debit'] = -diff
-        AccountMoveLine.create(debit_line)
-        AccountMoveLine.create(credit_line)
+        AccountMoveLine.append([0, 0, debit_line])
+        AccountMoveLine.append([0, 0, credit_line])
 
         # Create account move lines for quants already out of stock
         if qty_out > 0:
@@ -375,8 +377,8 @@ class AdjustmentLines(models.Model):
                 # negative cost, reverse the entry
                 debit_line['credit'] = -diff
                 credit_line['debit'] = -diff
-            AccountMoveLine.create(debit_line)
-            AccountMoveLine.create(credit_line)
+            AccountMoveLine.append([0, 0, debit_line])
+            AccountMoveLine.append([0, 0, credit_line])
 
             # TDE FIXME: oh dear
             if self.env.user.company_id.anglo_saxon_accounting:
@@ -396,7 +398,7 @@ class AdjustmentLines(models.Model):
                     # negative cost, reverse the entry
                     debit_line['credit'] = -diff
                     credit_line['debit'] = -diff
-                AccountMoveLine.create(debit_line)
-                AccountMoveLine.create(credit_line)
+                AccountMoveLine.append([0, 0, debit_line])
+                AccountMoveLine.append([0, 0, credit_line])
 
-        return True
+        return AccountMoveLine
diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js
index 6a727e114b452d6a2b380d6f52b198d61e8cd674..60f1e09c3b17af1f978ffc467c9e8a47ab8488ce 100644
--- a/addons/web_calendar/static/src/js/web_calendar.js
+++ b/addons/web_calendar/static/src/js/web_calendar.js
@@ -921,9 +921,10 @@ var CalendarView = View.extend({
             }
         }
         else {
+            var res_id = parseInt(id).toString() === id ? parseInt(id) : id;
             new form_common.FormViewDialog(this, {
                 res_model: this.model,
-                res_id: parseInt(id).toString() === id ? parseInt(id) : id,
+                res_id: res_id,
                 context: this.dataset.get_context(),
                 title: title,
                 view_id: +this.open_popup_action,
@@ -935,7 +936,7 @@ var CalendarView = View.extend({
                     }},
 
                     {text: _t("Delete"), close: true, click: function() {
-                        self.remove_event(id);
+                        self.remove_event(res_id);
                     }},
 
                     {text: _t("Close"), close: true}
diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js
index 2678ba955affe3103b99c72f8079a85d300aa3f4..435c5d7fa7831f624efe76667cd4a68d368e048c 100644
--- a/addons/web_editor/static/src/js/summernote.js
+++ b/addons/web_editor/static/src/js/summernote.js
@@ -1856,12 +1856,17 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent)
     var $dom = $(ancestor);
 
     if (!dom.isList(ancestor)) {
+        // to indent a selection, we indent the child nodes of the common
+        // ancestor that contains this selection
         $dom = $(dom.node(ancestor)).children();
     }
-    if (!$dom.length) {
-        $dom = $(dom.ancestor(r.sc, dom.isList) || dom.ancestor(r.sc, dom.isCell));
+    if (!$dom.not('br').length) {
+        // if selection is inside a list, we indent its list items
+        $dom = $(dom.ancestor(r.sc, dom.isList));
         if (!$dom.length) {
-            $dom = $(r.sc).closest(options.styleTags.join(','));
+            // if the selection is contained in a single HTML node, we indent
+            // the first ancestor 'content block' (P, H1, PRE, ...) or TD
+            $dom = $(r.sc).closest(options.styleTags.join(',')+',td');
         }
     }
 
diff --git a/addons/website/geoipresolver.py b/addons/website/geoipresolver.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f9b0e2272453753afe131450670ca9d136ec9aa
--- /dev/null
+++ b/addons/website/geoipresolver.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os.path
+
+try:
+    import GeoIP    # Legacy
+except ImportError:
+    GeoIP = None
+
+try:
+    import geoip2
+    import geoip2.database
+except ImportError:
+    geoip2 = None
+
+class GeoIPResolver(object):
+    def __init__(self, fname):
+        self.fname = fname
+        try:
+            self._db = geoip2.database.Reader(fname)
+            self.version = 2
+        except Exception:
+            try:
+                self._db = GeoIP.open(fname, GeoIP.GEOIP_STANDARD)
+                self.version = 1
+                assert self._db.database_info is not None
+            except Exception:
+                raise ValueError('Invalid GeoIP database: %r' % fname)
+
+    def __del__(self):
+        if self.version == 2:
+            self._db.close()
+
+    @classmethod
+    def open(cls, fname):
+        if not GeoIP and not geoip2:
+            return None
+        if not os.path.exists(fname):
+            return None
+        return GeoIPResolver(fname)
+
+    def resolve(self, ip):
+        if self.version == 1:
+            return self._db.record_by_addr(ip) or {}
+        elif self.version == 2:
+            try:
+                r = self._db.city(ip)
+            except (ValueError, geoip2.errors.AddressNotFoundError):
+                return {}
+            return {
+                'city': r.city.name,
+                'country_code': r.country.iso_code,
+                'country_name': r.country.name,
+                'region': r.subdivisions[0].iso_code if r.subdivisions else None,
+                'time_zone': r.location.time_zone,
+            }
+
+    # compat
+    def record_by_addr(self, addr):
+        return self.resolve(addr)
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index 92ab292e19cbd977210d1bf6e8969e9379144dc7..e492432b894359a1cc4c70e8c6c84827d6e48a97 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -14,7 +14,7 @@ import odoo
 from odoo import api, models
 from odoo import SUPERUSER_ID
 from odoo.http import request
-from odoo.tools import config
+from odoo.tools import config, ustr
 from odoo.exceptions import QWebException
 from odoo.tools.safe_eval import safe_eval
 
@@ -22,6 +22,8 @@ from odoo.addons.base import ir
 from odoo.addons.website.models.website import slug, url_for, _UNSLUG_RE
 
 
+from ..geoipresolver import GeoIPResolver
+
 logger = logging.getLogger(__name__)
 
 # global resolver (GeoIP API is thread-safe, for multithreaded workers)
@@ -100,25 +102,18 @@ class Http(models.AbstractModel):
         if odoo._geoip_resolver is not None:
             cls._geoip_resolver = odoo._geoip_resolver
             return
+        geofile = config.get('geoip_database')
         try:
-            import GeoIP
-            # updated database can be downloaded on MaxMind website
-            # http://dev.maxmind.com/geoip/legacy/install/city/
-            geofile = config.get('geoip_database')
-            if os.path.exists(geofile):
-                odoo._geoip_resolver = GeoIP.open(geofile, GeoIP.GEOIP_STANDARD)
-            else:
-                odoo._geoip_resolver = False
-                logger.warning('GeoIP database file %r does not exists, apt-get install geoip-database-contrib or download it from http://dev.maxmind.com/geoip/legacy/install/city/', geofile)
-        except ImportError:
-            odoo._geoip_resolver = False
+            odoo._geoip_resolver = GeoIPResolver.open(geofile) or False
+        except Exception as e:
+            logger.warning('Cannot load GeoIP: %s', ustr(e))
 
     @classmethod
     def _geoip_resolve(cls):
         if 'geoip' not in request.session:
             record = {}
             if odoo._geoip_resolver and request.httprequest.remote_addr:
-                record = odoo._geoip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
+                record = odoo._geoip_resolver.resolve(request.httprequest.remote_addr) or {}
             request.session['geoip'] = record
 
     @classmethod
diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
index 327afe03a567834d9ec6bd0a167d58323fade299..d765351ed026d4b345a2ba5b184851b92dc11b66 100644
--- a/addons/website_event_sale/static/src/js/website.tour.event_sale.js
+++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
@@ -91,6 +91,7 @@ tour.register('event_buy_tickets', {
         {
             content: "Last step",
             trigger: '.oe_website_sale:contains("Thank you for your order")',
+            timeout: 30000,
         }
     ]
 );
diff --git a/addons/website_form/static/src/js/website_form.js b/addons/website_form/static/src/js/website_form.js
index 716c49ed6857e65ee098b742854d48b6f5c6c082..f7c0ae1e2c2efd24f67ea5420d6e3d678556bbb4 100644
--- a/addons/website_form/static/src/js/website_form.js
+++ b/addons/website_form/static/src/js/website_form.js
@@ -21,7 +21,11 @@ odoo.define('website_form.animation', function (require) {
             return $.when(this._super.apply(this, arguments), def);
         },
 
-        start: function() {
+        start: function(editable_mode) {
+            if (editable_mode) {
+                this.stop();
+                return;
+            }
             var self = this;
             this.templates_loaded = ajax.loadXML('/website_form/static/src/xml/website_form.xml', qweb);
             this.$target.find('.o_website_form_send').on('click',function(e) {self.send(e);});
diff --git a/addons/website_sale/static/src/js/website_sale_tour_buy.js b/addons/website_sale/static/src/js/website_sale_tour_buy.js
index 18db42a12708c6707d0f08fd77352c681b220d1d..268a4448570893c883c59c7c97d3f0921ed53a5e 100644
--- a/addons/website_sale/static/src/js/website_sale_tour_buy.js
+++ b/addons/website_sale/static/src/js/website_sale_tour_buy.js
@@ -76,6 +76,7 @@ tour.register('shop_buy_product', {
         {
             content: "finish",
             trigger: '.oe_website_sale:contains("Thank you for your order")',
+            timeout: 30000,
         }
     ]
 );
diff --git a/odoo/addons/base/module/module.py b/odoo/addons/base/module/module.py
index 3e2eb4749cb2ae18500f08ced3efb00c5138cd03..e499eb6550b4529ddebbd582634849ba714a44b7 100644
--- a/odoo/addons/base/module/module.py
+++ b/odoo/addons/base/module/module.py
@@ -599,7 +599,7 @@ class Module(models.Model):
         res = [0, 0]    # [update, add]
 
         default_version = modules.adapt_version('1.0')
-        known_mods = self.search([])
+        known_mods = self.with_context(lang=None).search([])
         known_mods_names = {mod.name: mod for mod in known_mods}
 
         # iterate through detected modules and update/create them in db
diff --git a/odoo/addons/base/res/res_country_data.xml b/odoo/addons/base/res/res_country_data.xml
index 2d3eb442f450e8e222c65d4a3db36151e28e97ec..be6af58350f03199b3b4879a61e8a43e9e6809c5 100644
--- a/odoo/addons/base/res/res_country_data.xml
+++ b/odoo/addons/base/res/res_country_data.xml
@@ -1385,7 +1385,7 @@
             <field name="name">Sudan</field>
             <field name="code">sd</field>
             <field file="base/static/img/country_flags/sd.png" name="image" type="base64" />
-            <field name="currency_id" ref="SDD" />
+            <field name="currency_id" ref="SDG" />
             <field eval="249" name="phone_code" />
         </record>
         <record id="se" model="res.country">
diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml
index f986c0a08b86a703379645583d1d53dd542a3f08..dc864e1dc9ab17eaea7c0d59970d8520baa09abd 100644
--- a/odoo/addons/base/res/res_currency_data.xml
+++ b/odoo/addons/base/res/res_currency_data.xml
@@ -1016,6 +1016,7 @@
             <field name="active" eval="False"/>
         </record>
 
+        <!-- no longer in use since 2007 -->
         <record id="SDD" model="res.currency">
             <field name="name">SDD</field>
             <field name="symbol">£Sd</field>
@@ -1023,6 +1024,13 @@
             <field name="active" eval="False"/>
         </record>
 
+        <record id="SDG" model="res.currency">
+            <field name="name">SDG</field>
+            <field name="symbol">ج.س.</field>
+            <field name="rounding">0.01</field>
+            <field name="active" eval="False"/>
+        </record>
+
         <record id="LKR" model="res.currency">
             <field name="name">LKR</field>
             <field name="symbol">Rs</field>
diff --git a/odoo/addons/base/res/res_currency_demo.xml b/odoo/addons/base/res/res_currency_demo.xml
index ba316d0a7dbfd224e751249a425d14fbeb66d828..e74fb16fda8453a3375a06bbc2863f56b45b106c 100644
--- a/odoo/addons/base/res/res_currency_demo.xml
+++ b/odoo/addons/base/res/res_currency_demo.xml
@@ -877,6 +877,12 @@
             <field name="rate">544.44</field>
         </record>
 
+        <record forcecreate="0" id="rateSDG" model="res.currency.rate">
+            <field name="currency_id" ref="SDG" />
+            <field name="name">2010-01-01</field>
+            <field name="rate">3.1999</field>
+        </record>
+
         <record forcecreate="0" id="rateLKR" model="res.currency.rate">
             <field name="currency_id" ref="LKR" />
             <field name="name">2010-01-01</field>
diff --git a/odoo/tools/config.py b/odoo/tools/config.py
index 5056ae778807577c8500ea5f5154c3b6b8ecc3ea..2bf198cc58531426c99819eebbd044c31b4967e9 100644
--- a/odoo/tools/config.py
+++ b/odoo/tools/config.py
@@ -255,7 +255,7 @@ class configmanager(object):
                          type="int")
         group.add_option("--unaccent", dest="unaccent", my_default=False, action="store_true",
                          help="Use the unaccent function provided by the database when available.")
-        group.add_option("--geoip-db", dest="geoip_database", my_default='/usr/share/GeoIP/GeoLiteCity.dat',
+        group.add_option("--geoip-db", dest="geoip_database", my_default='/usr/share/GeoIP/GeoLite2-City.mmdb',
                          help="Absolute path to the GeoIP database file.")
         parser.add_option_group(group)