diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 40dccf363d58ad2a05c2f95e509a8906379cfc94..bc8fb1cddefc1cc17f00ebc569a7582237abc093 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -508,7 +508,7 @@ class AccountInvoice(models.Model):
     @api.multi
     def get_formview_id(self):
         """ Update form view id of action to open the invoice """
-        if self.type == 'in_invoice':
+        if self.type in ('in_invoice', 'in_refund'):
             return self.env.ref('account.invoice_supplier_form').id
         else:
             return self.env.ref('account.invoice_form').id
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 2f5e3f2eb9374298533a0eb7429ae7071e5ca85a..cca7c203e8c2a7ad8b73e455b937c88c3967f7da 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -829,7 +829,14 @@ class AccountMoveLine(models.Model):
 
         #if writeoff_acc_id specified, then create write-off move with value the remaining amount from move in self
         if writeoff_acc_id and writeoff_journal_id and remaining_moves:
-            writeoff_to_reconcile = remaining_moves._create_writeoff({'account_id': writeoff_acc_id.id, 'journal_id': writeoff_journal_id.id})
+            all_aml_share_same_currency = all([x.currency_id == self[0].currency_id for x in self])
+            writeoff_vals = {
+                'account_id': writeoff_acc_id.id,
+                'journal_id': writeoff_journal_id.id
+            }
+            if not all_aml_share_same_currency:
+                writeoff_vals['amount_currency'] = False
+            writeoff_to_reconcile = remaining_moves._create_writeoff(writeoff_vals)
             #add writeoff line to reconcile algo and finish the reconciliation
             remaining_moves = (remaining_moves + writeoff_to_reconcile).auto_reconcile_lines()
 
diff --git a/addons/calendar/calendar_data.xml b/addons/calendar/calendar_data.xml
index 772f6772971ffb2eb6f3c975f48187479e529677..d02c1028745d83c12296d8fd0eebe9129fd2d831 100644
--- a/addons/calendar/calendar_data.xml
+++ b/addons/calendar/calendar_data.xml
@@ -118,12 +118,12 @@
                 <table style="margin-top: 20px;"><tr>
                     <td>
                         <div style="border-top-left-radius:3px;border-top-right-radius:3px;font-size:12px;border-collapse:separate;text-align:center;font-weight:bold;color:#ffffff;width:130px;min-height: 18px;background:#a24689;padding-top: 4px;">
-                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
                         <div style="font-size:48px;min-height:auto;font-weight:bold;text-align:center;color: #5F5F5F;background-color: #F8F8F8;width: 130px;border:1px solid #a24689;">
-                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
-                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}</div>
+                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}</div>
                         <div style="border-collapse:separate;color: #5F5F5F;text-align:center;width: 130px;font-size:12px;border-bottom-right-radius:3px;font-weight:bold;border:1px solid #a24689;border-bottom-left-radius:3px;">${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}</div>
                     </td>
                     <td width="20px;"/>
@@ -210,12 +210,12 @@
                 <table style="margin-top: 20px;"><tr>
                     <td>
                         <div style="border-top-left-radius:3px;border-top-right-radius:3px;font-size:12px;border-collapse:separate;text-align:center;font-weight:bold;color:#ffffff;width:130px;min-height: 18px;background:#a24689;padding-top: 4px;">
-                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
                         <div style="font-size:48px;min-height:auto;font-weight:bold;text-align:center;color: #5F5F5F;background-color: #F8F8F8;width: 130px;border:1px solid #a24689;">
-                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
-                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}</div>
+                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}</div>
                         <div style="border-collapse:separate;color: #5F5F5F;text-align:center;width: 130px;font-size:12px;border-bottom-right-radius:3px;font-weight:bold;border:1px solid #a24689;border-bottom-left-radius:3px;">${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}</div>
                     </td>
                     <td width="20px;"/>
@@ -302,12 +302,12 @@
                 <table style="margin-top: 20px;"><tr>
                     <td>
                         <div style="border-top-left-radius:3px;border-top-right-radius:3px;font-size:12px;border-collapse:separate;text-align:center;font-weight:bold;color:#ffffff;width:130px;min-height: 18px;background:#a24689;padding-top: 4px;">
-                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start, 'dayname', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
                         <div style="font-size:48px;min-height:auto;font-weight:bold;text-align:center;color: #5F5F5F;background-color: #F8F8F8;width: 130px;border:1px solid #a24689;">
-                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz)}
+                            ${object.event_id.get_interval(object.event_id.start,'day', tz=object.partner_id.tz if not object.event_id.allday else None)}
                         </div>
-                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz)}</div>
+                        <div style='font-size:12px;text-align:center;font-weight:bold;color:#ffffff;background-color:#a24689'>${object.event_id.get_interval(object.event_id.start, 'month', tz=object.partner_id.tz if not object.event_id.allday else None)}</div>
                         <div style="border-collapse:separate;color: #5F5F5F;text-align:center;width: 130px;font-size:12px;border-bottom-right-radius:3px;font-weight:bold;border:1px solid #a24689;border-bottom-left-radius:3px;">${not object.event_id.allday and object.event_id.get_interval(object.event_id.start, 'time', tz=object.partner_id.tz) or ''}</div>
                     </td>
                     <td width="20px;"/>
diff --git a/addons/calendar/calendar_view.xml b/addons/calendar/calendar_view.xml
index 50015b7a0ee4f1513f69fef3ed9965948c5532ee..81ae9a3cc66efde1db9426e0987effb48c287886 100644
--- a/addons/calendar/calendar_view.xml
+++ b/addons/calendar/calendar_view.xml
@@ -101,18 +101,19 @@
                                 <group>
                                     <field name="start" attrs="{'invisible': True}"/>
                                     <field name="stop" attrs="{'invisible': True}"/>
+                                    <field name="id" attrs="{'invisible': True}"/>
 
-                                    <field name="start_date" string="Starting at" on_change="onchange_dates('start', start_date, stop_date, allday, True)" attrs="{'invisible': [('allday','=',False)]}"/>
-                                    <field name="stop_date" string="Ending at" on_change="onchange_dates('stop', start_date, stop_date, allday, True)" attrs="{'invisible': [('allday','=',False)]}"/>
+                                    <field name="start_date" string="Starting at" on_change="onchange_dates('start', start_date, stop_date, allday, True)" attrs="{'invisible': [('allday','=',False)], 'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
+                                    <field name="stop_date" string="Ending at" on_change="onchange_dates('stop', start_date, stop_date, allday, True)" attrs="{'invisible': [('allday','=',False)], 'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
 
-                                    <field name="start_datetime" string="Starting at" on_change="onchange_duration(start_datetime, duration)" attrs="{'invisible': [('allday','=',True)]}"/>
+                                    <field name="start_datetime" string="Starting at" on_change="onchange_duration(start_datetime, duration)" attrs="{'invisible': [('allday','=',True)], 'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
                                     <field name="stop_datetime" invisible="1"/>
                                     <label for="duration" attrs="{'invisible': [('allday','=',True)]}"/>
                                     <div attrs="{'invisible': [('allday','=',True)]}">
-                                        <field name="duration" widget="float_time" string="Duration" on_change="onchange_duration(start_datetime, duration)" class="oe_inline"/>
+                                        <field name="duration" widget="float_time" string="Duration" on_change="onchange_duration(start_datetime, duration)" class="oe_inline" attrs="{'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
                                         <span> hours</span>
                                     </div>
-                                    <field name="allday"  on_change="onchange_allday(start, stop, start_date, stop_date, start_datetime, stop_datetime, allday)"/>
+                                    <field name="allday"  on_change="onchange_allday(start, stop, start_date, stop_date, start_datetime, stop_datetime, allday)" attrs="{'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
                                 </group>
                                 <group>
                                     <field name="categ_ids" widget="many2many_tags" />
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index 8baf69a5a7a77d7b455bed26fb9944b382783958..95ad18f044f1518606ffbf12a95eefbb581b3dbf 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -306,7 +306,7 @@ class MergePartnerAutomatic(osv.TransientModel):
         for partner_id in partner_ids:
             child_ids = child_ids.union(set(proxy.search(cr, uid, [('id', 'child_of', [partner_id])])) - set([partner_id]))
         if set(partner_ids).intersection(child_ids):
-            raise osv.except_osv(_('Error'), _("You cannot merge a contact with one of his parent."))
+            raise UserError(_("You cannot merge a contact with one of his parent."))
 
         if openerp.SUPERUSER_ID != uid and len(set(partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context))) > 1:
             raise UserError(_("All contacts must have the same email. Only the Administrator can merge contacts with different emails."))
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 41fd1a7452cbf7962fb436371afcf6b4f46f10a9..bcb994b57fe391b92cd87c2ee6e8f33d804cd218 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -460,11 +460,11 @@ class crm_lead(FormatAddress, osv.osv):
                 value = dict(key).get(lead[field_name], lead[field_name])
             elif field.type == 'many2one':
                 if lead[field_name]:
-                    value = lead[field_name].name_get()[0][1]
+                    value = lead[field_name].sudo().name_get()[0][1]
             elif field.type == 'many2many':
                 if lead[field_name]:
                     for val in lead[field_name]:
-                        field_value = val.name_get()[0][1]
+                        field_value = val.sudo().name_get()[0][1]
                         value += field_value + ","
             else:
                 value = lead[field_name]
diff --git a/addons/crm_partner_assign/security/ir.model.access.csv b/addons/crm_partner_assign/security/ir.model.access.csv
index e0b29587ff47b01f1c9cacbc0d88e1fc216af765..3f39d776ddc216ac171218252a0249b04d7f135d 100644
--- a/addons/crm_partner_assign/security/ir.model.access.csv
+++ b/addons/crm_partner_assign/security/ir.model.access.csv
@@ -3,6 +3,8 @@ access_ crm_lead_report_assign,crm.lead.report.assign,model_crm_lead_report_assi
 access_ crm_lead_report_assign_all,crm.lead.report.assign.all,model_crm_lead_report_assign,base.group_user,1,0,0,0
 access_crm_partner_report,crm.partner.report.assign.all,model_crm_partner_report_assign,base.group_sale_salesman,1,0,0,0
 access_res_partner_grade,res.partner.grade,model_res_partner_grade,base.group_sale_salesman,1,1,1,0
+access_res_partner_grade_employee,res.partner.grade,model_res_partner_grade,base.group_user,1,0,0,0
+access_res_partner_grade_portal,res.partner.grade,model_res_partner_grade,base.group_portal,1,0,0,0
 access_res_partner_grade_public,res.partner.grade,model_res_partner_grade,base.group_public,1,0,0,0
 access_res_partner_grade_manager,res.partner.grade.manager,model_res_partner_grade,base.group_sale_manager,1,1,1,1
 access_res_partner_activation_user,res.partner.activation.user,model_res_partner_activation,base.group_user,1,0,0,0
diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py
index 1607a6005d1da61500b0bea3454201c6845c2e19..a219d7ddc014adccfb1e3a05e0631d18d7db7d97 100644
--- a/addons/gamification/models/goal.py
+++ b/addons/gamification/models/goal.py
@@ -129,18 +129,36 @@ class gamification_goal_definition(osv.Model):
                 raise UserError(_("The domain for the definition %s seems incorrect, please check it.\n\n%s") % (definition.name, msg))
         return True
 
+    def _check_model_validity(self, cr, uid, ids, context=None):
+        """ make sure the selected field and model are usable"""
+        for definition in self.browse(cr, uid, ids, context=context):
+            try:
+                if not definition.model_id or not definition.field_id:
+                    continue
+
+                model = self.pool[definition.model_id.model]
+                field = model._fields[definition.field_id.name]
+                if not field.store:
+                    raise UserError(
+                        _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not stored") % (definition.name, definition.field_id.name))
+            except KeyError, e:
+                raise UserError(
+                    _("The model configuration for the definition %s seems incorrect, please check it.\n\n%s not found") % (definition.name, e.message))
+
     def create(self, cr, uid, vals, context=None):
         res_id = super(gamification_goal_definition, self).create(cr, uid, vals, context=context)
         if vals.get('computation_mode') in ('count', 'sum'):
             self._check_domain_validity(cr, uid, [res_id], context=context)
-
+        if vals.get('field_id'):
+            self._check_model_validity(cr, uid, [res_id], context=context)
         return res_id
 
     def write(self, cr, uid, ids, vals, context=None):
         res = super(gamification_goal_definition, self).write(cr, uid, ids, vals, context=context)
         if vals.get('computation_mode', 'count') in ('count', 'sum') and (vals.get('domain') or vals.get('model_id')):
             self._check_domain_validity(cr, uid, ids, context=context)
-
+        if vals.get('field_id') or vals.get('model_id') or vals.get('batch_mode'):
+            self._check_model_validity(cr, uid, ids, context=context)
         return res
 
     def on_change_model_id(self, cr, uid, ids, model_id, context=None):
@@ -148,7 +166,8 @@ class gamification_goal_definition(osv.Model):
         if not model_id:
             return {'domain': {'field_id': expression.FALSE_DOMAIN, 'field_date_id': expression.FALSE_DOMAIN}}
         model = self.pool['ir.model'].browse(cr, uid, model_id, context=context)
-        model_fields_domain = ['|', ('model_id', '=', model_id), ('model_id', 'in', model.inherited_model_ids.ids)]
+        model_fields_domain = [('store', '=', True),
+                                '|', ('model_id', '=', model_id), ('model_id', 'in', model.inherited_model_ids.ids)]
         model_date_fields_domain = expression.AND([[('ttype', 'in', ('date', 'datetime'))], model_fields_domain])
         return {'domain': {'field_id': model_fields_domain, 'field_date_id': model_date_fields_domain}}
 
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index dba5acddcd34f86c96c8f317b977f0ca1f177065..3c77c1dfcf9c7a1a3763ef9cba09304836217f4f 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -567,14 +567,14 @@ class hr_employee(osv.Model):
             # Find for holidays status
             status_ids = type_obj.search(cr, uid, [('limit', '=', False)], context=context)
             if len(status_ids) != 1 :
-                raise osv.except_osv(_('Warning!'),_("The feature behind the field 'Remaining Legal Leaves' can only be used when there is only one leave type with the option 'Allow to Override Limit' unchecked. (%s Found). Otherwise, the update is ambiguous as we cannot decide on which leave type the update has to be done. \nYou may prefer to use the classic menus 'Leave Requests' and 'Allocation Requests' located in 'Human Resources \ Leaves' to manage the leave days of the employees if the configuration does not allow to use this field.") % (len(status_ids)))
+                raise UserError(_("The feature behind the field 'Remaining Legal Leaves' can only be used when there is only one leave type with the option 'Allow to Override Limit' unchecked. (%s Found). Otherwise, the update is ambiguous as we cannot decide on which leave type the update has to be done. \nYou may prefer to use the classic menus 'Leave Requests' and 'Allocation Requests' located in 'Human Resources \ Leaves' to manage the leave days of the employees if the configuration does not allow to use this field.") % (len(status_ids)))
             status_id = status_ids and status_ids[0] or False
             if not status_id:
                 return False
             if diff > 0:
                 leave_id = holiday_obj.create(cr, uid, {'name': _('Allocation for %s') % employee.name, 'employee_id': employee.id, 'holiday_status_id': status_id, 'type': 'add', 'holiday_type': 'employee', 'number_of_days_temp': diff}, context=context)
             elif diff < 0:
-                raise osv.except_osv(_('Warning!'), _('You cannot reduce validated allocation requests'))
+                raise UserError(_('You cannot reduce validated allocation requests'))
             else:
                 return False
             for sig in ('confirm', 'validate', 'second_validate'):
diff --git a/addons/hr_payroll/report/report_payslip_details.py b/addons/hr_payroll/report/report_payslip_details.py
index f5858f8e7ef11ec04b0d4b777a8f407042ef1ac7..5cc1af7ba65cde1013a205986610c13e091ee40e 100644
--- a/addons/hr_payroll/report/report_payslip_details.py
+++ b/addons/hr_payroll/report/report_payslip_details.py
@@ -18,13 +18,16 @@ class payslip_details_report(report_sxw.rml_parse):
         payslip_line = self.pool.get('hr.payslip.line')
         rule_cate_obj = self.pool.get('hr.salary.rule.category')
 
-        def get_recursive_parent(rule_categories):
-            if not rule_categories:
-                return []
-            if rule_categories[0].parent_id:
-                rule_categories = rule_categories[0].parent_id | rule_categories
-                get_recursive_parent(rule_categories)
-            return rule_categories
+        def get_recursive_parent(current_rule_category, rule_categories = None):
+            if rule_categories:
+                rule_categories = current_rule_category | rule_categories
+            else:
+                rule_categories = current_rule_category
+
+            if current_rule_category.parent_id:
+                return get_recursive_parent(current_rule_category.parent_id, rule_categories)
+            else:
+                return rule_categories
 
         res = []
         result = {}
diff --git a/addons/im_livechat/i18n/im_livechat.pot b/addons/im_livechat/i18n/im_livechat.pot
index 724c5cb037d1ab8516b3cfcb0810e1fae366dd50..27b293522f4b35620ff0c88cf03cf8d7eb1a58ef 100644
--- a/addons/im_livechat/i18n/im_livechat.pot
+++ b/addons/im_livechat/i18n/im_livechat.pot
@@ -4,10 +4,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Odoo Server 9.0\n"
+"Project-Id-Version: Odoo Server 9.0c\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-09 09:20+0000\n"
-"PO-Revision-Date: 2015-10-09 09:20+0000\n"
+"POT-Creation-Date: 2016-05-26 11:19+0000\n"
+"PO-Revision-Date: 2016-05-26 11:19+0000\n"
 "Last-Translator: <>\n"
 "Language-Team: \n"
 "MIME-Version: 1.0\n"
@@ -15,19 +15,6 @@ msgstr ""
 "Content-Transfer-Encoding: \n"
 "Plural-Forms: \n"
 
-#. module: im_livechat
-#. openerp-web
-#: code:addons/im_livechat/static/src/js/im_livechat.js:222
-#, python-format
-msgid " for the following reason: %s"
-msgstr ""
-
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.loader
-msgid "\", {modules:modules, use_cors: false});\n"
-"                    });"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.model.fields,field_description:im_livechat.field_im_livechat_report_operator_nbr_channel
 msgid "# of channel"
@@ -44,20 +31,6 @@ msgstr ""
 msgid "% Happy"
 msgstr ""
 
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.support_page
-msgid "&lt;!DOCTYPE html&gt;"
-msgstr ""
-
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.loader
-msgid ");\n"
-"                        button.appendTo($('body'));\n"
-"                        window.livechat_button = button;\n"
-"                    });\n"
-"                });"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.model.fields,help:im_livechat.field_im_livechat_channel_rule_action
 msgid "* Select 'Display the button' to simply display the chat button on the pages.\n"
@@ -87,11 +60,17 @@ msgstr ""
 
 #. module: im_livechat
 #. openerp-web
-#: code:addons/im_livechat/static/src/js/im_livechat.js:26
+#: code:addons/im_livechat/static/src/js/im_livechat.js:27
 #, python-format
 msgid "Ask something ..."
 msgstr ""
 
+#. module: im_livechat
+#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_form
+#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_tree
+msgid "Attendees"
+msgstr ""
+
 #. module: im_livechat
 #: selection:im_livechat.channel.rule,action:0
 msgid "Auto popup"
@@ -176,6 +155,7 @@ msgstr ""
 
 #. module: im_livechat
 #: model:ir.model.fields,field_description:im_livechat.field_im_livechat_report_channel_technical_name
+#: model:ir.ui.view,arch_db:im_livechat.im_livechat_report_channel_view_search
 msgid "Code"
 msgstr ""
 
@@ -187,7 +167,7 @@ msgstr ""
 
 #. module: im_livechat
 #: model:ir.ui.view,arch_db:im_livechat.im_livechat_channel_view_form
-msgid "Copy and paste this code into your website, within the &amp;lt;head&amp;gt; tag:"
+msgid "Copy and paste this code into your website, within the &lt;head&gt; tag:"
 msgstr ""
 
 #. module: im_livechat
@@ -290,26 +270,16 @@ msgstr ""
 
 #. module: im_livechat
 #. openerp-web
-#: code:addons/im_livechat/static/src/xml/im_livechat.xml:16
+#: code:addons/im_livechat/static/src/xml/im_livechat.xml:19
 #, python-format
 msgid "Explain your note"
 msgstr ""
 
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_form
-msgid "Feedback"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.ui.view,arch_db:im_livechat.im_livechat_channel_view_form
 msgid "For website built with Odoo CMS, please install the website_livechat module. Then go to Settings &gt; Website Settings and select the Website Live Chat Channel you want to add on your website."
 msgstr ""
 
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_form
-msgid "General"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.model.fields,help:im_livechat.field_im_livechat_channel_rule_sequence
 msgid "Given the order to find a matching rule. If 2 rules are matching for the given url/country, the one with the lowest sequence will be chosen."
@@ -361,9 +331,9 @@ msgstr ""
 
 #. module: im_livechat
 #. openerp-web
-#: code:addons/im_livechat/static/src/js/im_livechat.js:220
+#: code:addons/im_livechat/static/src/xml/im_livechat.xml:15
 #, python-format
-msgid "I rated you with :rating_%d"
+msgid "I don't want to rate this conversation"
 msgstr ""
 
 #. module: im_livechat
@@ -449,11 +419,6 @@ msgstr ""
 msgid "Livechat Support Channel Statistics allows you to easily check and analyse your company livechat session performance. Extract informations about the missed sessions, the audiance, the duration of a session, etc."
 msgstr ""
 
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.support_page
-msgid "Livechat Support Page"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.model,name:im_livechat.model_im_livechat_report_channel
 #: model:ir.model,name:im_livechat.model_im_livechat_report_operator
@@ -579,6 +544,11 @@ msgstr ""
 msgid "Options"
 msgstr ""
 
+#. module: im_livechat
+#: model:ir.model.fields,help:im_livechat.field_im_livechat_channel_rating_percentage_satisfaction
+msgid "Percentage of happy ratings over the past 7 days"
+msgstr ""
+
 #. module: im_livechat
 #: model:ir.ui.view,arch_db:im_livechat.im_livechat_channel_view_kanban
 msgid "Quit"
@@ -590,6 +560,13 @@ msgstr ""
 msgid "Rating"
 msgstr ""
 
+#. module: im_livechat
+#. openerp-web
+#: code:addons/im_livechat/static/src/js/im_livechat.js:308
+#, python-format
+msgid "Rating: :rating_%d"
+msgstr ""
+
 #. module: im_livechat
 #: model:ir.model.fields,help:im_livechat.field_im_livechat_channel_rule_regex_url
 msgid "Regular expression identifying the web page on which the rules will be applied."
@@ -623,8 +600,9 @@ msgid "Search report"
 msgstr ""
 
 #. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.im_livechat_report_channel_view_search
-msgid "Session"
+#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_form
+#: model:ir.ui.view,arch_db:im_livechat.mail_channel_view_tree
+msgid "Session Date"
 msgstr ""
 
 #. module: im_livechat
@@ -777,11 +755,6 @@ msgid "You can create channels for each website on which you want\n"
 "                visitors to talk in real time with your operators."
 msgstr ""
 
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.loader
-msgid "document.addEventListener(\"DOMContentLoaded\", function(event) {"
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.ui.view,arch_db:im_livechat.im_livechat_channel_view_form
 msgid "e.g. Hello, how may I help you?"
@@ -792,30 +765,6 @@ msgstr ""
 msgid "e.g. YourWebsite.com"
 msgstr ""
 
-#. module: im_livechat
-#. openerp-web
-#: code:addons/im_livechat/static/src/xml/im_livechat_backend.xml:6
-#, python-format
-msgid "livechat"
-msgstr ""
-
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.loader
-msgid "odoo.define('im_livechat.livesupport', function (require) {\n"
-"                        var im_livechat = require('im_livechat.im_livechat');\n"
-"                        var button = new im_livechat.LivechatButton(\n"
-"                            $('body'),\n"
-"                            \""
-msgstr ""
-
-#. module: im_livechat
-#: model:ir.ui.view,arch_db:im_livechat.loader
-msgid "odoo.define('web.session', function (require) {\n"
-"                        var Session = require('web.Session');\n"
-"                        var modules = odoo._modules;\n"
-"                        return new Session(undefined, \""
-msgstr ""
-
 #. module: im_livechat
 #: model:ir.ui.view,arch_db:im_livechat.im_livechat_channel_view_form
 msgid "or copy this url and send it by email to your customers or suppliers:"
@@ -826,11 +775,3 @@ msgstr ""
 msgid "seconds"
 msgstr ""
 
-#. module: im_livechat
-#. openerp-web
-#: code:addons/im_livechat/static/src/xml/im_livechat_backend.xml:9
-#: code:addons/im_livechat/static/src/xml/im_livechat_backend.xml:12
-#, python-format
-msgid "true"
-msgstr ""
-
diff --git a/addons/im_livechat/views/im_livechat_channel_templates.xml b/addons/im_livechat/views/im_livechat_channel_templates.xml
index 52257ef1658908aa6b7238163266f9a9cbbc793c..a01ac4ccf7cfdb7bb04441496edfa3ff5cdd361b 100644
--- a/addons/im_livechat/views/im_livechat_channel_templates.xml
+++ b/addons/im_livechat/views/im_livechat_channel_templates.xml
@@ -137,11 +137,11 @@
 
         <!-- the js code to initialize the LiveSupport object -->
         <template id="loader" name="Livechat : Javascript appending the livechat button">
+            <t t-translation="off">
 
             <t t-if="not info">
                 <t t-set="info" t-value="request.env['im_livechat.channel'].get_livechat_info(channel)"/>
             </t>
-
                 document.addEventListener("DOMContentLoaded", function(event) {
                     <t t-if="web_session_required">
                     odoo.define('web.session', function (require) {
@@ -164,6 +164,7 @@
             </t>
                     });
                 });
+            </t>
         </template>
 
 
diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js
index b119238ea0d58f692eb98ca6c4cff40153ad1224..c746a5ea67ba77583b23534f7c2197f208cfec73 100644
--- a/addons/point_of_sale/static/src/js/screens.js
+++ b/addons/point_of_sale/static/src/js/screens.js
@@ -131,6 +131,8 @@ var ScreenWidget = PosBaseWidget.extend({
         this.pos.barcode_reader.set_action_callback({
             'cashier': _.bind(self.barcode_cashier_action, self),
             'product': _.bind(self.barcode_product_action, self),
+            'weight': _.bind(self.barcode_product_action, self),
+            'price': _.bind(self.barcode_product_action, self),
             'client' : _.bind(self.barcode_client_action, self),
             'discount': _.bind(self.barcode_discount_action, self),
             'error'   : _.bind(self.barcode_error_action, self),
diff --git a/addons/product_visible_discount/product_visible_discount.py b/addons/product_visible_discount/product_visible_discount.py
index 7f9c28199a0781469f5753240f17eb4b9e1c3c15..286b30743a7fd36d657ca89f77ec93e6f533b5b5 100644
--- a/addons/product_visible_discount/product_visible_discount.py
+++ b/addons/product_visible_discount/product_visible_discount.py
@@ -33,14 +33,15 @@ class sale_order_line(osv.osv):
             currency_id = item.pricelist_id.currency_id
 
         product = product_obj.browse(cr, uid, product_id, context=context)
+        product_currency = (product.company_id and product.company_id.currency_id) or self.pool['res.users'].browse(cr, uid, uid).company_id.currency_id
         if not currency_id:
-            currency_id = product.company_id.currency_id
+            currency_id = product_currency
             cur_factor = 1.0
         else:
-            if currency_id.id == product.company_id.currency_id.id:
+            if currency_id.id == product_currency.id:
                 cur_factor = 1.0
             else:
-                cur_factor = self.pool['res.currency']._get_conversion_rate(cr, uid, product.company_id.currency_id, currency_id, context=context)
+                cur_factor = self.pool['res.currency']._get_conversion_rate(cr, uid, product_currency, currency_id, context=context)
 
         product_uom = context and context.get('uom') or product.uom_id.id
         if uom and uom != product_uom:
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index e7f235fcc438eee14a9a6e8d8d33de208437b75a..448f29b10a54a6184d215bad9d52a55c73f91a59 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -50,7 +50,7 @@ except (OSError, IOError):
 else:
     _logger.info('Will use the Wkhtmltopdf binary at %s' % _get_wkhtmltopdf_bin())
     out, err = process.communicate()
-    version = re.search('([0-9.]+)', out).group(0)
+    version = re.search('([0-9.]+)', out or "0").group(0)
     if LooseVersion(version) < LooseVersion('0.12.0'):
         _logger.info('Upgrade Wkhtmltopdf to (at least) 0.12.0')
         wkhtmltopdf_state = 'upgrade'
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index b2655c836fae4b4c9a580a28b46cde8860e2fb45..33bc556dcccb796696b689d6b5415607c576e8f3 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -545,17 +545,9 @@ class SaleOrderLine(models.Model):
     def _compute_tax_id(self):
         for line in self:
             fpos = line.order_id.fiscal_position_id or line.order_id.partner_id.property_account_position_id
-            if fpos:
-                # The superuser is used by website_sale in order to create a sale order. We need to make
-                # sure we only select the taxes related to the company of the partner. This should only
-                # apply if the partner is linked to a company.
-                if self.env.uid == SUPERUSER_ID and line.order_id.company_id:
-                    taxes = fpos.map_tax(line.product_id.taxes_id).filtered(lambda r: r.company_id == line.order_id.company_id)
-                else:
-                    taxes = fpos.map_tax(line.product_id.taxes_id)
-                line.tax_id = taxes
-            else:
-                line.tax_id = line.product_id.taxes_id if line.product_id.taxes_id else False
+            # If company_id is set, always filter taxes by the company
+            taxes = line.product_id.taxes_id.filtered(lambda r: not line.company_id or r.company_id == line.company_id)
+            line.tax_id = fpos.map_tax(taxes) if fpos else taxes
 
     @api.multi
     def _prepare_order_line_procurement(self, group_id=False):
diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py
index 3ba7c9d30bb333c4a52095d51e1ff5b3beeb0a24..19c96db048c4d0171ab3991fffe430e6262b698b 100644
--- a/addons/stock/wizard/stock_return_picking.py
+++ b/addons/stock/wizard/stock_return_picking.py
@@ -45,7 +45,7 @@ class stock_return_picking(osv.osv_memory):
             context = {}
         if context and context.get('active_ids', False):
             if len(context.get('active_ids')) > 1:
-                raise osv.except_osv(_('Warning!'), _("You may only return one picking at a time!"))
+                raise UserError(_("You may only return one picking at a time!"))
         res = super(stock_return_picking, self).default_get(cr, uid, fields, context=context)
         record_id = context and context.get('active_id', False) or False
         uom_obj = self.pool.get('product.uom')
diff --git a/addons/stock_account/stock_account.py b/addons/stock_account/stock_account.py
index 7b4eb4f9c91d2acd28aeba5aab6072dc231139c7..6a54df1ac6a771eab0c5dc478d0d02de984cdc37 100644
--- a/addons/stock_account/stock_account.py
+++ b/addons/stock_account/stock_account.py
@@ -255,7 +255,7 @@ class stock_quant(osv.osv):
 
         :param context: context dictionary that can explicitly mention the company to consider via the 'force_company' key
         :returns: journal_id, source account, destination account, valuation account
-        :raise: osv.except_osv() is any mandatory account or journal is not defined.
+        :raise: openerp.exceptions.UserError if any mandatory account or journal is not defined.
         """
         product_obj = self.pool.get('product.template')
         accounts = product_obj.browse(cr, uid, move.product_id.product_tmpl_id.id, context).get_product_accounts()
@@ -432,12 +432,14 @@ class stock_move(osv.osv):
                 else:
                     tmpl_dict[product_id] = 0
                     product_avail = qty_available
+                # if the incoming move is for a purchase order with foreign currency, need to call this to get the same value that the quant will use.
+                price_unit = self.pool.get('stock.move').get_price_unit(cr, uid, move, context=context)
                 if product_avail <= 0:
-                    new_std_price = move.price_unit
+                    new_std_price = price_unit
                 else:
                     # Get the standard price
                     amount_unit = product.standard_price
-                    new_std_price = ((amount_unit * product_avail) + (move.price_unit * move.product_qty)) / (product_avail + move.product_qty)
+                    new_std_price = ((amount_unit * product_avail) + (price_unit * move.product_qty)) / (product_avail + move.product_qty)
                 tmpl_dict[product_id] += move.product_qty
                 # Write the standard price, as SUPERUSER_ID because a warehouse manager may not have the right to write on products
                 ctx = dict(context or {}, force_company=move.company_id.id)
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 726c30e43fa0ef7e18ad87cacdabf88cbc43adb7..42d9b3a92ac71f1fb2b8899b6d63b4de7fb2439d 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -790,7 +790,7 @@
         <span class="o_count"/>
         <button class="btn btn-link" type="button"
             t-att-accesskey="widget.node.attrs.accesskey"/>
-        <input t-if="widget.debug" type="text" class="o_form_input o_debug_input"/>
+        <input t-if="widget.debug" t-att-readonly="widget.get('effective_readonly')" type="text" class="o_form_input o_debug_input"/>
     </div>
 </t>
 <t t-name="web.datepicker">
diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js
index 22536d70d94078628a4689fbfb81f6d200af12ae..c2b45cdb065403128db424662adab143fb72d846 100644
--- a/addons/website_forum/static/src/js/website_forum.js
+++ b/addons/website_forum/static/src/js/website_forum.js
@@ -20,7 +20,7 @@ if(!$('.website_forum').length) {
             ev.preventDefault();
             var $warning = $('<div class="alert alert-danger alert-dismissable oe_forum_alert" id="karma_alert">'+
                 '<button type="button" class="close notification_close" data-dismiss="alert" aria-hidden="true">&times;</button>'+
-                karma + _t(' karma is required to perform this action. You can earn karma by having your answers upvoted by the community.') + '</div>');
+                karma + ' ' + _t(' karma is required to perform this action. You can earn karma by having your answers upvoted by the community.') + '</div>');
             var vote_alert = $(ev.currentTarget).parent().find("#vote_alert");
             if (vote_alert.length == 0) {
                 $(ev.currentTarget).parent().append($warning);
diff --git a/addons/website_mail/views/website_mail.xml b/addons/website_mail/views/website_mail.xml
index d0df8e6b5a1e059ae10ef3d273cac55fe59140af..b65a19b327118c98831c41c2c81f2412cce95dea 100644
--- a/addons/website_mail/views/website_mail.xml
+++ b/addons/website_mail/views/website_mail.xml
@@ -84,6 +84,14 @@
                                 <t t-set="object" t-value="message"/>
                                 <t t-call="website.publish_short"/>
                                 <div t-field="message.body"/>
+                                <div class="o_mg_link_content">
+                                    <div class="col-md-2 col-sm-3 text-center" t-foreach='message.attachment_ids' t-as='attachment'>
+                                        <a t-attf-href="/web/content/#{attachment.id}?download=true" target="_blank">
+                                            <div class='oe_attachment_embedded o_image' t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/100x80"/>
+                                            <div class='oe_attachment_name'><t t-raw='attachment.name' /></div>
+                                        </a>
+                                    </div>
+                                </div>
                             </div>
                             </div>
                         </li>
diff --git a/addons/website_project_issue/views/project_issue_templates.xml b/addons/website_project_issue/views/project_issue_templates.xml
index 67729ac99e3e2d4c902759e752debadff726729b..a19fa256366c0a7d2278c21f151828beda18c1eb 100644
--- a/addons/website_project_issue/views/project_issue_templates.xml
+++ b/addons/website_project_issue/views/project_issue_templates.xml
@@ -53,6 +53,7 @@
                                     <div class="col-md-12">
                                         <h4>
                                             Issue <span t-field="issue.id"/> - <span t-field="issue.name"/>
+                                            <a class="btn btn-info" t-att-href="'/web#return_label=Website&amp;model=project.issue&amp;id=%s&amp;view_type=form' % (issue.id)" groups="project.group_project_user">Edit Issue</a>
                                             <span t-field="issue.stage_id.name" class="pull-right label label-info" title="Current stage of this issue"/>
                                         </h4>
                                     </div>
diff --git a/doc/_extensions/odoo/static/style.css b/doc/_extensions/odoo/static/style.css
index 65ad613a94efb37e7b462f7944f6c8b73d345e10..1d48dea23b0aa28f44f979dde1fe83a709fe57c3 100644
--- a/doc/_extensions/odoo/static/style.css
+++ b/doc/_extensions/odoo/static/style.css
@@ -9473,18 +9473,18 @@ h6,
   line-height: 1.4;
 }
 @media (min-width: 1200px) {
-  .has_code_col h1,
-  .has_code_col h2,
-  .has_code_col h3,
-  .has_code_col h4,
-  .has_code_col h5,
-  .has_code_col h6,
-  .has_code_col .h1,
-  .has_code_col .h2,
-  .has_code_col .h3,
-  .has_code_col .h4,
-  .has_code_col .h5,
-  .has_code_col .h6 {
+  .has_code_col .doc-aside h1,
+  .has_code_col .doc-aside h2,
+  .has_code_col .doc-aside h3,
+  .has_code_col .doc-aside h4,
+  .has_code_col .doc-aside h5,
+  .has_code_col .doc-aside h6,
+  .has_code_col .doc-aside .h1,
+  .has_code_col .doc-aside .h2,
+  .has_code_col .doc-aside .h3,
+  .has_code_col .doc-aside .h4,
+  .has_code_col .doc-aside .h5,
+  .has_code_col .doc-aside .h6 {
     color: white;
   }
 }
@@ -11928,7 +11928,7 @@ main.index.animating .card {
   font-size: 65%;
 }
 @media (min-width: 1200px) {
-  .has_code_col .card.top .container h1 {
+  .has_code_col .doc-aside .card.top .container h1 {
     color: white;
   }
 }
@@ -11969,7 +11969,7 @@ main.index.animating .card {
   }
 }
 @media screen and (min-width: 768px) and (min-width: 1200px) {
-  .has_code_col .card.top .container h1 {
+  .has_code_col .doc-aside .card.top .container h1 {
     color: white;
   }
 }
@@ -12010,7 +12010,7 @@ main.index.animating .card {
   font-size: 65%;
 }
 @media (min-width: 1200px) {
-  .has_code_col .toctree-wrapper > ul > li.toctree-l1 > span {
+  .has_code_col .doc-aside .toctree-wrapper > ul > li.toctree-l1 > span {
     color: white;
   }
 }
diff --git a/doc/cla/corporate/rocksolidsolutions.md b/doc/cla/corporate/rocksolidsolutions.md
new file mode 100644
index 0000000000000000000000000000000000000000..133c19de35c77a651fd74ea38679b97c433cf2b6
--- /dev/null
+++ b/doc/cla/corporate/rocksolidsolutions.md
@@ -0,0 +1,15 @@
+United States, 2016-05-25
+
+Rock Solid Solutions, LLC <http://www.rocksolidsolutions.org> agrees to the terms of the Odoo Corporate Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Daniel Kauffman, Manager rocksolidsolutions@users.noreply.github.com <https://github.com/rocksolidsolutions>
+
+List of contributors:
+
+Daniel Kauffman rocksolidsolutions@users.noreply.github.com <https://github.com/rocksolidsolutions>
diff --git a/openerp/service/server.py b/openerp/service/server.py
index 92fda76aa7a125eb2f8adffa9158fcd6c43439f3..1425acce3eba970f02a0278a118a37fadbb845d7 100644
--- a/openerp/service/server.py
+++ b/openerp/service/server.py
@@ -383,7 +383,8 @@ class PreforkServer(CommonServer):
     """
     def __init__(self, app):
         # config
-        self.address = (config['xmlrpc_interface'] or '0.0.0.0', config['xmlrpc_port'])
+        self.address = config['xmlrpc'] and \
+            (config['xmlrpc_interface'] or '0.0.0.0', config['xmlrpc_port'])
         self.population = config['workers']
         self.timeout = config['limit_time_real']
         self.limit_request = config['limit_request']
@@ -558,12 +559,13 @@ class PreforkServer(CommonServer):
         signal.signal(signal.SIGQUIT, dumpstacks)
         signal.signal(signal.SIGUSR1, log_ormcache_stats)
 
-        # listen to socket
-        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        self.socket.setblocking(0)
-        self.socket.bind(self.address)
-        self.socket.listen(8 * self.population)
+        if self.address:
+            # listen to socket
+            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            self.socket.setblocking(0)
+            self.socket.bind(self.address)
+            self.socket.listen(8 * self.population)
 
     def stop(self, graceful=True):
         if self.long_polling_pid is not None:
@@ -587,7 +589,8 @@ class PreforkServer(CommonServer):
             _logger.info("Stopping forcefully")
         for pid in self.workers.keys():
             self.worker_kill(pid, signal.SIGTERM)
-        self.socket.close()
+        if self.socket:
+            self.socket.close()
 
     def run(self, preload, stop):
         self.start()
@@ -690,11 +693,13 @@ class Worker(object):
         _logger.info("Worker %s (%s) alive", self.__class__.__name__, self.pid)
         # Reseed the random number generator
         random.seed()
-        # Prevent fd inherientence close_on_exec
-        flags = fcntl.fcntl(self.multi.socket, fcntl.F_GETFD) | fcntl.FD_CLOEXEC
-        fcntl.fcntl(self.multi.socket, fcntl.F_SETFD, flags)
-        # reset blocking status
-        self.multi.socket.setblocking(0)
+        if self.multi.socket:
+            # Prevent fd inheritance: close_on_exec
+            flags = fcntl.fcntl(self.multi.socket, fcntl.F_GETFD) | fcntl.FD_CLOEXEC
+            fcntl.fcntl(self.multi.socket, fcntl.F_SETFD, flags)
+            # reset blocking status
+            self.multi.socket.setblocking(0)
+
         signal.signal(signal.SIGINT, self.signal_handler)
         signal.signal(signal.SIGTERM, signal.SIG_DFL)
         signal.signal(signal.SIGCHLD, signal.SIG_DFL)
@@ -812,7 +817,8 @@ class WorkerCron(Worker):
     def start(self):
         os.nice(10)     # mommy always told me to be nice with others...
         Worker.start(self)
-        self.multi.socket.close()
+        if self.multi.socket:
+            self.multi.socket.close()
 
 #----------------------------------------------------------
 # start/stop public api
diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py
index 756edfb61cedb61ec602949bc8627d719b60a7f1..a852f05de77da35605c141ffa255683337260252 100644
--- a/openerp/tools/translate.py
+++ b/openerp/tools/translate.py
@@ -32,7 +32,7 @@ _logger = logging.getLogger(__name__)
 # used to notify web client that these translations should be loaded in the UI
 WEB_TRANSLATION_COMMENT = "openerp-web"
 
-SKIPPED_ELEMENTS = ('script', 'style')
+SKIPPED_ELEMENTS = ('script', 'style', 'title')
 
 _LOCALE2WIN32 = {
     'af_ZA': 'Afrikaans_South Africa',
@@ -231,7 +231,8 @@ class XMLTranslator(object):
             isinstance(node, SKIPPED_ELEMENT_TYPES) or
             node.tag in SKIPPED_ELEMENTS or
             node.get("t-translation", "").strip() == "off" or
-            node.tag == "attribute" and node.get("name") not in TRANSLATED_ATTRS
+            node.tag == "attribute" and node.get("name") not in TRANSLATED_ATTRS or
+            not node.getparent() and node.text and '<!DOCTYPE' in node.text
         ):
             # do not translate the contents of the node
             tail, node.tail = node.tail, None