diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index 9550f77bcab5de52d9cb4858e6580cf18d3c26de..de2c5734699b87684b57487a7886f6c20e68caf9 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -702,7 +702,9 @@ class account_analytic_account(osv.osv):
 
     def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None):
         fpos_obj = self.pool.get('account.fiscal.position')
-        fiscal_position = fpos_obj.browse(cr, uid,  fiscal_position_id, context=context)
+        fiscal_position = None
+        if fiscal_position_id:
+            fiscal_position = fpos_obj.browse(cr, uid,  fiscal_position_id, context=context)
         invoice_lines = []
         for line in contract.recurring_invoice_line_ids:
 
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index 51ebf96e81bd8dbc61fd50c144767735606dc1ec..c787516111f90201c0aaeadbd84d6958971852c0 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -221,9 +221,9 @@ class email_template(osv.osv):
                             help="Optional translation language (ISO code) to select when sending out an email. "
                                  "If not set, the english version will be used. "
                                  "This should usually be a placeholder expression "
-                                 "that provides the appropriate language code, e.g. "
-                                 "${object.partner_id.lang.code}.",
-                            placeholder="${object.partner_id.lang.code}"),
+                                 "that provides the appropriate language, e.g. "
+                                 "${object.partner_id.lang}.",
+                            placeholder="${object.partner_id.lang}"),
         'user_signature': fields.boolean('Add Signature',
                                          help="If checked, the user's signature will be appended to the text version "
                                               "of the message"),
diff --git a/addons/event/event.py b/addons/event/event.py
index a31ec00b8c082507d9ebf22e0d9d73e91421cc17..c1d5a44a1d226e620bbd2822778b67bb58b23dd9 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -177,7 +177,7 @@ class event_event(osv.osv):
         'name': fields.char('Event Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
         'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}),
         'type': fields.many2one('event.type', 'Type of Event', readonly=False, states={'done': [('readonly', True)]}),
-        'seats_max': fields.integer('Maximum Avalaible Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}),
+        'seats_max': fields.integer('Maximum Available Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}),
         'seats_min': fields.integer('Minimum Reserved Seats', oldname='register_min', help="You can for each event define a minimum registration level. If you do not enough registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}),
         'seats_reserved': fields.function(_get_seats, oldname='register_current', string='Reserved Seats', type='integer', multi='seats_reserved',
             store={'event.registration': (_get_events_from_registrations, ['state'], 10),
diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py
index 69ad0cb6af6ac1512e0356105b616eef49b1ec4b..9816dc6808263bd73a4b2e40927ed4a3c67780e0 100644
--- a/addons/event_sale/event_sale.py
+++ b/addons/event_sale/event_sale.py
@@ -215,7 +215,7 @@ class event_ticket(osv.osv):
         'deadline': fields.date("Sales End"),
         'is_expired': fields.function(_is_expired, type='boolean', string='Is Expired'),
         'price': fields.float('Price'),
-        'seats_max': fields.integer('Maximum Avalaible Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )"),
+        'seats_max': fields.integer('Maximum Available Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )"),
         'seats_reserved': fields.function(_get_seats, string='Reserved Seats', type='integer', multi='seats_reserved'),
         'seats_available': fields.function(_get_seats, string='Available Seats', type='integer', multi='seats_reserved'),
         'seats_unconfirmed': fields.function(_get_seats, string='Unconfirmed Seat Reservations', type='integer', multi='seats_reserved'),
diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py
index adf09a63c855d8a5ab279767784176134d88ae65..39b2ba5c3efdb44a7ed9aadc1ef0c83a71d436cf 100644
--- a/addons/hr_holidays/report/holidays_summary_report.py
+++ b/addons/hr_holidays/report/holidays_summary_report.py
@@ -223,9 +223,7 @@ class report_custom(report_rml):
         elif data['model']=='ir.ui.menu':
             for id in data['form']['depts']:
                 dept = obj_dept.browse(cr, uid, id, context=context)
-                cr.execute("""SELECT id FROM hr_employee \
-                WHERE department_id = %s""", (id,))
-                emp_ids = [x[0] for x in cr.fetchall()]
+                emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)], context=context)
                 if emp_ids==[]:
                     continue
                 dept_done=0
diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv
index 8a94f0274083c609d7d54a73e917747e57d1643c..b05ab25d3cf358abb6f442fe7d63679bee2989d2 100644
--- a/addons/stock/security/ir.model.access.csv
+++ b/addons/stock/security/ir.model.access.csv
@@ -3,7 +3,7 @@ access_stock_incoterms_all,stock.incoterms all,model_stock_incoterms,,1,0,0,0
 access_stock_incoterms_manager,stock.incoterms manager,model_stock_incoterms,stock.group_stock_manager,1,1,1,1
 access_stock_warehouse_manager,stock.warehouse.manager,model_stock_warehouse,stock.group_stock_manager,1,1,1,1
 access_stock_warehouse_user,stock.warehouse.user,model_stock_warehouse,base.group_user,1,0,0,0
-access_stock_location__partner_manager,stock.location.partner.manager,model_stock_location,base.group_partner_manager,1,1,1,1
+access_stock_location__partner_manager,stock.location.partner.manager,model_stock_location,base.group_partner_manager,1,0,0,0
 access_stock_location_manager,stock.location.manager,model_stock_location,stock.group_stock_manager,1,1,1,1
 access_stock_location_user,stock.location.user,model_stock_location,base.group_user,1,0,0,0
 access_stock_picking_user,stock.picking user,model_stock_picking,stock.group_stock_user,1,1,1,1
diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py
index ea0ec1506ba72d2a448a1d8c2ea62bcc5826d5cf..f14199b3b9d38dd4ab354dcb722a989bebea8a64 100644
--- a/addons/website_crm_partner_assign/controllers/main.py
+++ b/addons/website_crm_partner_assign/controllers/main.py
@@ -124,7 +124,7 @@ class WebsiteCrmPartnerAssign(http.Controller):
             context=request.context)  # todo in trunk: order="grade_id DESC, implemented_count DESC", offset=pager['offset'], limit=self._references_per_page
         partners = partner_obj.browse(request.cr, SUPERUSER_ID, partner_ids, request.context)
         # remove me in trunk
-        partners.sort(key=lambda x: (-1 * (x.grade_id and x.grade_id.id or 0), len(x.implemented_partner_ids)), reverse=True)
+        partners.sort(key=lambda x: (x.grade_id.sequence if x.grade_id else 0, len([i for i in x.implemented_partner_ids if i.website_published])), reverse=True)
         partners = partners[pager['offset']:pager['offset'] + self._references_per_page]
 
         google_map_partner_ids = ','.join(map(str, [p.id for p in partners]))
diff --git a/addons/website_partner/models/res_partner.py b/addons/website_partner/models/res_partner.py
index e762455debe3f805cdf31614ba269acf6f540ec0..c165a50ab06d5a986368a6904a7e997ed0254afd 100644
--- a/addons/website_partner/models/res_partner.py
+++ b/addons/website_partner/models/res_partner.py
@@ -17,7 +17,7 @@ class WebsiteResPartner(osv.Model):
             'Website Partner Full Description'
         ),
         'website_short_description': fields.text(
-            'Website artner Short Description'
+            'Website Partner Short Description'
         ),
         # hack to allow using plain browse record in qweb views
         'self': fields.function(_get_ids, type='many2one', relation=_name),
diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py
index 3101f52f2e03ef1194ba2396c596e1a01e1c180e..7b6e1bb9165a21b83ff635827824c34f22d9b285 100644
--- a/openerp/addons/base/ir/ir_model.py
+++ b/openerp/addons/base/ir/ir_model.py
@@ -151,7 +151,7 @@ class ir_model(osv.osv):
             if result and result[0] == 'v':
                 cr.execute('DROP view %s' % (model_pool._table,))
             elif result and result[0] == 'r':
-                cr.execute('DROP TABLE %s' % (model_pool._table,))
+                cr.execute('DROP TABLE %s CASCADE' % (model_pool._table,))
         return True
 
     def unlink(self, cr, user, ids, context=None):
@@ -312,6 +312,14 @@ class ir_model_fields(osv.osv):
             if column_name and (result and result[0] == 'r'):
                 cr.execute('ALTER table "%s" DROP column "%s" cascade' % (model._table, field.name))
             model._columns.pop(field.name, None)
+
+            # remove m2m relation table for custom fields
+            # we consider the m2m relation is only one way as it's not possible
+            # to specify the relation table in the interface for custom fields
+            # TODO master: maybe use ir.model.relations for custom fields
+            if field.state == 'manual' and field.ttype == 'many2many':
+                rel_name = self.pool[field.model]._all_columns[field.name].column._rel
+                cr.execute('DROP table "%s"' % (rel_name))
         return True
 
     def unlink(self, cr, user, ids, context=None):
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index 6bf532468462865788c6caaf74c0142e4c878abb..29694c041d44669035dd10a6b5e90aae8cfea800 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -3072,7 +3072,10 @@ class BaseModel(object):
 
     def _m2m_raise_or_create_relation(self, cr, f):
         m2m_tbl, col1, col2 = f._sql_names(self)
-        self._save_relation_table(cr, m2m_tbl)
+        # do not create relations for custom fields as they do not belong to a module
+        # they will be automatically removed when dropping the corresponding ir.model.field
+        if not f.string.startswith('x_'):
+            self._save_relation_table(cr, m2m_tbl)
         cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (m2m_tbl,))
         if not cr.dictfetchall():
             if f._obj not in self.pool: