diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 75940d2d83d4b464e39c65cdb8a45b21cf26c1c1..1ddab4bece9385fd17026e888eb7ec8f5ff4d3fe 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -26,6 +26,9 @@ from openerp.report import report_sxw
 
 class account_bank_statement(osv.osv):
     def create(self, cr, uid, vals, context=None):
+        if vals.get('name', '/') == '/':
+            journal_id = vals.get('journal_id', self._default_journal_id(cr, uid, context=context))
+            vals['name'] = self._compute_default_statement_name(cr, uid, journal_id, context=context)
         if 'line_ids' in vals:
             for idx, line in enumerate(vals['line_ids']):
                 line[2]['sequence'] = idx + 1
@@ -65,17 +68,14 @@ class account_bank_statement(osv.osv):
             return periods[0]
         return False
 
-    def _compute_default_statement_name(self, cr, uid, context=None):
+    def _compute_default_statement_name(self, cr, uid, journal_id, context=None):
         if context is None:
             context = {}
         obj_seq = self.pool.get('ir.sequence')
-        default_journal_id = self._default_journal_id(cr, uid, context=context)
-        if default_journal_id != False:
-            period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context)
-            context['fiscalyear_id'] = period.fiscalyear_id.id
-            journal = self.pool.get('account.journal').browse(cr, uid, default_journal_id, None)
-            return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context)
-        return obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=context)
+        period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context)
+        context['fiscalyear_id'] = period.fiscalyear_id.id
+        journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None)
+        return obj_seq.next_by_id(cr, uid, journal.sequence_id.id, context=context)
 
     def _currency(self, cursor, user, ids, name, args, context=None):
         res = {}
@@ -150,7 +150,7 @@ class account_bank_statement(osv.osv):
     }
 
     _defaults = {
-        'name': _compute_default_statement_name,
+        'name': '/', 
         'date': fields.date.context_today,
         'state': 'draft',
         'journal_id': _default_journal_id,
@@ -213,11 +213,8 @@ class account_bank_statement(osv.osv):
 
     def _get_counter_part_account(sefl, cr, uid, st_line, context=None):
         """Retrieve the account to use in the counterpart move.
-           This method may be overridden to implement custom move generation (making sure to
-           call super() to establish a clean extension chain).
 
-           :param browse_record st_line: account.bank.statement.line record to
-                  create the move from.
+           :param browse_record st_line: account.bank.statement.line record to create the move from.
            :return: int/long of the account.account to use as counterpart
         """
         if st_line.amount >= 0:
@@ -226,26 +223,19 @@ class account_bank_statement(osv.osv):
 
     def _get_counter_part_partner(sefl, cr, uid, st_line, context=None):
         """Retrieve the partner to use in the counterpart move.
-           This method may be overridden to implement custom move generation (making sure to
-           call super() to establish a clean extension chain).
 
-           :param browse_record st_line: account.bank.statement.line record to
-                  create the move from.
+           :param browse_record st_line: account.bank.statement.line record to create the move from.
            :return: int/long of the res.partner to use as counterpart
         """
         return st_line.partner_id and st_line.partner_id.id or False
 
     def _prepare_bank_move_line(self, cr, uid, st_line, move_id, amount, company_currency_id, context=None):
         """Compute the args to build the dict of values to create the counter part move line from a
-           statement line by calling the _prepare_move_line_vals. This method may be
-           overridden to implement custom move generation (making sure to call super() to
-           establish a clean extension chain).
+           statement line by calling the _prepare_move_line_vals. 
 
-           :param browse_record st_line: account.bank.statement.line record to
-                  create the move from.
+           :param browse_record st_line: account.bank.statement.line record to create the move from.
            :param int/long move_id: ID of the account.move to link the move line
            :param float amount: amount of the move line
-           :param int/long account_id: ID of account to use as counter part
            :param int/long company_currency_id: ID of currency of the concerned company
            :return: dict of value to create() the bank account.move.line
         """
@@ -258,7 +248,6 @@ class account_bank_statement(osv.osv):
         if st_line.statement_id.currency.id != company_currency_id:
             amt_cur = st_line.amount
             cur_id = st_line.currency_id or st_line.statement_id.currency.id
-        # TODO : FIXME the amount should be in the journal currency
         if st_line.currency_id and st_line.amount_currency:
             amt_cur = st_line.amount_currency
             cur_id = st_line.currency_id.id
@@ -269,9 +258,7 @@ class account_bank_statement(osv.osv):
     def _prepare_move_line_vals(self, cr, uid, st_line, move_id, debit, credit, currency_id=False,
                 amount_currency=False, account_id=False, partner_id=False, context=None):
         """Prepare the dict of values to create the move line from a
-           statement line. All non-mandatory args will replace the default computed one.
-           This method may be overridden to implement custom move generation (making sure to
-           call super() to establish a clean extension chain).
+           statement line.
 
            :param browse_record st_line: account.bank.statement.line record to
                   create the move from.
@@ -342,21 +329,29 @@ class account_bank_statement(osv.osv):
                 move_ids.append(st_line.journal_entry_id.id)
             self.pool.get('account.move').post(cr, uid, move_ids, context=context)
             self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context)
+        self.link_bank_to_partner(cr, uid, ids, context=context)
         return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
 
     def button_cancel(self, cr, uid, ids, context=None):
-        done = []
         account_move_obj = self.pool.get('account.move')
+        reconcile_pool = self.pool.get('account.move.reconcile')
+        move_line_pool = self.pool.get('account.move.line')
+        move_ids = []
         for st in self.browse(cr, uid, ids, context=context):
-            if st.state=='draft':
-                continue
-            move_ids = []
             for line in st.line_ids:
-                move_ids += [x.id for x in line.move_ids]
+                if line.journal_entry_id:
+                    move_ids.append(line.journal_entry_id.id)
+                    for aml in line.journal_entry_id.line_id:
+                        if aml.reconcile_id:
+                            move_lines = [l.id for l in aml.reconcile_id.line_id]
+                            move_lines.remove(aml.id)
+                            reconcile_pool.unlink(cr, uid, [aml.reconcile_id.id], context=context)
+                            if len(move_lines) >= 2:
+                                move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto', context=context)
+        if move_ids:
             account_move_obj.button_cancel(cr, uid, move_ids, context=context)
             account_move_obj.unlink(cr, uid, move_ids, context)
-            done.append(st.id)
-        return self.write(cr, uid, done, {'state':'draft'}, context=context)
+        return self.write(cr, uid, ids, {'state': 'draft'}, context=context)
 
     def _compute_balance_end_real(self, cr, uid, journal_id, context=None):
         res = False
@@ -417,18 +412,35 @@ class account_bank_statement(osv.osv):
 
     def number_of_lines_reconciled(self, cr, uid, id, context=None):
         bsl_obj = self.pool.get('account.bank.statement.line')
-        return bsl_obj.search_count(cr, uid, [('statement_id','=',id), ('journal_entry_id','!=',False)], context=context)
-
+        return bsl_obj.search_count(cr, uid, [('statement_id', '=', id), ('journal_entry_id', '!=', False)], context=context)
+        
     def get_format_currency_js_function(self, cr, uid, id, context=None):
         """ Returns a string that can be used to instanciate a javascript function.
-            That function formats a number according to the statement's journal currency """
+            That function formats a number according to the statement line's currency or the statement currency"""
         company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
-        currency_obj = id and self.browse(cr, uid, id, context=context).journal_id.currency or company_currency
+        st = id and self.browse(cr, uid, id, context=context)
+        if not st:
+            return
+        statement_currency = st.journal_id.currency or company_currency
         digits = 2 # TODO : from currency_obj
-        if currency_obj.position == 'after':
-            return "return amount.toFixed("+str(digits)+") + ' "+currency_obj.symbol+"';"
-        elif currency_obj.position == 'before':
-            return "return '"+currency_obj.symbol+" ' + amount.toFixed("+str(digits)+");"
+        function = ""
+        done_currencies = []
+        for st_line in st.line_ids:
+            st_line_currency = st_line.currency_id or statement_currency
+            if st_line_currency.id not in done_currencies:
+                if st_line_currency.position == 'after':
+                    return_str = "return amount.toFixed(" + str(digits) + ") + ' " + st_line_currency.symbol + "';"
+                else:
+                    return_str = "return '" + st_line_currency.symbol + " ' + amount.toFixed(" + str(digits) + ");"
+                function += "if (currency_id === " + str(st_line_currency.id) + "){ " + return_str + " }"
+                done_currencies.append(st_line_currency.id)
+        return function
+
+    def link_bank_to_partner(self, cr, uid, ids, context=None):
+        for statement in self.browse(cr, uid, ids, context=context):
+            for st_line in statement.line_ids:
+                if st_line.bank_account_id and st_line.partner_id and st_line.bank_account_id.partner_id.id != st_line.partner_id.id:
+                    self.pool.get('res.partner.bank').write(cr, uid, [st_line.bank_account_id.id], {'partner_id': st_line.partner_id.id}, context=context)
 
 class account_bank_statement_line(osv.osv):
 
@@ -444,35 +456,40 @@ class account_bank_statement_line(osv.osv):
             }
             for mv_line in reconciliation_data['reconciliation_proposition']:
                 mv_line_ids_selected.append(mv_line['id'])
-            ret.append(reconciliation_data);
-        
+            ret.append(reconciliation_data)
+
         # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines
-        for reconciliation_data in ret:
-            if not reconciliation_data['st_line']['has_no_partner']:
-                if self.get_move_lines_counterparts(cr, uid, reconciliation_data['st_line']['id'], excluded_ids=mv_line_ids_selected, count=True, context=context) == 0:
-                    reconciliation_data['st_line']['no_match'] = True
+        #for reconciliation_data in ret:
+        #    if not reconciliation_data['st_line']['has_no_partner']:
+        #        st_line = self.browse(cr, uid, reconciliation_data['st_line']['id'], context=context)
+        #        if not self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=mv_line_ids_selected, count=True, context=context):
+        #            reconciliation_data['st_line']['no_match'] = True
         return ret
 
     def get_statement_line_for_reconciliation(self, cr, uid, id, context=None):
         """ Returns the data required by the bank statement reconciliation use case """
         line = self.browse(cr, uid, id, context=context)
         statement_currency = line.journal_id.currency or line.journal_id.company_id.currency_id
+        amount = line.amount
         rml_parser = report_sxw.rml_parse(cr, uid, 'statement_line_widget', context=context)
         amount_str = line.amount > 0 and line.amount or -line.amount
         amount_str = rml_parser.formatLang(amount_str, currency_obj=statement_currency)
         amount_currency_str = ""
         if line.amount_currency and line.currency_id:
-            amount_currency_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id)
+            amount_currency_str = amount_str
+            amount_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id)
+            amount = line.amount_currency
 
-        dict = {
+        data = {
             'id': line.id,
             'ref': line.ref,
             'note': line.note or "",
             'name': line.name,
             'date': line.date,
-            'amount': line.amount,
+            'amount': amount,
             'amount_str': amount_str,
-            'no_match': self.get_move_lines_counterparts(cr, uid, id, count=True, context=context) == 0 and line.partner_id.id,
+            'currency_id': line.currency_id.id or statement_currency.id,
+            'no_match': self.get_move_lines_counterparts(cr, uid, line, count=True, context=context) == 0,
             'partner_id': line.partner_id.id,
             'statement_id': line.statement_id.id,
             'account_code': line.journal_id.default_debit_account_id.code,
@@ -482,93 +499,116 @@ class account_bank_statement_line(osv.osv):
             'has_no_partner': not line.partner_id.id,
         }
         if line.partner_id.id:
-            if line.amount > 0:
-                dict['open_balance_account_id'] = line.partner_id.property_account_receivable.id
-            else:
-                dict['open_balance_account_id'] = line.partner_id.property_account_payable.id
-        return dict
+            data['open_balance_account_id'] = line.partner_id.property_account_payable.id
+            if amount > 0:
+                data['open_balance_account_id'] = line.partner_id.property_account_receivable.id
+        return data
+
+    def search_structured_com(self, cr, uid, st_line, context=None):
+        if not st_line.ref:
+            return
+        domain = [('ref', '=', st_line.ref)]
+        if st_line.partner_id:
+            domain += [('partner_id', '=', st_line.partner_id.id)]
+        ids = self.pool.get('account.move.line').search(cr, uid, domain, limit=1, context=context)
+        return ids and ids[0] or False
 
     def get_reconciliation_proposition(self, cr, uid, id, excluded_ids=[], context=None):
         """ Returns move lines that constitute the best guess to reconcile a statement line. """
         st_line = self.browse(cr, uid, id, context=context)
         company_currency = st_line.journal_id.company_id.currency_id.id
         statement_currency = st_line.journal_id.currency.id or company_currency
-
         # either use the unsigned debit/credit fields or the signed amount_currency field
         sign = 1
         if statement_currency == company_currency:
+            amount_field = 'credit'
             if st_line.amount > 0:
                 amount_field = 'debit'
-            else:
-                amount_field = 'credit'
         else:
             amount_field = 'amount_currency'
             if st_line.amount < 0:
                 sign = -1
 
+        # look for structured communication
+        exact_match_id = self.search_structured_com(cr, uid, st_line, context=context)
+        if exact_match_id:
+            return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context)
+        #we don't propose anything if there is no partner detected
+        if not st_line.partner_id.id:
+            return []
         # look for exact match
-        exact_match_id = self.get_move_lines_counterparts(cr, uid, id, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field,'=',(sign*st_line.amount))])
+        exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))])
         if exact_match_id:
             return exact_match_id
 
         # select oldest move lines
         if sign == -1:
-            mv_lines = self.get_move_lines_counterparts(cr, uid, id, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field,'<',0)])
+            mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '<', 0)])
         else:
-            mv_lines = self.get_move_lines_counterparts(cr, uid, id, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field,'>',0)])
+            mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '>', 0)])
         ret = []
         total = 0
         # get_move_lines_counterparts inverts debit and credit
         amount_field = 'debit' if amount_field == 'credit' else 'credit'
         for line in mv_lines:
-            if total + line[amount_field] <= st_line.amount:
+            if total + line[amount_field] <= abs(st_line.amount):
                 ret.append(line)
                 total += line[amount_field]
-            else:
+            if total >= abs(st_line.amount):
                 break
-
         return ret
 
-    def get_move_lines_counterparts(self, cr, uid, id, excluded_ids=[], str="", offset=0, limit=None, count=False, additional_domain=[], context=None):
+    def get_move_lines_counterparts_id(self, cr, uid, st_line_id, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None):
+        st_line = self.browse(cr, uid, st_line_id, context=context)
+        return self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids, filter_str, offset, limit, count, additional_domain, context=context)
+
+    def get_move_lines_counterparts(self, cr, uid, st_line, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None):
         """ Find the move lines that could be used to reconcile a statement line and returns the counterpart that could be created to reconcile them
             If count is true, only returns the count.
 
-            :param integer id: the id of the statement line
+            :param st_line: the browse record of the statement line
             :param integers list excluded_ids: ids of move lines that should not be fetched
-            :param string str: string to filter lines
+            :param string filter_str: string to filter lines
             :param integer offset: offset of the request
             :param integer limit: number of lines to fetch
             :param boolean count: just return the number of records
             :param tuples list domain: additional domain restrictions
         """
-        if context is None:
-            context = {}
-
-        rml_parser = report_sxw.rml_parse(cr, uid, 'statement_line_counterpart_widget', context=context)
-        st_line = self.browse(cr, uid, id, context=context)
-        company_currency = st_line.journal_id.company_id.currency_id
-        statement_currency = st_line.journal_id.currency or company_currency
         mv_line_pool = self.pool.get('account.move.line')
-        currency_obj = self.pool.get('res.currency')
 
         domain = additional_domain + [
-            ('partner_id', '=', st_line.partner_id.id),
             ('reconcile_id', '=', False),
-            ('state','=','valid'),
-            '|',('account_id.type', '=', 'receivable'),
-            ('account_id.type', '=', 'payable'), #Let the front-end warn the user if he tries to mix payable and receivable in the same reconciliation
+            ('state', '=', 'valid'),
         ]
+        if st_line.partner_id.id:
+            domain += [('partner_id', '=', st_line.partner_id.id),
+                '|', ('account_id.type', '=', 'receivable'),
+                ('account_id.type', '=', 'payable')]
+        else:
+            domain += [('account_id.reconcile', '=', True)]
+            #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')]
         if excluded_ids:
             domain.append(('id', 'not in', excluded_ids))
-        if str:
-            domain += ['|', ('move_id.name', 'ilike', str), ('move_id.ref', 'ilike', str)]
+        if filter_str:
+            if not st_line.partner_id:
+                domain += [ '|', ('partner_id.name', 'ilike', filter_str)]
+            domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)]
+        line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context)
+        return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context)
+
+    def make_counter_part_lines(self, cr, uid, st_line, line_ids, count=False, context=None):
+        if context is None:
+            context = {}
+        mv_line_pool = self.pool.get('account.move.line')
+        currency_obj = self.pool.get('res.currency')
+        company_currency = st_line.journal_id.company_id.currency_id
+        statement_currency = st_line.journal_id.currency or company_currency
+        rml_parser = report_sxw.rml_parse(cr, uid, 'statement_line_counterpart_widget', context=context)
         #partially reconciled lines can be displayed only once
         reconcile_partial_ids = []
-        ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context)
-
         if count:
             nb_lines = 0
-            for line in mv_line_pool.browse(cr, uid, ids, context=context):
+            for line in mv_line_pool.browse(cr, uid, line_ids, context=context):
                 if line.reconcile_partial_id and line.reconcile_partial_id.id in reconcile_partial_ids:
                     continue
                 nb_lines += 1
@@ -577,7 +617,7 @@ class account_bank_statement_line(osv.osv):
             return nb_lines
         else:
             ret = []
-            for line in mv_line_pool.browse(cr, uid, ids, context=context):
+            for line in mv_line_pool.browse(cr, uid, line_ids, context=context):
                 if line.reconcile_partial_id and line.reconcile_partial_id.id in reconcile_partial_ids:
                     continue
                 amount_currency_str = ""
@@ -595,8 +635,12 @@ class account_bank_statement_line(osv.osv):
                     'period_name': line.period_id.name,
                     'journal_name': line.journal_id.name,
                     'amount_currency_str': amount_currency_str,
+                    'partner_id': line.partner_id.id,
+                    'partner_name': line.partner_id.name,
+                    'has_no_partner': not bool(st_line.partner_id.id),
                 }
-                if statement_currency.id != company_currency.id and line.currency_id and line.currency_id.id == statement_currency.id:
+                st_line_currency = st_line.currency_id or statement_currency
+                if st_line.currency_id and line.currency_id and line.currency_id.id == st_line.currency_id.id:
                     if line.amount_residual_currency < 0:
                         ret_line['debit'] = 0
                         ret_line['credit'] = -line.amount_residual_currency
@@ -613,21 +657,46 @@ class account_bank_statement_line(osv.osv):
                         ret_line['credit'] = line.amount_residual if line.debit != 0 else 0
                     ctx = context.copy()
                     ctx.update({'date': st_line.date})
-                    ret_line['debit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, ret_line['debit'], context=ctx)
-                    ret_line['credit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, ret_line['credit'], context=ctx)
-                ret_line['debit_str'] = rml_parser.formatLang(ret_line['debit'], currency_obj=statement_currency)
-                ret_line['credit_str'] = rml_parser.formatLang(ret_line['credit'], currency_obj=statement_currency)
+                    ret_line['debit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, ret_line['debit'], context=ctx)
+                    ret_line['credit'] = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, ret_line['credit'], context=ctx)
+                ret_line['debit_str'] = rml_parser.formatLang(ret_line['debit'], currency_obj=st_line_currency)
+                ret_line['credit_str'] = rml_parser.formatLang(ret_line['credit'], currency_obj=st_line_currency)
                 ret.append(ret_line)
                 if line.reconcile_partial_id:
                     reconcile_partial_ids.append(line.reconcile_partial_id.id)
             return ret
 
+    def get_currency_rate_line(self, cr, uid, st_line, currency_diff, move_id, context=None):
+        if currency_diff < 0:
+            account_id = st_line.company_id.expense_currency_exchange_account_id.id
+            if not account_id:
+                raise osv.except_osv(_('Insufficient Configuration!'), _("You should configure the 'Loss Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
+        else:
+            account_id = st_line.company_id.income_currency_exchange_account_id.id
+            if not account_id:
+                raise osv.except_osv(_('Insufficient Configuration!'), _("You should configure the 'Gain Exchange Rate Account' in the accounting settings, to manage automatically the booking of accounting entries related to differences between exchange rates."))
+        return {
+            'move_id': move_id,
+            'name': _('change') + ': ' + (st_line.name or '/'),
+            'period_id': st_line.statement_id.period_id.id,
+            'journal_id': st_line.journal_id.id,
+            'partner_id': st_line.partner_id.id,
+            'company_id': st_line.company_id.id,
+            'statement_id': st_line.statement_id.id,
+            'debit': currency_diff < 0 and -currency_diff or 0,
+            'credit': currency_diff > 0 and currency_diff or 0,
+            'date': st_line.date,
+            'account_id': account_id
+            }
+
     def process_reconciliation(self, cr, uid, id, mv_line_dicts, context=None):
         """ Creates a move line for each item of mv_line_dicts and for the statement line. Reconcile a new move line with its counterpart_move_line_id if specified. Finally, mark the statement line as reconciled by putting the newly created move id in the column journal_entry_id.
 
             :param int id: id of the bank statement line
             :param list of dicts mv_line_dicts: move lines to create. If counterpart_move_line_id is specified, reconcile with it
         """
+        if context is None:
+            context = {}
         st_line = self.browse(cr, uid, id, context=context)
         company_currency = st_line.journal_id.company_id.currency_id
         statement_currency = st_line.journal_id.currency or company_currency
@@ -637,7 +706,7 @@ class account_bank_statement_line(osv.osv):
         currency_obj = self.pool.get('res.currency')
 
         # Checks
-        if st_line.journal_entry_id.id != False:
+        if st_line.journal_entry_id.id:
             raise osv.except_osv(_('Error!'), _('The bank statement line was already reconciled.'))
         for mv_line_dict in mv_line_dicts:
             for field in ['debit', 'credit', 'amount_currency']:
@@ -657,37 +726,50 @@ class account_bank_statement_line(osv.osv):
         amount = currency_obj.compute(cr, uid, st_line.statement_id.currency.id, company_currency.id, st_line.amount, context=context)
         bank_st_move_vals = bs_obj._prepare_bank_move_line(cr, uid, st_line, move_id, amount, company_currency.id, context=context)
         aml_obj.create(cr, uid, bank_st_move_vals, context=context)
-        st_line_currency_rate = bank_st_move_vals['amount_currency'] and statement_currency.id == company_currency.id and (bank_st_move_vals['amount_currency'] / st_line.amount) or False
-        st_line_currency = bank_st_move_vals['currency_id']
         # Complete the dicts
-        st_line_statement_id = st_line.statement_id.id
-        st_line_journal_id = st_line.journal_id.id
-        st_line_partner_id = st_line.partner_id.id
-        st_line_company_id = st_line.company_id.id
-        st_line_period_id = st_line.statement_id.period_id.id
+        st_line_currency = st_line.currency_id or statement_currency
+        st_line_currency_rate = st_line.currency_id and statement_currency.id == company_currency.id and (st_line.amount_currency / st_line.amount) or False
+        to_create = []
         for mv_line_dict in mv_line_dicts:
             mv_line_dict['ref'] = move_name
             mv_line_dict['move_id'] = move_id
-            mv_line_dict['period_id'] = st_line_period_id
-            mv_line_dict['journal_id'] = st_line_journal_id
-            mv_line_dict['partner_id'] = st_line_partner_id
-            mv_line_dict['company_id'] = st_line_company_id
-            mv_line_dict['statement_id'] = st_line_statement_id
+            mv_line_dict['period_id'] = st_line.statement_id.period_id.id
+            mv_line_dict['journal_id'] = st_line.journal_id.id
+            mv_line_dict['company_id'] = st_line.company_id.id
+            mv_line_dict['statement_id'] = st_line.statement_id.id
             if mv_line_dict.get('counterpart_move_line_id'):
                 mv_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
                 mv_line_dict['account_id'] = mv_line.account_id.id
-            if statement_currency.id != company_currency.id:
+            if st_line_currency.id != company_currency.id:
                 mv_line_dict['amount_currency'] = mv_line_dict['debit'] - mv_line_dict['credit']
-                mv_line_dict['currency_id'] = statement_currency.id
-                mv_line_dict['debit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'])
-                mv_line_dict['credit'] = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'])
-            elif st_line_currency and st_line_currency_rate:
-                mv_line_dict['amount_currency'] = self.pool.get('res.currency').round(cr, uid, st_line.currency_id, (mv_line_dict['debit'] - mv_line_dict['credit']) * st_line_currency_rate) 
-                mv_line_dict['currency_id'] = st_line_currency
-
+                mv_line_dict['currency_id'] = st_line_currency.id
+                if st_line.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate:
+                    debit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['debit'] / st_line_currency_rate)
+                    credit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['credit'] / st_line_currency_rate)
+                else:
+                    debit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=context)
+                    credit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=context)
+                if mv_line_dict.get('counterpart_move_line_id'):
+                    #post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line
+                    ctx = context.copy()
+                    ctx['date'] = mv_line.date
+                    debit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx)
+                    credit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx)
+                    mv_line_dict['credit'] = credit_at_old_rate
+                    mv_line_dict['debit'] = debit_at_old_rate
+                    if debit_at_old_rate - debit_at_current_rate:
+                        currency_diff = debit_at_current_rate - debit_at_old_rate
+                        to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
+                    if credit_at_old_rate - credit_at_current_rate:
+                        currency_diff = credit_at_current_rate - credit_at_old_rate
+                        to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
+                else:
+                    mv_line_dict['debit'] = debit_at_current_rate
+                    mv_line_dict['credit'] = credit_at_current_rate
+            to_create.append(mv_line_dict)
         # Create move lines
         move_line_pairs_to_reconcile = []
-        for mv_line_dict in mv_line_dicts:
+        for mv_line_dict in to_create:
             counterpart_move_line_id = None # NB : this attribute is irrelevant for aml_obj.create() and needs to be removed from the dict
             if mv_line_dict.get('counterpart_move_line_id'):
                 counterpart_move_line_id = mv_line_dict['counterpart_move_line_id']
@@ -723,7 +805,7 @@ class account_bank_statement_line(osv.osv):
         'bank_account_id': fields.many2one('res.partner.bank','Bank Account'),
         'statement_id': fields.many2one('account.bank.statement', 'Statement', select=True, required=True, ondelete='cascade'),
         'journal_id': fields.related('statement_id', 'journal_id', type='many2one', relation='account.journal', string='Journal', store=True, readonly=True),
-        'ref': fields.char('Reference', size=32),
+        'ref': fields.char('Structured Communication'),
         'note': fields.text('Notes'),
         'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of bank statement lines."),
         'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index de75c7079b3b00a7960d13129ee3dc6c772362e6..eb705b429952251fee09fee2e00da53c22a4a6fd 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -127,8 +127,8 @@ class account_move_line(osv.osv):
 
             if move_line.reconcile_id:
                 continue
-            if not move_line.account_id.type in ('payable', 'receivable'):
-                #this function does not suport to be used on move lines not related to payable or receivable accounts
+            if not move_line.account_id.reconcile:
+                #this function does not suport to be used on move lines not related to a reconcilable account
                 continue
 
             if move_line.currency_id:
diff --git a/addons/account/demo/account_bank_statement.xml b/addons/account/demo/account_bank_statement.xml
index 693dbc876b5a015a83d78185f838d3687e947180..b79d8b95cd66002af68285bda158133790f44568 100644
--- a/addons/account/demo/account_bank_statement.xml
+++ b/addons/account/demo/account_bank_statement.xml
@@ -15,7 +15,7 @@
             <field name="balance_end_real" eval="3707.58"/>
         </record>
         <record id="demo_bank_statement_line_1" model="account.bank.statement.line">
-            <field name="ref">001</field>
+            <field name="ref"></field>
             <field name="statement_id" ref="demo_bank_statement_1"/>
             <field name="sequence" eval="1"/>
             <field name="company_id" ref="base.main_company"/>
@@ -26,7 +26,7 @@
             <field name="partner_id" ref="base.res_partner_9"/>
         </record>
         <record id="demo_bank_statement_line_2" model="account.bank.statement.line">
-            <field name="ref">002</field>
+            <field name="ref">SAJ2014002</field>
             <field name="statement_id" ref="demo_bank_statement_1"/>
             <field name="sequence" eval="2"/>
             <field name="company_id" ref="base.main_company"/>
@@ -37,7 +37,7 @@
             <field name="partner_id" ref="base.res_partner_9"/>
         </record>
         <record id="demo_bank_statement_line_3" model="account.bank.statement.line">
-            <field name="ref">003</field>
+            <field name="ref"></field>
             <field name="statement_id" ref="demo_bank_statement_1"/>
             <field name="sequence" eval="3"/>
             <field name="company_id" ref="base.main_company"/>
@@ -47,7 +47,7 @@
             <field name="date" eval="time.strftime('%Y')+'-01-01'"/>
         </record>
         <record id="demo_bank_statement_line_4" model="account.bank.statement.line">
-            <field name="ref">004</field>
+            <field name="ref"></field>
             <field name="statement_id" ref="demo_bank_statement_1"/>
             <field name="sequence" eval="4"/>
             <field name="company_id" ref="base.main_company"/>
diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.css b/addons/account/static/src/css/account_bank_statement_reconciliation.css
index 626d1f32dab7fc2c674c04fbeb3c8933ffd4e0e1..05caeab26559cbd81f7bc262487e7becffa78a9d 100644
--- a/addons/account/static/src/css/account_bank_statement_reconciliation.css
+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.css
@@ -120,8 +120,6 @@
         cursor: pointer; }
     .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_match:not(.no_partner) .toggle_match {
       visibility: hidden !important; }
-    .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .partner_name, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line.no_partner .line_open_balance {
-      display: none !important; }
     .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line > table > tbody > tr:nth-child(1) > td table {
       margin-bottom: 10px; }
     .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child {
@@ -202,10 +200,6 @@
         cursor: pointer; }
     .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td:nth-child(6) {
       border-left: 1px solid black; }
-    .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(5) {
-      border-top: 1px solid black; }
-    .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.initial_line > td:nth-child(6) {
-      border-top: 1px solid black; }
     .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls {
       padding: 0 0 5px 18px; }
       .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls .filter {
diff --git a/addons/account/static/src/css/account_bank_statement_reconciliation.scss b/addons/account/static/src/css/account_bank_statement_reconciliation.scss
index 3b98689bcbc0bad532b39e9e70b6174f8ca18483..248536b7a9bb140bcfe05dc0e42a26dd61d4a61b 100644
--- a/addons/account/static/src/css/account_bank_statement_reconciliation.scss
+++ b/addons/account/static/src/css/account_bank_statement_reconciliation.scss
@@ -194,12 +194,6 @@ $initialLineBackground: #f0f0f0;
             }
         }
 
-        &.no_partner {
-            .partner_name, .line_open_balance {
-                display: none !important;
-            }
-        }
-
         /* gap between accounting_view and action view */
         > table > tbody > tr:nth-child(1) > td table {
             margin-bottom: 10px;
@@ -341,10 +335,6 @@ $initialLineBackground: #f0f0f0;
 
             // accounting "T"
             td:nth-child(6) { border-left: $accountingBorder; }
-            tr.initial_line > td {
-                &:nth-child(5) { border-top: $accountingBorder; }
-                &:nth-child(6) { border-top: $accountingBorder; }
-            }
         }
 
 
diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js
index a7e83a2146b2790cbcf2c655f29b6f04c4af0a41..8f5786e978f5bb02bcad33a8c43af1c7ea0404d6 100644
--- a/addons/account/static/src/js/account_widgets.js
+++ b/addons/account/static/src/js/account_widgets.js
@@ -171,7 +171,7 @@ openerp.account = function (instance) {
             deferred_promises.push(self.model_bank_statement
                 .call("get_format_currency_js_function", [self.statement_id])
                 .then(function(data){
-                    self.formatCurrency = new Function("amount", data);
+                    self.formatCurrency = new Function("amount, currency_id", data);
                 })
             );
     
@@ -245,7 +245,7 @@ openerp.account = function (instance) {
     
         keyboardShortcutsHandler: function(e) {
             var self = this;
-            if (e.which === 13 && (e.ctrlKey || e.metaKey)) {
+            if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) {
                 $.each(self.getChildren(), function(i, o){
                     if (o.is_valid && o.persistAndDestroy()) {
                         self.lines_reconciled_with_ctrl_enter++;
@@ -789,6 +789,9 @@ openerp.account = function (instance) {
             line.q_amount = (line.debit !== 0 ? "- "+line.q_debit : "") + (line.credit !== 0 ? line.q_credit : "");
             line.q_popover = QWeb.render("bank_statement_reconciliation_move_line_details", {line: line});
             line.q_label = line.name;
+            if (line.has_no_partner){
+                line.q_label = line.partner_name + ': ' +line.q_label;
+            }
     
             // WARNING : pretty much of a ugly hack
             // The value of account_move.ref is either the move's communication or it's name without the slashes
@@ -981,6 +984,7 @@ openerp.account = function (instance) {
         lineOpenBalanceClickHandler: function() {
             var self = this;
             if (self.get("mode") === "create") {
+                self.addLineBeingEdited();
                 self.set("mode", "match");
             } else {
                 self.set("mode", "create");
@@ -1038,7 +1042,8 @@ openerp.account = function (instance) {
             var slice_start = self.get("pager_index") * self.max_move_lines_displayed;
             var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed;
             _( _.filter(self.mv_lines_deselected, function(o){
-                    return o.name.indexOf(self.filter) !== -1 || o.ref.indexOf(self.filter) !== -1 })
+                    return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1)
+                })
                 .slice(slice_start, slice_end)).each(function(line){
                 var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false}));
                 self.bindPopoverTo($line.find(".line_info_button"));
@@ -1057,7 +1062,6 @@ openerp.account = function (instance) {
     
         updatePagerControls: function() {
             var self = this;
-    
             if (self.get("pager_index") === 0)
                 self.$(".pager_control_left").addClass("disabled");
             else
@@ -1075,7 +1079,7 @@ openerp.account = function (instance) {
         balanceChanged: function() {
             var self = this;
             var balance = self.get("balance");
-    
+            self.$(".tbody_open_balance").empty();
             // Special case hack : no identified partner
             if (self.st_line.has_no_partner) {
                 if (Math.abs(balance).toFixed(3) === "0.000") {
@@ -1088,19 +1092,23 @@ openerp.account = function (instance) {
                     self.$(".button_ok").attr("disabled", "disabled");
                     self.$(".button_ok").text("OK");
                     self.is_valid = false;
+                    var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : "");
+                    var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : "");
+                    var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]}));
+                    $line.find('.js_open_balance')[0].innerHTML = "Choose counterpart";
+                    self.$(".tbody_open_balance").append($line);
                 }
                 return;
             }
     
-            self.$(".tbody_open_balance").empty();
             if (Math.abs(balance).toFixed(3) === "0.000") {
                 self.$(".button_ok").addClass("oe_highlight");
                 self.$(".button_ok").text("OK");
             } else {
                 self.$(".button_ok").removeClass("oe_highlight");
                 self.$(".button_ok").text("Keep open");
-                var debit = (balance > 0 ? self.formatCurrency(balance) : "");
-                var credit = (balance < 0 ? self.formatCurrency(-1*balance) : "");
+                var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : "");
+                var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : "");
                 var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {debit: debit, credit: credit, account_code: self.map_account_id_code[self.st_line.open_balance_account_id]}));
                 self.$(".tbody_open_balance").append($line);
             }
@@ -1111,21 +1119,15 @@ openerp.account = function (instance) {
     
             self.$(".action_pane.active").removeClass("active");
     
-            // Special case hack : if no_partner, either inactive or create
+            // Special case hack : if no_partner and mode == inactive
             if (self.st_line.has_no_partner) {
                 if (self.get("mode") === "inactive") {
                     self.$(".match").slideUp(self.animation_speed);
                     self.$(".create").slideUp(self.animation_speed);
                     self.$(".toggle_match").removeClass("visible_toggle");
                     self.el.dataset.mode = "inactive";
-                } else {
-                    self.initializeCreateForm();
-                    self.$(".match").slideUp(self.animation_speed);
-                    self.$(".create").slideDown(self.animation_speed);
-                    self.$(".toggle_match").addClass("visible_toggle");
-                    self.el.dataset.mode = "create";
-                }
-                return;
+                    return;
+                } 
             }
     
             if (self.get("mode") === "inactive") {
@@ -1198,6 +1200,8 @@ openerp.account = function (instance) {
             var self = this;
             var line_created_being_edited = self.get("line_created_being_edited");
             line_created_being_edited[0][elt.corresponding_property] = val.newValue;
+             
+            line_created_being_edited[0].currency_id = self.st_line.currency_id;
     
             // Specific cases
             if (elt === self.account_id_field)
@@ -1215,7 +1219,7 @@ openerp.account = function (instance) {
                             var tax = data.taxes[0];
                             var tax_account_id = (amount > 0 ? tax.account_collected_id : tax.account_paid_id)
                             line_created_being_edited[0].amount = (data.total.toFixed(3) === amount.toFixed(3) ? amount : data.total);
-                            line_created_being_edited[1] = {id: line_created_being_edited[0].id, account_id: tax_account_id, account_num: self.map_account_id_code[tax_account_id], label: tax.name, amount: tax.amount, no_remove_action: true};
+                            line_created_being_edited[1] = {id: line_created_being_edited[0].id, account_id: tax_account_id, account_num: self.map_account_id_code[tax_account_id], label: tax.name, amount: tax.amount, no_remove_action: true, currency_id: self.st_line.currency_id};
                         }
                     );
                 } else {
@@ -1228,10 +1232,9 @@ openerp.account = function (instance) {
             $.when(deferred_tax).then(function(){
                 // Format amounts
                 if (line_created_being_edited[0].amount)
-                    line_created_being_edited[0].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[0].amount));
+                    line_created_being_edited[0].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[0].amount), line_created_being_edited[0].currency_id);
                 if (line_created_being_edited[1] && line_created_being_edited[1].amount)
-                    line_created_being_edited[1].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[1].amount));
-
+                    line_created_being_edited[1].amount_str = self.formatCurrency(Math.abs(line_created_being_edited[1].amount), line_created_being_edited[0].currency_id);
                 self.set("line_created_being_edited", line_created_being_edited);
                 self.createdLinesChanged(); // TODO For some reason, previous line doesn't trigger change handler
             });
@@ -1268,10 +1271,10 @@ openerp.account = function (instance) {
             line.initial_amount = line.debit !== 0 ? line.debit : -1 * line.credit;
             if (balance < 0) {
                 line.debit -= balance;
-                line.debit_str = self.formatCurrency(line.debit);
+                line.debit_str = self.formatCurrency(line.debit, self.st_line.currency_id);
             } else {
                 line.credit -= balance;
-                line.credit_str = self.formatCurrency(line.credit);
+                line.credit_str = self.formatCurrency(line.credit, self.st_line.currency_id);
             }
             line.propose_partial_reconcile = false;
             line.partial_reconcile = true;
@@ -1291,12 +1294,13 @@ openerp.account = function (instance) {
         },
     
         unpartialReconcileLine: function(line) {
+            var self = this;
             if (line.initial_amount > 0) {
                 line.debit = line.initial_amount;
-                line.debit_str = this.formatCurrency(line.debit);
+                line.debit_str = self.formatCurrency(line.debit, self.st_line.currency_id);
             } else {
                 line.credit = -1 * line.initial_amount;
-                line.credit_str = this.formatCurrency(line.credit);
+                line.credit_str = self.formatCurrency(line.credit, self.st_line.currency_id);
             }
             line.propose_partial_reconcile = true;
             line.partial_reconcile = false;
@@ -1359,16 +1363,15 @@ openerp.account = function (instance) {
             if (limit > 0) {
                 // Load move lines
                 deferred_move_lines = self.model_bank_statement_line
-                    .call("get_move_lines_counterparts", [self.st_line.id, excluded_ids, self.filter, offset, limit])
+                    .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit])
                     .then(function (lines) {
                         _(lines).each(self.decorateMoveLine.bind(self));
                         move_lines = lines;
                     });
             }
-    
             // Fetch the number of move lines corresponding to this statement line and this filter
             var deferred_total_move_lines_num = self.model_bank_statement_line
-                .call("get_move_lines_counterparts", [self.st_line.id, excluded_ids, self.filter, offset, limit, true])
+                .call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true])
                 .then(function(num){
                     move_lines_num = num;
                 });
diff --git a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml
index f311207ad8cb0e6c106b7116b48d2366d53d475e..b5a8492545d3c8ee44daf4987b3cc8f764cd5de9 100644
--- a/addons/account/static/src/xml/account_bank_statement_reconciliation.xml
+++ b/addons/account/static/src/xml/account_bank_statement_reconciliation.xml
@@ -185,7 +185,7 @@
             <td><span class="toggle_create glyphicon glyphicon-play"></span></td>
             <td><t t-esc="account_code"/></td>
             <td></td>
-            <td>Open balance</td>
+            <td class="js_open_balance">Open balance</td>
             <td><t t-esc="debit"/></td>
             <td><t t-esc="credit"/></td>
             <td></td>
diff --git a/addons/l10n_be_coda/__openerp__.py b/addons/l10n_be_coda/__openerp__.py
index ea1ce59eb887e8b15bfc508f107fded6c57f21de..6ecdb04f1d60fb39047ebe63241ede609781981d 100644
--- a/addons/l10n_be_coda/__openerp__.py
+++ b/addons/l10n_be_coda/__openerp__.py
@@ -59,25 +59,7 @@ A removal of one object in the CODA processing results in the removal of the
 associated objects. The removal of a CODA File containing multiple Bank
 Statements will also remove those associated statements.
 
-The following reconciliation logic has been implemented in the CODA processing:
--------------------------------------------------------------------------------
-    1) The Company's Bank Account Number of the CODA statement is compared against
-       the Bank Account Number field of the Company's CODA Bank Account
-       configuration records (whereby bank accounts defined in type='info'
-       configuration records are ignored). If this is the case an 'internal transfer'
-       transaction is generated using the 'Internal Transfer Account' field of the
-       CODA File Import wizard.
-    2) As a second step the 'Structured Communication' field of the CODA transaction
-       line is matched against the reference field of in- and outgoing invoices
-       (supported : Belgian Structured Communication Type).
-    3) When the previous step doesn't find a match, the transaction counterparty is
-       located via the Bank Account Number configured on the OpenERP Customer and
-       Supplier records.
-    4) In case the previous steps are not successful, the transaction is generated
-       by using the 'Default Account for Unrecognized Movement' field of the CODA
-       File Import wizard in order to allow further manual processing.
-
-In stead of a manual adjustment of the generated Bank Statements, you can also
+Instead of a manual adjustment of the generated Bank Statements, you can also
 re-import the CODA after updating the OpenERP database with the information that
 was missing to allow automatic reconciliation.
 
diff --git a/addons/l10n_be_coda/l10n_be_coda.py b/addons/l10n_be_coda/l10n_be_coda.py
index 0dfa9bf9db4ae02245f36398fb899a7353cf1e20..c4cd8ab7c2b253cf6b0498123d359e575440c1e7 100644
--- a/addons/l10n_be_coda/l10n_be_coda.py
+++ b/addons/l10n_be_coda/l10n_be_coda.py
@@ -28,46 +28,4 @@ class account_bank_statement(osv.osv):
     }
 
 
-class account_bank_statement_line(osv.osv):
-    _inherit = 'account.bank.statement.line'
-    _columns = {
-        'coda_account_number': fields.char('Account Number', help="The Counter Party Account Number")
-    }
-
-    def create(self, cr, uid, data, context=None):
-        """
-            This function creates a Bank Account Number if, for a bank statement line,
-            the partner_id field and the coda_account_number field are set,
-            and the account number does not exist in the database
-        """
-        if 'partner_id' in data and data['partner_id'] and 'coda_account_number' in data and data['coda_account_number']:
-            acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', data['coda_account_number'])])
-            if len(acc_number_ids) == 0:
-                try:
-                    type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal')
-                    type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context)
-                    self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': data['coda_account_number'], 'partner_id': data['partner_id'], 'state': type_id.code}, context=context)
-                except ValueError:
-                    pass
-        return super(account_bank_statement_line, self).create(cr, uid, data, context=context)
-
-    def write(self, cr, uid, ids, vals, context=None):
-        super(account_bank_statement_line, self).write(cr, uid, ids, vals, context)
-        """
-            Same as create function above, but for write function
-        """
-        if 'partner_id' in vals:
-            for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
-                if line.coda_account_number:
-                    acc_number_ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', line.coda_account_number)])
-                    if len(acc_number_ids) == 0:
-                        try:
-                            type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal')
-                            type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context)
-                            self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': line.coda_account_number, 'partner_id': vals['partner_id'], 'state': type_id.code}, context=context)
-                        except ValueError:
-                            pass
-        return True
-
-
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml
index 63436a60a9204cb7636e971f41a4a55d502ec373..ce44539a7153228af3946e8a1a57497e788b721e 100644
--- a/addons/l10n_be_coda/l10n_be_coda_demo.xml
+++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml
@@ -32,5 +32,27 @@
             <field eval="'2011-01-31'" name="date_stop"/>
             <field name="company_id" ref="base.main_company"/>
         </record>
+
+        <!-- invoice with BBA -->
+        <record id="coda_demo_invoice_1" model="account.invoice">
+            <field name="currency_id" ref="base.EUR"/>
+            <field name="company_id" ref="base.main_company"/>
+            <field name="journal_id" ref="account.sales_journal"/>
+            <field name="period_id" ref="period_1_2011"/>
+            <field name="state">draft</field>
+            <field name="type">out_invoice</field>
+            <field name="account_id" ref="account.a_recv"/>
+            <field name="partner_id" ref="base.res_partner_9"/>
+            <field name="reference_type">bba</field>
+            <field name="reference">+++240/2838/42818+++</field>
+        </record>
+        <record id="invoice_1_line_1" model="account.invoice.line">
+            <field name="name">Otpez Laptop without OS</field>
+            <field name="invoice_id" ref="coda_demo_invoice_1"/>
+            <field name="price_unit">608.89</field>
+            <field name="quantity">10</field>
+            <field name="account_id" ref="account.a_sale"/>
+        </record>
+        <workflow action="invoice_open" model="account.invoice" ref="coda_demo_invoice_1"/>
     </data> 
 </openerp>
diff --git a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt
index bc3af59e322eed6a60822e1924ee7d89d0e6877f..d0add859663d178b9acfd721b11cf8ea78998a29 100644
--- a/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt
+++ b/addons/l10n_be_coda/test_coda_file/Ontvangen_CODA.2011-01-11-18.59.15.txt
@@ -4,7 +4,7 @@
 2200010000                                                                                        GKCCBEBB                   1 0
 2300010000BE41063012345610                     PARTNER 1                                                                     0 1
 3100010001OL44483FW SCTOFBIONLO001010001001PARTNER 1                                                                         0 0
-2100020000OL4414AC8BOVSOVSOVERS00000000030444501101110015000002010237                                              11011113501 0
+2100020000OL4414AC8BOVSOVSOVERS0000000003044450110111001500001101240283842818                                      11011113501 0
 2200020000                                                                                        BBRUBEBB                   1 0
 2300020000BE61310126985517                     PARTNER 2                                                                     0 1
 3100020001OL4414AC8BOVSOVSOVERS001500001001PARTNER 2                                                                         1 0
diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py
index e50f8537881f1d786f474ca1e014f41c4d730815..cac4cce452cdd6d280b842c41ccaeb0a2ef12c4e 100644
--- a/addons/l10n_be_coda/wizard/account_coda_import.py
+++ b/addons/l10n_be_coda/wizard/account_coda_import.py
@@ -291,79 +291,38 @@ class account_coda_import(osv.osv_memory):
                     if 'counterpartyAddress' in line and line['counterpartyAddress'] != '':
                         note.append(_('Counter Party Address') + ': ' + line['counterpartyAddress'])
                     line['name'] = "\n".join(filter(None, [line['counterpartyName'], line['communication']]))
-                    partner = None
                     partner_id = None
-                    invoice = False
+                    structured_com = ""
+                    bank_account_id = False
                     if line['communication_struct'] and 'communication_type' in line and line['communication_type'] == '101':
-                        ids = self.pool.get('account.invoice').search(cr, uid, [('reference', '=', line['communication']), ('reference_type', '=', 'bba')])
-                        
-# Gère les communications structurées
-# TODO : à faire primer sur resolution_proposition : si la communication indique une facture, on la sélectionne
-                        
-#                        if ids:
-#                            invoice = self.pool.get('account.invoice').browse(cr, uid, ids[0])
-#                            partner = invoice.partner_id
-#                            partner_id = partner.id
-#                            if invoice.type in ['in_invoice', 'in_refund'] and line['debit'] == '1':
-#                                line['transaction_type'] = 'supplier'
-#                            elif invoice.type in ['out_invoice', 'out_refund'] and line['debit'] == '0':
-#                                line['transaction_type'] = 'customer'
-#                            line['account'] = invoice.account_id.id
-#                            line['reconcile'] = False
-#                            if invoice.type in ['in_invoice', 'out_invoice']:
-#                                iml_ids = self.pool.get('account.move.line').search(cr, uid, [('move_id', '=', invoice.move_id.id), ('reconcile_id', '=', False), ('account_id.reconcile', '=', True)])
-#                            if iml_ids:
-#                                line['reconcile'] = iml_ids[0]
-#                            if line['reconcile']:
-#                                voucher_vals = {
-#                                    'type': line['transaction_type'] == 'supplier' and 'payment' or 'receipt',
-#                                    'name': line['name'],
-#                                    'partner_id': partner_id,
-#                                    'journal_id': statement['journal_id'].id,
-#                                    'account_id': statement['journal_id'].default_credit_account_id.id,
-#                                    'company_id': statement['journal_id'].company_id.id,
-#                                    'currency_id': statement['journal_id'].company_id.currency_id.id,
-#                                    'date': line['entryDate'],
-#                                    'amount': abs(line['amount']),
-#                                    'period_id': statement['period_id'],
-#                                    'invoice_id': invoice.id,
-#                                }
-#                                context['invoice_id'] = invoice.id
-#                                voucher_vals.update(self.pool.get('account.voucher').onchange_partner_id(cr, uid, [],
-#                                    partner_id=partner_id,
-#                                    journal_id=statement['journal_id'].id,
-#                                    amount=abs(line['amount']),
-#                                    currency_id=statement['journal_id'].company_id.currency_id.id,
-#                                    ttype=line['transaction_type'] == 'supplier' and 'payment' or 'receipt',
-#                                    date=line['transactionDate'],
-#                                    context=context
-#                                )['value'])
-#                                line_drs = []
-#                                for line_dr in voucher_vals['line_dr_ids']:
-#                                    line_drs.append((0, 0, line_dr))
-#                                voucher_vals['line_dr_ids'] = line_drs
-#                                line_crs = []
-#                                for line_cr in voucher_vals['line_cr_ids']:
-#                                    line_crs.append((0, 0, line_cr))
-#                                voucher_vals['line_cr_ids'] = line_crs
-#                                line['voucher_id'] = self.pool.get('account.voucher').create(cr, uid, voucher_vals, context=context)
+                        structured_com = line['communication']
                     if 'counterpartyNumber' in line and line['counterpartyNumber']:
                         ids = self.pool.get('res.partner.bank').search(cr, uid, [('acc_number', '=', str(line['counterpartyNumber']))])
-                        if ids and len(ids) > 0:
-                            partner = self.pool.get('res.partner.bank').browse(cr, uid, ids[0], context=context).partner_id
-                            partner_id = partner.id
+                        if ids:
+                            bank_account_id = ids[0]
+                            partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id
+                        else:
+                            #create the bank account, not linked to any partner. The reconciliation will link the partner manually
+                            #chosen at the bank statement final confirmation time.
+                            try:
+                                type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal')
+                                type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context)
+                                bank_code = type_id.code
+                            except ValueError:
+                                bank_code = 'bank'
+                            bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, {'acc_number': str(line['counterpartyNumber']), 'state': bank_code}, context=context)
                     if 'communication' in line and line['communication'] != '':
                         note.append(_('Communication') + ': ' + line['communication'])
                     data = {
                         'name': line['name'],
-                        'note':  "\n".join(note),
+                        'note': "\n".join(note),
                         'date': line['entryDate'],
                         'amount': line['amount'],
                         'partner_id': partner_id,
                         'statement_id': statement['id'],
-                        'ref': line['ref'],
+                        'ref': structured_com,
                         'sequence': line['sequence'],
-                        'coda_account_number': line['counterpartyNumber'],
+                        'bank_account_id': bank_account_id,
                     }
                     self.pool.get('account.bank.statement.line').create(cr, uid, data, context=context)
             if statement['coda_note'] != '':
diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py
index cc29c50928a26d876ee46e4aee328aa36c7499ea..e8477ec18ff74eb1c5c30f470769b8edfe7caab9 100644
--- a/openerp/addons/base/res/res_bank.py
+++ b/openerp/addons/base/res/res_bank.py
@@ -128,8 +128,7 @@ class res_partner_bank(osv.osv):
             change_default=True, domain="[('country_id','=',country_id)]"),
         'company_id': fields.many2one('res.company', 'Company',
             ondelete='cascade', help="Only if this bank account belong to your company"),
-        'partner_id': fields.many2one('res.partner', 'Account Owner', required=True,
-            ondelete='cascade', select=True),
+        'partner_id': fields.many2one('res.partner', 'Account Owner', ondelete='cascade', select=True),
         'state': fields.selection(_bank_type_get, 'Bank Account Type', required=True,
             change_default=True),
         'sequence': fields.integer('Sequence'),