diff --git a/.bzrignore b/.bzrignore
deleted file mode 100644
index 86a1881981f547b45b146212e7f29abbe1e151fa..0000000000000000000000000000000000000000
--- a/.bzrignore
+++ /dev/null
@@ -1,15 +0,0 @@
-.*
-*.egg-info
-*.orig
-*.vim
-build/
-RE:^bin/
-RE:^dist/
-RE:^include/
-
-RE:^share/
-RE:^man/
-RE:^lib/
-
-RE:^addons/\w+/doc/_build/
-RE:^.*?/node_modules
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..7828a605ef0eba8ebcce468bc2ea96613de27cc0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+# sphinx build directories
+_build/
+
+# dotfiles
+.*
+!.gitignore
+# compiled python files
+*.py[co]
+# setup.py egg_info
+*.egg-info
+# emacs backup files
+*~
+# hg stuff
+*.orig
+status
+# odoo filestore
+openerp/filestore
+# generated for windows installer?
+install/win32/*.bat
+install/win32/meta.py
+
+# various virtualenv
+/bin/
+/build/
+/dist/
+/include/
+/lib/
+/man/
+/share/
+/src/
diff --git a/addons/delivery/sale.py b/addons/delivery/sale.py
index c5d032ca8a8a056ea330c9b8cd8df57bbdce3de1..93072b3d02d866e09e0cc9fc207fae0c4d988d5e 100644
--- a/addons/delivery/sale.py
+++ b/addons/delivery/sale.py
@@ -74,7 +74,7 @@ class sale_order(osv.Model):
             if not grid_id:
                 raise osv.except_osv(_('No Grid Available!'), _('No grid matching for this carrier!'))
 
-            if order.state != 'draft':
+            if order.state not in ('draft', 'sent'):
                 raise osv.except_osv(_('Order not in Draft State!'), _('The order state have to be draft to add delivery lines.'))
 
             grid = grid_obj.browse(cr, uid, grid_id, context=context)
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index fe96029234423b092c3c68d890ffaeacf487bdeb..a264d58df7e4172b5db313ffda17e1e983ca9617 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -1132,7 +1132,14 @@ class mail_thread(osv.AbstractModel):
         body = u''
         if save_original:
             attachments.append(('original_email.eml', message.as_string()))
-        if not message.is_multipart() or 'text/' in message.get('content-type', ''):
+
+        # Be careful, content-type may contain tricky content like in the
+        # following example so test the MIME type with startswith()
+        #
+        # Content-Type: multipart/related;
+        #   boundary="_004_3f1e4da175f349248b8d43cdeb9866f1AMSPR06MB343eurprd06pro_";
+        #   type="text/html"
+        if not message.is_multipart() or message.get('content-type', '').startswith("text/"):
             encoding = message.get_content_charset()
             body = message.get_payload(decode=True)
             body = tools.ustr(body, encoding, errors='replace')
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 6497ec0045c8ca9f838d1c59e1d2f41143b1a994..bf5a95d7abeef09997da89c2cf3d8ac6bad8f35a 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -503,6 +503,8 @@ class purchase_order(osv.osv):
         if not len(ids):
             return False
         self.write(cr, uid, ids, {'state':'draft','shipped':0})
+        for purchase in self.browse(cr, uid, ids, context=context):
+            self.pool['purchase.order.line'].write(cr, uid, [l.id for l in  purchase.order_line], {'state': 'draft'})
         for p_id in ids:
             # Deleting the existing instance of workflow for PO
             self.delete_workflow(cr, uid, [p_id]) # TODO is it necessary to interleave the calls?
@@ -598,6 +600,8 @@ class purchase_order(osv.osv):
                         _('You must first cancel all receptions related to this purchase order.'))
             self.pool.get('account.invoice') \
                 .signal_invoice_cancel(cr, uid, map(attrgetter('id'), purchase.invoice_ids))
+            self.pool['purchase.order.line'].write(cr, uid, [l.id for l in  purchase.order_line],
+                    {'state': 'cancel'})
         self.write(cr,uid,ids,{'state':'cancel'})
 
         self.signal_purchase_cancel(cr, uid, ids)
@@ -908,6 +912,8 @@ class purchase_order_line(osv.osv):
     def unlink(self, cr, uid, ids, context=None):
         procurement_ids_to_cancel = []
         for line in self.browse(cr, uid, ids, context=context):
+            if line.state not in ['draft', 'cancel']:
+                raise osv.except_osv(_('Invalid Action!'), _('Cannot delete a purchase order line which is in state \'%s\'.') %(line.state,))
             if line.move_dest_id:
                 procurement_ids_to_cancel.extend(procurement.id for procurement in line.move_dest_id.procurements)
         if procurement_ids_to_cancel:
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 0664b6521c139c6010761644a44450015c6431d6..8e895190295e37bd5d31f023c3c796ad31fe9342 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -515,14 +515,18 @@ class sale_order(osv.osv):
             if grouped:
                 res = self._make_invoice(cr, uid, val[0][0], reduce(lambda x, y: x + y, [l for o, l in val], []), context=context)
                 invoice_ref = ''
+                origin_ref = ''
                 for o, l in val:
-                    invoice_ref += o.name + '|'
+                    invoice_ref += (o.client_order_ref or o.name) + '|'
+                    origin_ref += (o.origin or o.name) + '|'
                     self.write(cr, uid, [o.id], {'state': 'progress'})
                     cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (o.id, res))
                 #remove last '|' in invoice_ref
-                if len(invoice_ref) >= 1: 
+                if len(invoice_ref) >= 1:
                     invoice_ref = invoice_ref[:-1]
-                invoice.write(cr, uid, [res], {'origin': invoice_ref, 'name': invoice_ref})
+                if len(origin_ref) >= 1:
+                    origin_ref = origin_ref[:-1]
+                invoice.write(cr, uid, [res], {'origin': origin_ref, 'name': invoice_ref})
             else:
                 for order, il in val:
                     res = self._make_invoice(cr, uid, order, il, context=context)
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index efb8582e9cb1bc8c934bea8b62df011cc0adadf4..c59fbc31da1c95ad797862226d677aaa73298343 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -2395,7 +2395,7 @@ class stock_move(osv.osv):
                 picking_ids.append(move.picking_id.id)
             if move.move_dest_id.id and (move.state != 'done'):
                 # Downstream move should only be triggered if this move is the last pending upstream move
-                other_upstream_move_ids = self.search(cr, uid, [('id','!=',move.id),('state','not in',['done','cancel']),
+                other_upstream_move_ids = self.search(cr, uid, [('id','not in',move_ids),('state','not in',['done','cancel']),
                                             ('move_dest_id','=',move.move_dest_id.id)], context=context)
                 if not other_upstream_move_ids:
                     self.write(cr, uid, [move.id], {'move_history_ids': [(4, move.move_dest_id.id)]})
diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv
index 25df6e117d0a7ccc4d25ef88b2e22a71252942a9..0fd8b548cb09528c5615455b8a40e1acad78de63 100644
--- a/openerp/addons/base/security/ir.model.access.csv
+++ b/openerp/addons/base/security/ir.model.access.csv
@@ -108,6 +108,7 @@
 "access_multi_company_default manager","multi_company_default Manager","model_multi_company_default","group_erp_manager",1,1,1,1
 "access_ir_filter all","ir_filters all","model_ir_filters",,1,1,1,1
 "access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
+"access_ir_config_parameter_system","ir_config_parameter_system","model_ir_config_parameter","group_system",1,1,1,1
 "access_ir_mail_server","ir_mail_server","model_ir_mail_server","group_system",1,1,1,1
 "access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0
 "access_ir_needaction_mixin","ir_needaction_mixin","model_ir_needaction_mixin",,1,1,1,1