diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 35979cd808ef412dea145738880fbd7764ddd916..d0dc2ec8b42c36346fe1c262305c31731a5bc28f 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -295,7 +295,8 @@ class account_invoice(osv.osv):
             },
             multi='all'),
         'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}, track_visibility='always'),
-        'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+        'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]},
+                                      domain="[('type', 'in', {'out_invoice': ['sale'], 'out_refund': ['sale_refund'], 'in_refund': ['purchase_refund'], 'in_invoice': ['purchase']}.get(type, [])), ('company_id', '=', company_id)]"),
         'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True, readonly=True, states={'draft':[('readonly',False)]}),
         'check_total': fields.float('Verification Total', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
         'reconciled': fields.function(_reconciled, string='Paid/Reconciled', type='boolean',
diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index dcb078b102f6e989c74119aa96b3a5573c401ff3..f1dc842eceecedcbb872c129c99c82d38c307dea 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -72,6 +72,7 @@ class account_analytic_invoice_line(osv.osv):
 
         result = {}
         res = self.pool.get('product.product').browse(cr, uid, product, context=local_context)
+        price = False
         if price_unit is not False:
             price = price_unit
         elif pricelist_id:
diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml
index 97f96f75901e067a899cfe5f075599e0af86c4ae..2dd53832529dad16f2c7af9ce779bd074d84dc48 100644
--- a/addons/account_voucher/voucher_sales_purchase_view.xml
+++ b/addons/account_voucher/voucher_sales_purchase_view.xml
@@ -248,7 +248,7 @@
                         <page string="Bill Information">
                             <field name="line_dr_ids" on_change="onchange_price(line_dr_ids, tax_id, partner_id)" context="{'journal_id':journal_id,'partner_id':partner_id}">
                                 <tree string="Expense Lines" editable="bottom">
-                                    <field name="account_id" widget="selection" domain="[('user_type.report_type','=','expense'), ('type','!=','view')]"/>
+                                    <field name="account_id" domain="[('user_type.report_type','=','expense'), ('type','!=','view')]"/>
                                     <field name="name"/>
                                     <field name="amount"/>
                                     <field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
diff --git a/addons/auth_crypt/auth_crypt.py b/addons/auth_crypt/auth_crypt.py
index 4651d27fe7da991b2ef7610460fbde74005c2068..c5bd57990178038d90b3e569255a531294583c13 100644
--- a/addons/auth_crypt/auth_crypt.py
+++ b/addons/auth_crypt/auth_crypt.py
@@ -117,10 +117,22 @@ def sh256crypt(cls, password, salt, magic=magic_sha256):
 class res_users(osv.osv):
     _inherit = "res.users"
 
+    def init(self, cr):
+        """Encrypt all passwords at module installation"""
+        cr.execute("SELECT id, password FROM res_users WHERE password IS NOT NULL and password != ''")
+        for user in cr.fetchall():
+            self._set_encrypted_password(cr, user[0], user[1])
+
+    def _set_encrypted_password(self, cr, uid, plain_password):
+        """Set an encrypted password for a given user"""
+        salt = gen_salt()
+        stored_password_crypt = md5crypt(plain_password, salt)
+        cr.execute("UPDATE res_users SET password = '', password_crypt = %s WHERE id = %s",
+                   (stored_password_crypt, uid))
+
     def set_pw(self, cr, uid, id, name, value, args, context):
         if value:
-            encrypted = md5crypt(value, gen_salt())
-            cr.execute("update res_users set password='', password_crypt=%s where id=%s", (encrypted, id))
+            self._set_encrypted_password(cr, id, value)
         del value
 
     def get_pw( self, cr, uid, ids, name, args, context ):
@@ -144,9 +156,7 @@ class res_users(osv.osv):
         if cr.rowcount:
             stored_password, stored_password_crypt = cr.fetchone()
             if stored_password and not stored_password_crypt:
-                salt = gen_salt()
-                stored_password_crypt = md5crypt(stored_password, salt)
-                cr.execute("UPDATE res_users SET password='', password_crypt=%s WHERE id=%s", (stored_password_crypt, uid))
+                self._set_encrypted_password(cr, uid, stored_password)
         try:
             return super(res_users, self).check_credentials(cr, uid, password)
         except openerp.exceptions.AccessDenied:
diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py
index 4fca426ffc0563530a171094f5f8b63b59a74d74..e4d3e18792a7d89826d8449254d09255ed494c24 100644
--- a/addons/auth_oauth/controllers/main.py
+++ b/addons/auth_oauth/controllers/main.py
@@ -70,7 +70,7 @@ class OAuthLogin(openerp.addons.web.controllers.main.Home):
         state = dict(
             d=request.session.db,
             p=provider['id'],
-            r=request.httprequest.full_path
+            r=werkzeug.url_quote_plus(request.httprequest.full_path)
         )
         token = request.params.get('token')
         if token:
@@ -139,7 +139,7 @@ class OAuthController(http.Controller):
                 cr.commit()
                 action = state.get('a')
                 menu = state.get('m')
-                redirect = state.get('r')
+                redirect = werkzeug.url_unquote_plus(state['r']) if state.get('r') else False
                 url = '/web'
                 if redirect and not redirect.startswith('/auth_oauth/signin') and \
                 (not redirect.startswith('/web/login') or 'redirect' in urlparse.urlsplit(redirect).query):
diff --git a/addons/calendar/static/src/js/base_calendar.js b/addons/calendar/static/src/js/base_calendar.js
index eed958e20d9ac1406f90168d7153e8cac65d89dd..37669840818c75fe1b8314dadbfbf0edadf43410 100644
--- a/addons/calendar/static/src/js/base_calendar.js
+++ b/addons/calendar/static/src/js/base_calendar.js
@@ -102,7 +102,7 @@ openerp.calendar = function(instance) {
             var self = this;
             var action_url = '';
 
-            action_url = _.str.sprintf('/?db=%s#id=%s&view_type=form&model=calendar.event', db, meeting_id);
+            action_url = _.str.sprintf('/web?db=%s#id=%s&view_type=form&model=calendar.event', db, meeting_id);
             
             var reload_page = function(){
                 return location.replace(action_url);
diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py
index e76b5c60d1fe85cf32432630c4c2aa3aacd8ac82..c4a4dfd6b2d4a5c514a07a16632fd8a8ad5b99e2 100644
--- a/addons/event/report/report_event_registration.py
+++ b/addons/event/report/report_event_registration.py
@@ -32,7 +32,7 @@ class report_event_registration(osv.osv):
         'draft_state': fields.integer(' # No of Draft Registrations', size=20),
         'confirm_state': fields.integer(' # No of Confirmed Registrations', size=20),
         'seats_max': fields.integer('Max Seats'),
-        'nbevent': fields.integer('Number Of Events'),
+        'nbevent': fields.integer('Number of Registrations'),
         'event_type': fields.many2one('event.type', 'Event Type'),
         'registration_state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Attended'), ('cancel', 'Cancelled')], 'Registration State', readonly=True, required=True),
         'event_state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Event State', readonly=True, required=True),
@@ -59,7 +59,7 @@ class report_event_registration(osv.osv):
                 r.name AS name_registration,
                 e.company_id AS company_id,
                 e.date_begin AS event_date,
-                count(e.id) AS nbevent,
+                count(r.id) AS nbevent,
                 CASE WHEN r.state IN ('draft') THEN r.nb_register ELSE 0 END AS draft_state,
                 CASE WHEN r.state IN ('open','done') THEN r.nb_register ELSE 0 END AS confirm_state,
                 e.type AS event_type,
diff --git a/addons/event/static/src/css/event.css b/addons/event/static/src/css/event.css
index ff5bfaba19b4e792f46b387cb9b2ce743bfae7f0..53c03cc03f007b3c2ea2b32dcfaceed7b8049b11 100644
--- a/addons/event/static/src/css/event.css
+++ b/addons/event/static/src/css/event.css
@@ -1,7 +1,7 @@
 .oe_event_date{
   border-top-left-radius:3px;
   border-top-right-radius:3px;
-  font-size: 48px;
+  font-size: 36px;
   height: auto;
   font-weight: bold;
   text-align: center;
diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py
index ed6016b96658584f447eb1ca9fdd1a5391c78305..ea99ef6b841f8781c21009aa7b6bc90056c4f64c 100644
--- a/addons/gamification/models/challenge.py
+++ b/addons/gamification/models/challenge.py
@@ -58,7 +58,7 @@ def start_end_date_for_period(period, default_start_date=False, default_end_date
         end_date = default_end_date
 
     if start_date and end_date:
-        return (start_date.strftime(DF), end_date.strftime(DF))
+        return (datetime.strftime(start_date, DF), datetime.strftime(end_date, DF))
     else:
         return (start_date, end_date)
 
diff --git a/addons/google_calendar/google_calendar.py b/addons/google_calendar/google_calendar.py
index f36062b6be2c422839da7f3ba3e95627319306c3..b8b60141e978072fd6939931b84ec3af6df9d779 100644
--- a/addons/google_calendar/google_calendar.py
+++ b/addons/google_calendar/google_calendar.py
@@ -530,7 +530,7 @@ class google_calendar(osv.AbstractModel):
         for att in att_obj.browse(cr, uid, my_att_ids, context=context):
             event = att.event_id
 
-            base_event_id = att.google_internal_event_id.split('_')[0]
+            base_event_id = att.google_internal_event_id.rsplit('_', 1)[0]
 
             if base_event_id not in event_to_synchronize:
                 event_to_synchronize[base_event_id] = {}
@@ -552,7 +552,7 @@ class google_calendar(osv.AbstractModel):
 
         for event in all_event_from_google.values():
             event_id = event.get('id')
-            base_event_id = event_id.split('_')[0]
+            base_event_id = event_id.rsplit('_', 1)[0]
 
             if base_event_id not in event_to_synchronize:
                 event_to_synchronize[base_event_id] = {}
@@ -615,7 +615,7 @@ class google_calendar(osv.AbstractModel):
                     if actSrc == 'OE':
                         self.delete_an_event(cr, uid, current_event[0], context=context)
                     elif actSrc == 'GG':
-                            new_google_event_id = event.GG.event['id'].split('_')[1]
+                            new_google_event_id = event.GG.event['id'].rsplit('_', 1)[1]
                             if 'T' in new_google_event_id:
                                 new_google_event_id = new_google_event_id.replace('T', '')[:-1]
                             else:
@@ -623,7 +623,11 @@ class google_calendar(osv.AbstractModel):
 
                                 if event.GG.status:
                                     parent_event = {}
-                                    parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].OE.event_id, new_google_event_id)
+                                    if event_to_synchronize[base_event][0][1].OE.event_id:
+                                        parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].OE.event_id, new_google_event_id)
+                                    else:
+                                        main_ev = att_obj.search_read(cr, uid, [('google_internal_event_id', '=', event.GG.event['id'].rsplit('_', 1)[0])], fields=['event_id'], context=context)
+                                        parent_event['id'] = "%s-%s" % (main_ev[0].get('event_id')[0], new_google_event_id)
                                     res = self.update_from_google(cr, uid, parent_event, event.GG.event, "copy", context)
                                 else:
                                     if event_to_synchronize[base_event][0][1].OE.event_id:
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index 5bb172eb0820d6f0a250e0eb2b8975573c1d86c8..fbadc726e4b844d719eeb61d9c619a15e93d50ee 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -225,7 +225,7 @@ class hr_employee(osv.osv):
                  "resized as a 128x128px image, with aspect ratio preserved. "\
                  "Use this field in form views or some kanban views."),
         'image_small': fields.function(_get_image, fnct_inv=_set_image,
-            string="Smal-sized photo", type="binary", multi="_get_image",
+            string="Small-sized photo", type="binary", multi="_get_image",
             store = {
                 'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
             },
diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml
index 5b0a58ec8835821635d42e81fb882306547d158b..5805c0db1f3bf96871512c3b4c619509e265b14c 100644
--- a/addons/hr/hr_view.xml
+++ b/addons/hr/hr_view.xml
@@ -39,7 +39,9 @@
                             <page string="Public Information">
                                 <group>
                                     <group string="Contact Information">
-                                        <field name="address_id" on_change="onchange_address_id(address_id)" context="{'show_address': 1}" options='{"always_reload": True, "highlight_first_line": True}'/>
+                                        <field name="address_id" on_change="onchange_address_id(address_id)"
+                                            context="{'show_address': 1, 'default_customer': False}"
+                                            options='{"always_reload": True, "highlight_first_line": True}'/>
                                         <field name="mobile_phone"/>
                                         <field name="work_location"/>
                                     </group>
@@ -67,7 +69,9 @@
                                         <field name="otherid" groups="base.group_hr_user"/>
                                     </group>
                                     <group string="Contact Information">
-                                        <field name="address_home_id" context="{'show_address': 1}" options='{"always_reload": True, "highlight_first_line": True}'/>
+                                        <field name="address_home_id"
+                                            context="{'show_address': 1, 'default_customer': False}"
+                                            options='{"always_reload": True, "highlight_first_line": True}'/>
                                     </group>
                                     <group string="Status">
                                         <field name="gender"/>
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index b6b95427db1863d6591cb3c982a318ec00b5c9c1..277b2d727e1bad6511c294d646891e798d3f10de 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -99,7 +99,7 @@ class hr_holidays_status(osv.osv):
         for record in self.browse(cr, uid, ids, context=context):
             name = record.name
             if not record.limit:
-                name = name + ('  (%d/%d)' % (record.leaves_taken or 0.0, record.max_leaves or 0.0))
+                name = name + ('  (%g/%g)' % (record.leaves_taken or 0.0, record.max_leaves or 0.0))
             res.append((record.id, name))
         return res
 
diff --git a/addons/l10n_be_invoice_bba/invoice.py b/addons/l10n_be_invoice_bba/invoice.py
index 854593a87cc391532f1c63bb425b8a04e7a3af28..499e6e6c4ac1057bd74d5f1e6e00b21d96c44daa 100644
--- a/addons/l10n_be_invoice_bba/invoice.py
+++ b/addons/l10n_be_invoice_bba/invoice.py
@@ -141,7 +141,7 @@ class account_invoice(osv.osv):
                 elif algorithm == 'random':
                     if not self.check_bbacomm(reference):
                         base = random.randint(1, 9999999999)
-                        bbacomm = str(base).rjust(7, '0')
+                        bbacomm = str(base).rjust(10, '0')
                         base = int(bbacomm)
                         mod = base % 97 or 97
                         mod = str(mod).rjust(2, '0')
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index cc74f25dcde0fca0ce9ac043f57c47463e1654eb..c9662f045678ec7688c16e3ae0766b72713e74ad 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -34,6 +34,7 @@ import pytz
 import socket
 import time
 import xmlrpclib
+import re
 from email.message import Message
 from urllib import urlencode
 
@@ -48,6 +49,8 @@ from openerp.tools.translate import _
 _logger = logging.getLogger(__name__)
 
 
+mail_header_msgid_re = re.compile('<[^<>]+>')
+
 def decode_header(message, header, separator=' '):
     return separator.join(map(decode, filter(None, message.get_all(header, []))))
 
@@ -1291,13 +1294,13 @@ class mail_thread(osv.AbstractModel):
             msg_dict['date'] = stored_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
 
         if message.get('In-Reply-To'):
-            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', '=', decode(message['In-Reply-To']))])
+            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', '=', decode(message['In-Reply-To'].strip()))])
             if parent_ids:
                 msg_dict['parent_id'] = parent_ids[0]
 
         if message.get('References') and 'parent_id' not in msg_dict:
-            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', 'in',
-                                                                         [x.strip() for x in decode(message['References']).split()])])
+            msg_list =  mail_header_msgid_re.findall(decode(message['References']))
+            parent_ids = self.pool.get('mail.message').search(cr, uid, [('message_id', 'in', [x.strip() for x in msg_list])])
             if parent_ids:
                 msg_dict['parent_id'] = parent_ids[0]
 
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 91d50e9323630f73fdd8a877f5af820d72cba4f0..390449db653479932d509b52351132eddc994c83 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -1050,8 +1050,8 @@ class mrp_production(osv.osv):
 
             # Take routing location as a Source Location.
             source_location_id = production.location_src_id.id
-            if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
-                source_location_id = production.bom_id.routing_id.location_id.id
+            if production.routing_id and production.routing_id.location_id:
+                source_location_id = production.routing_id.location_id.id
 
             for line in production.product_lines:
                 consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index ff225c46e10f977db17e43b1c7fd2daef5576ea0..bb09e6829430f4c2da3a92d4a8ba0a0c7448dc94 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -50,8 +50,8 @@
             <field name="user_id" ref="base.user_demo"/>
             <field name="alias_model">project.task</field>
             <field name="message_follower_ids" eval="[(6, 0, [
-                    ref('base.user_root'),
-                    ref('base.user_demo')])]"/>
+                    ref('base.partner_root'),
+                    ref('base.partner_demo')])]"/>
         </record>
 
         <!-- We assign after so that default values applies -->
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 503d6f84aa1c4379d58256c3afdbf5aedfbe6dbd..05848a5f1e6f994148a4879b48956408f43f1873 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -2337,7 +2337,7 @@
 }
 .openerp .oe_fileupload .oe_add button.oe_attach .oe_e {
   position: relative;
-  top: -1px;
+  top: -10px;
   left: -9px;
 }
 .openerp .oe_fileupload .oe_add input.oe_form_binary_file {
@@ -3288,6 +3288,9 @@ body.oe_single_form .oe_single_form_container {
 .openerp_ie ul.oe_form_status li.oe_active > .arrow span, .openerp_ie ul.oe_form_status_clickable li.oe_active > .arrow span {
   background-color: #729fcf !important;
 }
+}
+.openerp_ie .oe_webclient {
+  height: auto !important;
 
 @media print {
   .openerp {
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 8ebb2d88ca3838eb226f6a68804b0da188c6749d..12d9d83e48e5ea8a3e6fd4a114887a204c50852c 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -1918,7 +1918,7 @@ $sheet-padding: 16px
                 text-shadow: none
                 .oe_e
                     position: relative
-                    top: -1px
+                    top: -10px
                     left: -9px                    
             input.oe_form_binary_file
                 display: inline-block
@@ -2670,6 +2670,8 @@ body.oe_single_form
             > .arrow span
                 background-color: #729fcf !important
 
+    .oe_webclient
+        height: auto !important
 // }}}
 
 // @media print {{{
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 3c32dbe04260cd21ca2be9dac2e290a5b41e6ed4..f08dc31021a953a26d82ff4e8a3acdc87503fd7b 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -233,7 +233,8 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
                 value = value.replace(instance.web._t.database.parameters.thousands_sep, "");
             } while(tmp !== value);
             tmp = Number(value);
-            if (isNaN(tmp))
+            // do not accept not numbers or float values
+            if (isNaN(tmp) || tmp % 1)
                 throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value));
             return tmp;
         case 'float':
@@ -268,6 +269,11 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
         case 'datetime':
             var datetime = Date.parseExact(
                     value, (date_pattern + ' ' + time_pattern));
+            if (datetime !== null)
+                return instance.web.datetime_to_str(datetime);
+            datetime = Date.parseExact(value.replace(/\d+/g, function(m){
+                return m.length === 1 ? "0" + m : m ;
+            }), (date_pattern + ' ' + time_pattern));
             if (datetime !== null)
                 return instance.web.datetime_to_str(datetime);
             datetime = Date.parse(value);
@@ -276,6 +282,11 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
             throw new Error(_.str.sprintf(_t("'%s' is not a correct datetime"), value));
         case 'date':
             var date = Date.parseExact(value, date_pattern);
+            if (date !== null)
+                return instance.web.date_to_str(date);
+            date = Date.parseExact(value.replace(/\d+/g, function(m){
+                return m.length === 1 ? "0" + m : m ;
+            }), date_pattern);
             if (date !== null)
                 return instance.web.date_to_str(date);
             date = Date.parse(value);
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 832faa4ca62cd5ef0068e6fb31b7e46abf7b22d1..c59932265f70ee1ba7e5eaf17b24e689cbd1733d 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -345,11 +345,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
         'keydown .oe_searchview_input, .oe_searchview_facet': function (e) {
             switch(e.which) {
             case $.ui.keyCode.LEFT:
-                this.focusPreceding(this);
+                this.focusPreceding(e.target);
                 e.preventDefault();
                 break;
             case $.ui.keyCode.RIGHT:
-                this.focusFollowing(this);
+                this.focusFollowing(e.target);
                 e.preventDefault();
                 break;
             }
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 8bf948513a7ecf2ad2964cabb2d11dcbf85c7682..e651fbba26f469df9e10c22eed10cbaeb5f97d49 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -2517,6 +2517,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
     type_of_date: "datetime",
     events: {
         'change .oe_datepicker_master': 'change_datetime',
+        'keypress .oe_datepicker_master': 'change_datetime',
     },
     init: function(parent) {
         this._super(parent);
@@ -2635,8 +2636,8 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
     format_client: function(v) {
         return instance.web.format_value(v, {"widget": this.type_of_date});
     },
-    change_datetime: function() {
-        if (this.is_valid_()) {
+    change_datetime: function(e) {
+        if ((e.type !== "keypress" || e.which === 13) && this.is_valid_()) {
             this.set_value_from_ui_();
             this.trigger("datetime_changed");
         }
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index e2c63eb191ac59d333e4451f396fdbeaa17bc0da..ea2c28d9c3f924a5b8e5ac1ac4a9f727d5ff93aa 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -130,15 +130,7 @@
             if (this.editable()) {
                 this.$el.find('table:first').show();
                 this.$el.find('.oe_view_nocontent').remove();
-                this.start_edition().then(function(){
-                    var fields = self.editor.form.fields;
-                    self.editor.form.fields_order.some(function(field){
-                        if (fields[field].$el.is(':visible')){
-                            fields[field].$el.find("input").select();
-                            return true;
-                        }
-                    });
-                });
+                this.start_edition();
             } else {
                 this._super();
             }
@@ -243,6 +235,7 @@
             return this.ensure_saved().then(function () {
                 var $recordRow = self.groups.get_row_for(record);
                 var cells = self.get_cells_for($recordRow);
+                var fields = {};
                 self.fields_for_resize.splice(0, self.fields_for_resize.length);
                 return self.with_event('edit', {
                     record: record.attributes,
@@ -256,10 +249,16 @@
 
                         // FIXME: need better way to get the field back from bubbling (delegated) DOM events somehow
                         field.$el.attr('data-fieldname', field_name);
+                        fields[field_name] = field;
                         self.fields_for_resize.push({field: field, cell: cell});
                     }, options).then(function () {
                         $recordRow.addClass('oe_edition');
                         self.resize_fields();
+                        var focus_field = options && options.focus_field ? options.focus_field : undefined;
+                        if (!focus_field){
+                            focus_field = _.find(self.editor.form.fields_order, function(field){ return fields[field] && fields[field].$el.is(':visible:has(input)'); });
+                        }
+                        if (focus_field) fields[focus_field].$el.find('input').select();
                         return record.attributes;
                     });
                 }).fail(function () {
@@ -749,31 +748,6 @@
             throw new Error("is_editing's state filter must be either `new` or" +
                             " `edit` if provided");
         },
-        _focus_setup: function (focus_field) {
-            var form = this.form;
-
-            var field;
-            // If a field to focus was specified
-            if (focus_field
-                    // Is actually in the form
-                    && (field = form.fields[focus_field])
-                    // And is visible
-                    && field.$el.is(':visible')) {
-                // focus it
-                field.focus();
-                return;
-            }
-
-            _(form.fields_order).detect(function (name) {
-                // look for first visible field in fields_order, focus it
-                var field = form.fields[name];
-                if (!field.$el.is(':visible')) {
-                    return false;
-                }
-                // Stop as soon as a field got focused
-                return field.focus() !== false;
-            });
-        },
         edit: function (record, configureField, options) {
             // TODO: specify sequence of edit calls
             var self = this;
@@ -788,7 +762,6 @@
                 _(form.fields).each(function (field, name) {
                     configureField(name, field);
                 });
-                self._focus_setup(options && options.focus_field);
                 return form;
             });
         },
diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js
index 552e6a30b4743937c5a266562156496045d01e90..3b7f41999e232776039f568d07b7a6894cbf290d 100644
--- a/addons/web_calendar/static/src/js/web_calendar.js
+++ b/addons/web_calendar/static/src/js/web_calendar.js
@@ -219,7 +219,12 @@ openerp.web_calendar = function(instance) {
                 this.info_fields.push(fv.arch.children[fld].attrs.name);
             }
 
-            return (new instance.web.Model(this.dataset.model))
+            var edit_check = new instance.web.Model(this.dataset.model)
+                .call("check_access_rights", ["write", false])
+                .then(function (write_right) {
+                    self.write_right = write_right;
+                });
+            var init = new instance.web.Model(this.dataset.model)
                 .call("check_access_rights", ["create", false])
                 .then(function (create_right) {
                     self.create_right = create_right;
@@ -229,6 +234,7 @@ openerp.web_calendar = function(instance) {
                         self.ready.resolve();
                     });
                 });
+            return $.when(edit_check, init);
         },
 
         get_fc_init_options: function () {
@@ -842,7 +848,11 @@ openerp.web_calendar = function(instance) {
             if (! this.open_popup_action) {
                 var index = this.dataset.get_id_index(id);
                 this.dataset.index = index;
-                this.do_switch_view('form', null, { mode: "edit" });
+                if (this.write_right) {
+                    this.do_switch_view('form', null, { mode: "edit" });
+                } else {
+                    this.do_switch_view('form', null, { mode: "view" });
+                }
             }
             else {
                 var pop = new instance.web.form.FormOpenPopup(this);
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index d7b7843de00c6c0559a9cd9f45243618897d501d..93d75429352e7e66c3562259b37b552d836f0095 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -468,7 +468,7 @@
                     }
                 );
             });
-            menu.on('click', 'a[data-action!=ace]', function (event) {
+            menu.on('click', 'a[data-view-id]', function (event) {
                 var view_id = $(event.currentTarget).data('view-id');
                 openerp.jsonRpc('/website/customize_template_toggle', 'call', {
                     'view_id': view_id
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 89eae9f4a49c87cf5bfd5885985ce65f8e71b3df..938f1877731db445ae17cab8506a5fc9f1f3106f 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -98,7 +98,7 @@ class table_compute(object):
                     self.table[(pos/PPR)+y2][(pos%PPR)+x2] = False
             self.table[pos/PPR][pos%PPR] = {
                 'product': p, 'x':x, 'y': y,
-                'class': " ".join(map(lambda x: x.html_class, p.website_style_ids))
+                'class': " ".join(map(lambda x: x.html_class or '', p.website_style_ids))
             }
             if index<=PPG:
                 maxy=max(maxy,y+(pos/PPR))
diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py
index 8aa968a3b3a5a46718337219df51338bba141993..ae6a52ebee648a85b8124737fbafb5538a486343 100644
--- a/openerp/addons/base/ir/ir_actions.py
+++ b/openerp/addons/base/ir/ir_actions.py
@@ -482,6 +482,8 @@ class ir_actions_server(osv.osv):
                                    "based on the sequence. Low number means high priority."),
         'model_id': fields.many2one('ir.model', 'Base Model', required=True, ondelete='cascade',
                                     help="Base model on which the server action runs."),
+        'model_name': fields.related('model_id', 'model', type='char',
+                                     string='Model Name', readonly=True),
         'menu_ir_values_id': fields.many2one('ir.values', 'More Menu entry', readonly=True,
                                              help='More menu entry.'),
         # Client Action
@@ -641,6 +643,10 @@ class ir_actions_server(osv.osv):
             'wkf_field_id': False,
             'crud_model_id': model_id,
         }
+
+        if model_id:
+            values['model_name'] = self.pool.get('ir.model').browse(cr, uid, model_id, context).model
+
         return {'value': values}
 
     def on_change_wkf_wonfig(self, cr, uid, ids, use_relational_model, wkf_field_id, wkf_model_id, model_id, context=None):
@@ -744,6 +750,7 @@ class ir_actions_server(osv.osv):
         crud_model_name = False
         if crud_model_id:
             crud_model_name = self.pool.get('ir.model').browse(cr, uid, crud_model_id, context).model
+        
         values = {'link_field_id': False, 'crud_model_name': crud_model_name}
         return {'value': values}
 
diff --git a/openerp/addons/base/ir/ir_actions.xml b/openerp/addons/base/ir/ir_actions.xml
index 4eb869daa8003b37aefe1e8a3bfed248d7067fad..42408132794f11bddc680b4370cbf4e10e569914 100644
--- a/openerp/addons/base/ir/ir_actions.xml
+++ b/openerp/addons/base/ir/ir_actions.xml
@@ -349,8 +349,9 @@
                                             Check to attach the newly created record to the record on which the server action runs.
                                         </p>
                                         <group>
+                                            <field name="model_name" invisible="1"/>
                                             <field name="link_field_id"
-                                                    domain="[('model_id', '=', model_id), ('relation', '=', crud_model_name), ('ttype', 'in', ['many2one'])]"
+                                                    domain="[('model_id', '=', crud_model_id), ('relation', '=', model_name), ('ttype', 'in', ['many2one'])]"
                                                     attrs="{'required': [('state', '=', 'object_create'), ('link_new_record', '=', True)],
                                                             'invisible': ['|', ('state', '!=', 'object_create'), ('link_new_record', '=', False)]}"/>
                                         </group>
diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py
index e24d74e06252879812e9f2206ee5e79e2c5db2e3..db59d37d350f9f07a177b1361a1320a41351fa43 100644
--- a/openerp/osv/fields.py
+++ b/openerp/osv/fields.py
@@ -561,7 +561,7 @@ class many2one(_column):
         # we use uid=1 because the visibility of a many2one field value (just id and name)
         # must be the access right of the parent form and not the linked object itself.
         records = dict(obj.name_get(cr, SUPERUSER_ID,
-                                    list(set([x for x in res.values() if isinstance(x, (int,long))])),
+                                    list(set([x for x in res.values() if x and isinstance(x, (int,long))])),
                                     context=context))
         for id in res:
             if res[id] in records:
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index 6796042922ff6652693be3db6a81e9ef2fb450ac..2976d64471862b9c820858c711d1d36e8a858a54 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -3357,6 +3357,8 @@ class BaseModel(object):
             return []
         if fields_to_read is None:
             fields_to_read = self._columns.keys()
+        else:
+            fields_to_read = list(set(fields_to_read))
 
         # all inherited fields + all non inherited fields for which the attribute whose name is in load is True
         fields_pre = [f for f in fields_to_read if