diff --git a/addons/account/data/payment_receipt_data.xml b/addons/account/data/payment_receipt_data.xml
index 2b15ae5427ab984825979e6bf4739a85d3f58cb1..7cfcc760e189dc29f9f60d4e6da6237975ddc4bf 100644
--- a/addons/account/data/payment_receipt_data.xml
+++ b/addons/account/data/payment_receipt_data.xml
@@ -6,7 +6,7 @@
             <field name="model_id" ref="account.model_account_payment" />
             <field name="name">Print Receipt</field>
             <field name="key2">client_action_multi</field>
-            <field name="value" eval="'ir.actions.report.xml,' +str(ref('action_report_payment_receipt'))" />
+            <field name="value" eval="'ir.actions.report,' +str(ref('action_report_payment_receipt'))" />
             <field name="key">action</field>
             <field name="model">account.payment</field>
         </record>
diff --git a/addons/account/test/account_report.yml b/addons/account/test/account_report.yml
index 7ea73c1dd7545c4e663c09f888a73de913324f6e..b3ac442aa81a65f86c05e27ab95cb04405f8ea18 100644
--- a/addons/account/test/account_report.yml
+++ b/addons/account/test/account_report.yml
@@ -14,9 +14,8 @@
 -
   !python {model: account.invoice, id: False}: |
     import os
-    import odoo.report
     from odoo import tools
-    data, format = odoo.report.render_report(self.env.cr, self.env.uid, [ref('account.account_invoice_customer0')], 'account.report_invoice', {}, {})
+    data, format = ref('account.report_invoice').render(ref('account.account_invoice_customer0'))
     if tools.config['test_report_directory']:
         file(os.path.join(tools.config['test_report_directory'], 'account-invoice.'+format), 'wb+').write(data)
 -
@@ -24,9 +23,8 @@
 -
   !python {model: res.partner, id: False}: |
     import os
-    import odoo.report
     from odoo import tools
-    data, format = odoo.report.render_report(self.env.cr, self.env.uid, [ref('base.res_partner_1'),ref('base.res_partner_2'),ref('base.res_partner_12')], 'account.report_overdue', {}, {})
+    data, format = ref('account.report_overdue').render([ref('base.res_partner_1'),ref('base.res_partner_2'),ref('base.res_partner_12')])
     if tools.config['test_report_directory']:
         file(os.path.join(tools.config['test_report_directory'], 'account-report_overdue.'+format), 'wb+').write(data)
 -
diff --git a/addons/account/views/account_report.xml b/addons/account/views/account_report.xml
index 9d3e9b215c90717b36bb9ffc196ce57cc7429b15..ddf5cb21cb02a14d145c89f72418ae594300b842 100644
--- a/addons/account/views/account_report.xml
+++ b/addons/account/views/account_report.xml
@@ -13,7 +13,7 @@
             attachment="(object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')"
         />
 
-        <record id="account_invoices" model="ir.actions.report.xml">
+        <record id="account_invoices" model="ir.actions.report">
             <field name="print_report_name">(object.type == 'out_invoice' and object.state == 'draft' and 'Draft Invoice' or
             object.type == 'out_invoice' and object.state in ('open','paid') and 'Invoice'+'-'+(object.number) or
             object.type == 'out_refund' and object.state == 'draft' and 'Credit Note' or
@@ -33,7 +33,7 @@
             file="account.report_invoice_duplicate"
             attachment_use="False"
         />
-        <record id="account_invoice_action_report_duplicate" model="ir.actions.report.xml">
+        <record id="account_invoice_action_report_duplicate" model="ir.actions.report">
             <field name="print_report_name">(object.type == 'out_invoice' and object.state == 'draft' and 'Duplicate Invoice' or
             object.type == 'out_invoice' and object.state in ('open','paid') and 'Duplicate Invoice'+'-'+(object.number) or
             object.type == 'out_refund' and object.state == 'draft' and 'Duplicate Credit Note' or
@@ -52,7 +52,7 @@
             name="account.report_overdue"
             file="account.report_overdue"
             />
-        <record id="action_report_print_overdue" model="ir.actions.report.xml">
+        <record id="action_report_print_overdue" model="ir.actions.report">
             <field name="print_report_name">'Due Payments'+'-'+(object.name)</field>
         </record>
 
diff --git a/addons/base_import_module/tests/test_module/test.xml b/addons/base_import_module/tests/test_module/test.xml
index 8e3df933e2a73ccb3a3fdbe322e6ca9a15c2f631..80e24a4293bf39334752b339d10661a8729ef17a 100644
--- a/addons/base_import_module/tests/test_module/test.xml
+++ b/addons/base_import_module/tests/test_module/test.xml
@@ -7,7 +7,7 @@
 
     <record id="main_company2" model="res.company">
         <field name="name">Hagrid</field>
-        <field name="rml_header1">My Company Tagline</field>
+        <field name="report_header">My Company Tagline</field>
         <field name="currency_id" ref="base.EUR"/>
     </record>
 
diff --git a/addons/base_setup/models/res_config.py b/addons/base_setup/models/res_config.py
index ceeb7c3bdbff919b8f8c94f9112acb6806ea5014..8db758ccc31598c9c3b06febdd8bb7039da3dd99 100644
--- a/addons/base_setup/models/res_config.py
+++ b/addons/base_setup/models/res_config.py
@@ -28,7 +28,7 @@ class BaseConfigSettings(models.TransientModel):
              " * Checked : Partners are visible for every companies, even if a company is defined on the partner.\n"
              " * Unchecked : Each company can see only its partner (partners where company is defined). Partners not related to a company are visible for all companies.")
     default_custom_report_footer = fields.Boolean("Custom Report Footer")
-    rml_footer = fields.Text(related="company_id.rml_footer", string='Custom Report Footer', help="Footer text displayed at the bottom of all reports.")
+    report_footer = fields.Text(related="company_id.report_footer", string='Custom Report Footer', help="Footer text displayed at the bottom of all reports.")
     group_multi_currency = fields.Boolean(string='Allow multi currencies',
             implied_group='base.group_multi_currency',
             help="Allows to work in a multi currency environment")
diff --git a/addons/event/report/event_event_reports.xml b/addons/event/report/event_event_reports.xml
index 2f81b7b0e3b220961e6a6f75c2e977e9b395f45a..341d69702c23fc05c3095b7c92844c12cac87b77 100644
--- a/addons/event/report/event_event_reports.xml
+++ b/addons/event/report/event_event_reports.xml
@@ -25,7 +25,7 @@
         name="event.event_registration_report_template_badge"
         file="event.event_registration_report_template_badge"
         paperformat="event.paperformat_euro_lowmargin"/>
-    <record id="report_event_registration_badge" model="ir.actions.report.xml">
+    <record id="report_event_registration_badge" model="ir.actions.report">
         <field name="print_report_name">'Registration Event'+'-'+(object.name)</field>
     </record>
 
diff --git a/addons/hr_attendance/report/hr_employee_badge.xml b/addons/hr_attendance/report/hr_employee_badge.xml
index 8da14a63e8579b7fdb56c081ecfdcdd438a461a4..0ee61507e086c29934922d84cc4bff82263eeea5 100644
--- a/addons/hr_attendance/report/hr_employee_badge.xml
+++ b/addons/hr_attendance/report/hr_employee_badge.xml
@@ -7,7 +7,7 @@
         report_type="qweb-pdf"
         name="hr_attendance.print_employee_badge"
         file="hr_attendance.print_employee_badge"/>
-    <record id="hr_employee_print_badge" model="ir.actions.report.xml">
+    <record id="hr_employee_print_badge" model="ir.actions.report">
         <field name="print_report_name">'Print Badge'+'-'+(object.name)</field>
     </record>
 
diff --git a/addons/hr_expense/report/report_expense_sheet.xml b/addons/hr_expense/report/report_expense_sheet.xml
index e033d7920c1a5079b8072dd4878530e50b737ca3..6511dcbcf0c1498850ea7e48c8faa8a36caf5544 100644
--- a/addons/hr_expense/report/report_expense_sheet.xml
+++ b/addons/hr_expense/report/report_expense_sheet.xml
@@ -106,7 +106,7 @@
         name="hr_expense.report_expense_sheet"
         file="hr_expense.report_expense_sheet"
     />
-    <record id="action_report_hr_expense_sheet" model="ir.actions.report.xml">
+    <record id="action_report_hr_expense_sheet" model="ir.actions.report">
         <field name="print_report_name">'Expenses'+'-'+(object.employee_id.name)+'-'+(object.name)</field>
     </record>
 
diff --git a/addons/hr_holidays/report/hr_holidays_reports.xml b/addons/hr_holidays/report/hr_holidays_reports.xml
index b033dbf3679e71d093cf026ef4f32b402132534d..bea309eb923be7ad80e88b774d420fd3f917e29e 100644
--- a/addons/hr_holidays/report/hr_holidays_reports.xml
+++ b/addons/hr_holidays/report/hr_holidays_reports.xml
@@ -10,7 +10,7 @@
             file="hr_holidays.report_holidayssummary"
             menu="False"/>
 
-        <record id="report_holidays_summary" model="ir.actions.report.xml">
+        <record id="report_holidays_summary" model="ir.actions.report">
             <field name="paperformat_id" ref="hr_holidays.paperformat_hrsummary"/>
         </record>
 
diff --git a/addons/hr_payroll/tests/test_payslip_flow.py b/addons/hr_payroll/tests/test_payslip_flow.py
index 7ab0fad275a91c1a756a597f2180d7e1fd77707d..54de80bfbba435a64524e940e6a6d1e0a067abe3 100644
--- a/addons/hr_payroll/tests/test_payslip_flow.py
+++ b/addons/hr_payroll/tests/test_payslip_flow.py
@@ -2,10 +2,7 @@
 # Part of Odoo. See LICENSE file for full copyright and licensing details.
 
 import os
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
 
-from odoo.report import render_report
 from odoo.tools import config, test_reports
 from odoo.addons.hr_payroll.tests.common import TestPayslipBase
 
@@ -72,14 +69,14 @@ class TestPayslipFlow(TestPayslipBase):
         })
 
         # I print the payslip report
-        data, format = render_report(self.env.cr, self.env.uid, richard_payslip.ids, 'hr_payroll.report_payslip', {}, {})
+        data, data_format = self.env.ref('hr_payroll.action_report_payslip').render(richard_payslip.ids)
         if config.get('test_report_directory'):
-            open(os.path.join(config['test_report_directory'], 'hr_payroll-payslip.'+ format), 'wb+').write(data)
+            open(os.path.join(config['test_report_directory'], 'hr_payroll-payslip.'+ data_format), 'wb+').write(data)
 
         # I print the payslip details report
-        data, format = render_report(self.env.cr, self.env.uid, richard_payslip.ids, 'hr_payroll.report_payslipdetails', {}, {})
+        data, data_format = self.env.ref('hr_payroll.payslip_details_report').render(richard_payslip.ids)
         if config.get('test_report_directory'):
-            open(os.path.join(config['test_report_directory'], 'hr_payroll-payslipdetails.'+ format), 'wb+').write(data)
+            open(os.path.join(config['test_report_directory'], 'hr_payroll-payslipdetails.'+ data_format), 'wb+').write(data)
 
         # I print the contribution register report
         context = {'model': 'hr.contribution.register', 'active_ids': [self.ref('hr_payroll.hr_houserent_register')]}
diff --git a/addons/hr_payroll/views/hr_payroll_report.xml b/addons/hr_payroll/views/hr_payroll_report.xml
index c6e02324f0a64ddda58e2a5348af3a72c3495e89..6b1e8a94637cdeb7046d684ca0c370046ebda5a4 100644
--- a/addons/hr_payroll/views/hr_payroll_report.xml
+++ b/addons/hr_payroll/views/hr_payroll_report.xml
@@ -17,7 +17,7 @@
             name="hr_payroll.report_payslip" 
             file="hr_payroll.report_payslip"
         />
-        <record id="action_report_payslip" model="ir.actions.report.xml">
+        <record id="action_report_payslip" model="ir.actions.report">
             <field name="print_report_name">(object.employee_id.name)+'-'+'Payslip'</field>
         </record>
         <report
@@ -28,7 +28,7 @@
             name="hr_payroll.report_payslipdetails" 
             file="hr_payroll.report_payslipdetails"
         />
-        <record id="payslip_details_report" model="ir.actions.report.xml">
+        <record id="payslip_details_report" model="ir.actions.report">
             <field name="print_report_name">(object.name)</field>
         </record>
 </odoo>
diff --git a/addons/l10n_ca/data/res_company_data.xml b/addons/l10n_ca/data/res_company_data.xml
index 11adcbd01d4ae47b15cbaf2c5452c4858a2000aa..fdc19388202847711700cc97e5d35fc4590a00c4 100644
--- a/addons/l10n_ca/data/res_company_data.xml
+++ b/addons/l10n_ca/data/res_company_data.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <odoo>
 <record model="res.company" id="base.main_company">
-    <field name="rml_paper_format">us_letter</field>
     <field name="paperformat_id" ref="report.paperformat_us"/>
 </record>
 </odoo>
diff --git a/addons/l10n_ch/report/isr_report.xml b/addons/l10n_ch/report/isr_report.xml
index 23ff2f70758818a3d8335f24d11f4dd0e6e08436..1cabbd8c0560b0d0dc9f5c0fc58d3d6a48586b0b 100644
--- a/addons/l10n_ch/report/isr_report.xml
+++ b/addons/l10n_ch/report/isr_report.xml
@@ -27,7 +27,7 @@
             menu="False"
             />
 
-        <record id="l10n_ch_isr_report" model ="ir.actions.report.xml">
+        <record id="l10n_ch_isr_report" model ="ir.actions.report">
             <field name="print_report_name">
                 'ISR-' + object.number
                 <!--No additional condition on invoice state or type as this
diff --git a/addons/l10n_fr/test/l10n_fr_report.yml b/addons/l10n_fr/test/l10n_fr_report.yml
index aaff326624d64272faf63b7b578d1ccfa1e03f0e..927d7d4f2c12348a6221b53b481c2b3c086b9ad9 100644
--- a/addons/l10n_fr/test/l10n_fr_report.yml
+++ b/addons/l10n_fr/test/l10n_fr_report.yml
@@ -3,9 +3,8 @@
 -
   !python {model: account.move.line, id: False}: |
     import os
-    import odoo.report
     from odoo import tools
-    data, format = odoo.report.render_report(self.env.cr, self.env.uid, [], 'l10n_fr.report_l10nfrbilan', {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {})
+    data, format = self.env.ref('l10n_fr.report_l10nfrbilan').render([], data={'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}})
     if tools.config['test_report_directory']:
         file(os.path.join(tools.config['test_report_directory'], 'l10n_fr-bilan_report.'+format), 'wb+').write(data)
 
@@ -14,8 +13,7 @@
 -
   !python {model: account.move.line}: |
     import os
-    import odoo.report
     from odoo import tools
-    data, format = odoo.report.render_report(self.env.cr, self.env.uid, [], 'l10n_fr.report_l10nfrresultat', {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {})
+    data, format =  self.env.ref('l10n_fr.report_l10nfrresultat').render([], data={'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}})
     if tools.config['test_report_directory']:
         file(os.path.join(tools.config['test_report_directory'], 'l10n_fr-compute_resultant_report.'+format), 'wb+').write(data)
diff --git a/addons/l10n_in_hr_payroll/tests/test_payment_advice.py b/addons/l10n_in_hr_payroll/tests/test_payment_advice.py
index d08c0f58b7a3c69a9ad5d3e784adae5c8419c438..7d9417606f39500ff60f6a99a909ee32c30d5c27 100644
--- a/addons/l10n_in_hr_payroll/tests/test_payment_advice.py
+++ b/addons/l10n_in_hr_payroll/tests/test_payment_advice.py
@@ -3,7 +3,6 @@
 
 import os
 
-from odoo.report import render_report
 from odoo.tools import config
 from odoo.addons.l10n_in_hr_payroll.tests.common import TestPaymentAdviceBase
 
@@ -38,6 +37,6 @@ class TestPaymentAdvice(TestPaymentAdviceBase):
         self.assertEqual(payment_advice.state, 'confirm')
 
         # In order to test the PDF report defined on a Payment Advice, we will print a Print Advice Report when NEFT is checked
-        data, format = render_report(self.env.cr, self.env.uid, payment_advice.ids, 'l10n_in_hr_payroll.report_payrolladvice', {}, {})
+        data, data_format = self.env.ref('l10n_in_hr_payroll.payroll_advice').render(payment_advice.ids)
         if config.get('test_report_directory'):
-            open(os.path.join(config['test_report_directory'], 'l10n_in_hr_payroll_summary_report' + format), 'wb+').write(data)
+            open(os.path.join(config['test_report_directory'], 'l10n_in_hr_payroll_summary_report' + data_format), 'wb+').write(data)
diff --git a/addons/l10n_us/data/res_company_data.xml b/addons/l10n_us/data/res_company_data.xml
index 11adcbd01d4ae47b15cbaf2c5452c4858a2000aa..fdc19388202847711700cc97e5d35fc4590a00c4 100644
--- a/addons/l10n_us/data/res_company_data.xml
+++ b/addons/l10n_us/data/res_company_data.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <odoo>
 <record model="res.company" id="base.main_company">
-    <field name="rml_paper_format">us_letter</field>
     <field name="paperformat_id" ref="report.paperformat_us"/>
 </record>
 </odoo>
diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py
index 2c989bb7e2e73e8fdb0e17bb288b32eb8cab09b6..568337c75511e1f236ca88e0a4745b57ec05bf75 100644
--- a/addons/mail/models/mail_template.py
+++ b/addons/mail/models/mail_template.py
@@ -15,7 +15,6 @@ import urlparse
 from urllib import urlencode, quote as quote
 
 from odoo import _, api, fields, models, tools
-from odoo import report as odoo_report
 from odoo.exceptions import UserError
 from odoo.tools import pycompat
 
@@ -155,7 +154,7 @@ class MailTemplate(models.Model):
     report_name = fields.Char('Report Filename', translate=True,
                               help="Name to use for the generated report file (may contain placeholders)\n"
                                    "The extension can be omitted and will then come from the report type.")
-    report_template = fields.Many2one('ir.actions.report.xml', 'Optional report to print and attach')
+    report_template = fields.Many2one('ir.actions.report', 'Optional report to print and attach')
     ref_ir_act_window = fields.Many2one('ir.actions.act_window', 'Sidebar action', readonly=True, copy=False,
                                         help="Sidebar action to make this template available on records "
                                              "of the related document model")
@@ -508,10 +507,9 @@ class MailTemplate(models.Model):
                     report = template.report_template
                     report_service = report.report_name
 
-                    if report.report_type in ['qweb-html', 'qweb-pdf']:
-                        result, format = Template.env['report'].get_pdf([res_id], report_service), 'pdf'
-                    else:
-                        result, format = odoo_report.render_report(self._cr, self._uid, [res_id], report_service, {'model': template.model}, Template._context)
+                    if report.report_type not in ['qweb-html', 'qweb-pdf']:
+                        raise UserError(_('Unsupported report type %s found.') % report.report_type)
+                    result, format = Template.env['report'].get_pdf([res_id], report_service), 'pdf'
 
                     # TODO in trunk, change return format to binary to match message_post expected format
                     result = base64.b64encode(result)
diff --git a/addons/marketing_campaign/models/ir_actions.py b/addons/marketing_campaign/models/ir_actions.py
index cb9a55db6cca34d423cdef63b1b5e1f44a00df2f..989507a9fa5da154b1aadaab4253f63531718e8b 100644
--- a/addons/marketing_campaign/models/ir_actions.py
+++ b/addons/marketing_campaign/models/ir_actions.py
@@ -4,8 +4,8 @@
 from odoo import api, models
 
 
-class IrActionsReportXml(models.Model):
-    _inherit = 'ir.actions.report.xml'
+class IrActionsReport(models.Model):
+    _inherit = 'ir.actions.report'
 
     @api.model
     def search(self, args, offset=0, limit=None, order=None, count=False):
@@ -13,4 +13,4 @@ class IrActionsReportXml(models.Model):
         if model_id:
             model = self.env['ir.model'].browse(model_id).model
             args.append(('model', '=', model))
-        return super(IrActionsReportXml, self).search(args, offset=offset, limit=limit, order=order, count=count)
+        return super(IrActionsReport, self).search(args, offset=offset, limit=limit, order=order, count=count)
diff --git a/addons/marketing_campaign/models/marketing_campaign.py b/addons/marketing_campaign/models/marketing_campaign.py
index de60ed86e4f349091c70e725e4eeb076aa22665c..a6a3acf303e9f11e4a78749b781a1739163e91ee 100644
--- a/addons/marketing_campaign/models/marketing_campaign.py
+++ b/addons/marketing_campaign/models/marketing_campaign.py
@@ -311,7 +311,7 @@ class MarketingCampaignActivity(models.Model):
              "- Report: print an existing Report defined on the resource item and save it into a specific directory \n"
              "- Custom Action: execute a predefined action, e.g. to modify the fields of the resource record")
     email_template_id = fields.Many2one('mail.template', "Email Template", help='The email to send when this activity is activated')
-    report_id = fields.Many2one('ir.actions.report.xml', "Report", help='The report to generate when this activity is activated')
+    report_id = fields.Many2one('ir.actions.report', "Report", help='The report to generate when this activity is activated')
     server_action_id = fields.Many2one('ir.actions.server', string='Action',
         help="The action to perform when this activity is activated")
     to_ids = fields.One2many('marketing.campaign.transition', 'activity_from_id', 'Next Activities')
@@ -343,7 +343,7 @@ class MarketingCampaignActivity(models.Model):
     @api.multi
     def _process_wi_report(self, workitem):
         self.ensure_one()
-        return self.report_id.render_report(workitem.res_id, self.report_id.report_name, None)
+        return self.report_id.render(workitem.res_id)
 
     @api.multi
     def _process_wi_action(self, workitem):
@@ -611,7 +611,7 @@ class MarketingCampaignWorkitem(models.Model):
                 'model': self.object_id.model
             }
             res = {
-                'type': 'ir.actions.report.xml',
+                'type': 'ir.actions.report',
                 'report_name': self.activity_id.report_id.report_name,
                 'datas': datas,
             }
diff --git a/addons/mrp/report/mrp_report_views_main.xml b/addons/mrp/report/mrp_report_views_main.xml
index cdc7d40e79e4b230064156f9d8fd8550030af243..86dfc67ecba76bcc67375d031cc47311459d4abe 100644
--- a/addons/mrp/report/mrp_report_views_main.xml
+++ b/addons/mrp/report/mrp_report_views_main.xml
@@ -9,7 +9,7 @@
             file="mrp.report.mrp_bom_templates" 
             report_type="qweb-pdf"
         />
-        <record id="action_report_bom_structure" model="ir.actions.report.xml">
+        <record id="action_report_bom_structure" model="ir.actions.report">
             <field name="print_report_name">'BOM'+'-'+(object.product_id.name or object.product_tmpl_id.name)</field>
         </record>
 
@@ -21,7 +21,7 @@
             file="mrp.report.mrp_production_templates" 
             report_type="qweb-pdf"
         />
-        <record id="action_report_production_order" model="ir.actions.report.xml">
+        <record id="action_report_production_order" model="ir.actions.report">
             <field name="print_report_name">'Production Order'+'-'+(object.name)</field>
         </record>
 
@@ -33,7 +33,7 @@
             file="mrp_bom_cost"
             report_type="qweb-html"
         />
-        <record id="action_report_bom_price" model="ir.actions.report.xml">
+        <record id="action_report_bom_price" model="ir.actions.report">
             <field name="print_report_name">'BOM Cost'+'-'+(object.product_id.name or object.product_tmpl_id.name)</field>
         </record>
     </data>
diff --git a/addons/mrp_repair/report/mrp_repair_reports.xml b/addons/mrp_repair/report/mrp_repair_reports.xml
index 9963f87d614070e75c2e3b7ae80ce3c85a67d834..3cc755f5b73e80b135289d2719df83b85ff53812 100644
--- a/addons/mrp_repair/report/mrp_repair_reports.xml
+++ b/addons/mrp_repair/report/mrp_repair_reports.xml
@@ -9,7 +9,7 @@
             file="mrp_repair.report_mrprepairorder" 
             report_type="qweb-pdf"
         />
-        <record id="action_report_mrp_repair_order" model="ir.actions.report.xml">
+        <record id="action_report_mrp_repair_order" model="ir.actions.report">
             <field name="print_report_name">(object.state == 'draft' and 'Repair Quotation'+'-'+(object.name) or 'Repair Order'+'-'+(object.name))</field>
         </record>
     </data>
diff --git a/addons/point_of_sale/tests/test_point_of_sale_flow.py b/addons/point_of_sale/tests/test_point_of_sale_flow.py
index 24869ad5881d42f5900bed392e5e6988ed499233..26a13bf2f5f2d02f7e5c316a556f969ca45ad3ec 100644
--- a/addons/point_of_sale/tests/test_point_of_sale_flow.py
+++ b/addons/point_of_sale/tests/test_point_of_sale_flow.py
@@ -3,9 +3,10 @@ import time
 
 import odoo
 from odoo import fields
-from odoo.tools import float_compare, mute_logger
+from odoo.tools import float_compare, mute_logger, test_reports
 from odoo.addons.point_of_sale.tests.common import TestPointOfSaleCommon
 
+
 @odoo.tests.common.at_install(False)
 @odoo.tests.common.post_install(True)
 class TestPointOfSaleFlow(TestPointOfSaleCommon):
diff --git a/addons/point_of_sale/views/point_of_sale_report.xml b/addons/point_of_sale/views/point_of_sale_report.xml
index b8e8bafac9cca729f88f9e5567358f4ce2d3035a..d010e7fcfe47b93df5c7f15122d9659053edba06 100644
--- a/addons/point_of_sale/views/point_of_sale_report.xml
+++ b/addons/point_of_sale/views/point_of_sale_report.xml
@@ -10,7 +10,7 @@
     />
 
     <!-- used from POS UI, no need to be in print menu -->
-    <record id="pos_invoice_report" model="ir.actions.report.xml">
+    <record id="pos_invoice_report" model="ir.actions.report">
         <field name="name">Invoice</field>
         <field name="model">pos.order</field>
         <field name="report_type">qweb-pdf</field>
@@ -18,7 +18,7 @@
         <field name="print_report_name">'Invoice'+'-'+(object.name)</field>
     </record>
 
-    <record id="sale_details_report" model="ir.actions.report.xml">
+    <record id="sale_details_report" model="ir.actions.report">
         <field name="name">Sales Details</field>
         <field name="model">report.point_of_sale.details</field>
         <field name="report_type">qweb-pdf</field>
diff --git a/addons/product/report/product_reports.xml b/addons/product/report/product_reports.xml
index 2c7a58336d0460e2dd3f526c8c8df348f10e1ef9..0e48f95aa27151d7ff89c612b2d25ac2250f142a 100644
--- a/addons/product/report/product_reports.xml
+++ b/addons/product/report/product_reports.xml
@@ -8,7 +8,7 @@
             report_type="qweb-pdf"
             name="product.report_productlabel"
             file="product.report_productlabel"/>
-        <record id="report_product_label" model="ir.actions.report.xml">
+        <record id="report_product_label" model="ir.actions.report">
             <field name="print_report_name">'Products Labels'+'-'+(object.name)</field>
         </record>
 
@@ -19,7 +19,7 @@
             report_type="qweb-pdf"
             name="product.report_producttemplatelabel"
             file="product.report_producttemplatelabel"/>
-        <record id="report_product_template_label" model="ir.actions.report.xml">
+        <record id="report_product_template_label" model="ir.actions.report">
             <field name="print_report_name">'Products Labels'+'-'+(object.name)</field>
         </record>
 
diff --git a/addons/purchase/report/purchase_reports.xml b/addons/purchase/report/purchase_reports.xml
index a266c4d014704f642a4be371885d67f4e898b606..33524f2342c9982d0ec6270e71db483198809d25 100644
--- a/addons/purchase/report/purchase_reports.xml
+++ b/addons/purchase/report/purchase_reports.xml
@@ -8,7 +8,7 @@
             name="purchase.report_purchaseorder" 
             file="purchase.report_purchaseorder" 
         />
-        <record id="action_report_purchase_order" model="ir.actions.report.xml">
+        <record id="action_report_purchase_order" model="ir.actions.report">
             <field name="print_report_name">(object.state in ('draft', 'sent') and 'Request for Quotation'+'-'+(object.name) or 'Purchase Order'+'-'+(object.name))</field>
         </record>
 
@@ -20,7 +20,7 @@
             name="purchase.report_purchasequotation" 
             file="purchase.report_purchasequotation"
         />
-        <record id="report_purchase_quotation" model="ir.actions.report.xml">
+        <record id="report_purchase_quotation" model="ir.actions.report">
             <field name="print_report_name">'Request for Quotation'+'-'+(object.name)</field>
         </record>
 </odoo>
diff --git a/addons/purchase_requisition/report/purchase_requisition_report.xml b/addons/purchase_requisition/report/purchase_requisition_report.xml
index 98b73254c115f312be8b43303d0840b4e4e88f1f..0870c38afb0a1fff1280ba57f36abca29139f420 100644
--- a/addons/purchase_requisition/report/purchase_requisition_report.xml
+++ b/addons/purchase_requisition/report/purchase_requisition_report.xml
@@ -9,7 +9,7 @@
             name="purchase_requisition.report_purchaserequisitions" 
             file="purchase_requisition.report.report_purchaserequisitions"
          />
-        <record id="action_report_purchase_requisitions" model="ir.actions.report.xml">
+        <record id="action_report_purchase_requisitions" model="ir.actions.report">
             <field name="print_report_name">'Tender'+'-'+(object.name)</field>
         </record>
     </data>
diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py
index 7e0fd9f8123b98dec8f531880b26a460b05572f4..43771252ccb156aa333ec6025e36b8089a9c9673 100644
--- a/addons/report/controllers/main.py
+++ b/addons/report/controllers/main.py
@@ -110,11 +110,6 @@ class ReportController(Controller):
                 response.headers.add('Content-Disposition', content_disposition(filename))
                 response.set_cookie('fileToken', token)
                 return response
-            elif type == 'controller':
-                reqheaders = Headers(request.httprequest.headers)
-                response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
-                response.set_cookie('fileToken', token)
-                return response
             else:
                 return
         except Exception as e:
diff --git a/addons/report/models/__init__.py b/addons/report/models/__init__.py
index c983832539e0fa04a541f3799d63cfa94d6e6637..5e9033225cfb949145b76dda6b4339c04a62f287 100644
--- a/addons/report/models/__init__.py
+++ b/addons/report/models/__init__.py
@@ -3,7 +3,7 @@
 
 from . import abstract_report
 from . import base_config_settings
-from . import ir_actions_report_xml
+from . import  ir_actions_report
 from . import ir_http
 from . import ir_qweb
 from . import report
diff --git a/addons/report/models/ir_actions_report_xml.py b/addons/report/models/ir_actions_report.py
similarity index 87%
rename from addons/report/models/ir_actions_report_xml.py
rename to addons/report/models/ir_actions_report.py
index 8461815e389f689179572c6c5ad75f8ca4ef6564..cc46523c0b23b8ee6e757008debf6385ce3f1e50 100644
--- a/addons/report/models/ir_actions_report_xml.py
+++ b/addons/report/models/ir_actions_report.py
@@ -4,7 +4,7 @@
 from odoo import api, fields, models
 
 class ir_actions_report(models.Model):
-    _inherit = 'ir.actions.report.xml'
+    _inherit = 'ir.actions.report'
 
     paperformat_id = fields.Many2one('report.paperformat', 'Paper format')
     print_report_name = fields.Char('Printed Report Name',
@@ -12,7 +12,7 @@ class ir_actions_report(models.Model):
 
     @api.multi
     def associated_view(self):
-        """Used in the ir.actions.report.xml form view in order to search naively after the view(s)
+        """Used in the ir.actions.report form view in order to search naively after the view(s)
         used in the rendering.
         """
         self.ensure_one()
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 55abb28a6383d39e73f9ab3cc4a52e77458ee27a..b581bf0a6130d63a5b7185da0901017af03bc2f9 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -186,7 +186,7 @@ class Report(models.Model):
 
         html = html.decode('utf-8')  # Ensure the current document is utf-8 encoded.
 
-        # Get the ir.actions.report.xml record we are working on.
+        # Get the ir.actions.report record we are working on.
         report = self._get_report_from_name(report_name)
         # Check if we have to save the report or if we have to get one from the db.
         save_in_attachment = self._check_attachment_use(docids, report)
@@ -267,7 +267,7 @@ class Report(models.Model):
 
     @api.noguess
     def get_action(self, docids, report_name, data=None, config=True):
-        """Return an action of type ir.actions.report.xml.
+        """Return an action of type ir.actions.report.
 
         :param docids: id/ids/browserecord of the records to print (if not used, pass an empty list)
         :param report_name: Name of the template to generate an action for
@@ -297,14 +297,14 @@ class Report(models.Model):
                 active_ids = docids
             context = dict(self.env.context, active_ids=active_ids)
 
-        report = self.env['ir.actions.report.xml'].with_context(context).search([('report_name', '=', report_name)])
+        report = self.env['ir.actions.report'].with_context(context).search([('report_name', '=', report_name)])
         if not report:
             raise UserError(_("Bad Report Reference") + _("This report is not loaded into the database: %s.") % report_name)
 
         return {
             'context': context,
             'data': data,
-            'type': 'ir.actions.report.xml',
+            'type': 'ir.actions.report',
             'report_name': report.report_name,
             'report_type': report.report_type,
             'report_file': report.report_file,
@@ -515,10 +515,10 @@ class Report(models.Model):
 
     @api.model
     def _get_report_from_name(self, report_name):
-        """Get the first record of ir.actions.report.xml having the ``report_name`` as value for
+        """Get the first record of ir.actions.report having the ``report_name`` as value for
         the field report_name.
         """
-        report_obj = self.env['ir.actions.report.xml']
+        report_obj = self.env['ir.actions.report']
         qwebtypes = ['qweb-pdf', 'qweb-html']
         conditions = [('report_type', 'in', qwebtypes), ('report_name', '=', report_name)]
         context = self.env['res.users'].context_get()
diff --git a/addons/report/models/report_paperformat.py b/addons/report/models/report_paperformat.py
index a97a1dfd3e0c5e35ccd2d3ed2d09aea31999dfa9..08235f3060b2897b20a085c678b3bd97e58ea577 100644
--- a/addons/report/models/report_paperformat.py
+++ b/addons/report/models/report_paperformat.py
@@ -60,7 +60,7 @@ class report_paperformat(models.Model):
     header_line = fields.Boolean('Display a header line', default=False)
     header_spacing = fields.Integer('Header spacing', default=35)
     dpi = fields.Integer('Output DPI', required=True, default=90)
-    report_ids = fields.One2many('ir.actions.report.xml', 'paperformat_id', 'Associated reports', help="Explicitly associated reports")
+    report_ids = fields.One2many('ir.actions.report', 'paperformat_id', 'Associated reports', help="Explicitly associated reports")
 
     @api.constrains('format')
     def _check_format_or_page(self):
diff --git a/addons/report/models/res_company.py b/addons/report/models/res_company.py
index 85683e6edc1dbed03a9dd2c55533d80d06800e7e..61fa63fea8681595c39cf3ccd98b4f9f688dc04e 100644
--- a/addons/report/models/res_company.py
+++ b/addons/report/models/res_company.py
@@ -29,17 +29,10 @@ class ResCompany(models.Model):
 
     @api.model_cr
     def init(self):
-        # set a default paperformat based on rml one.
         for company in self.search([('paperformat_id', '=', False)]):
             paperformat_euro = self.env.ref('report.paperformat_euro', False)
-            paperformat_us = self.env.ref('report.paperformat_us', False)
-            paperformat_id = {
-                'a4': paperformat_euro and paperformat_euro.id or False,
-                'us_letter': paperformat_us and paperformat_us.id or False,
-            }.get(company.rml_paper_format) or paperformat_euro
-
-            if paperformat_id:
-                company.write({'paperformat_id': paperformat_id})
+            if paperformat_euro:
+                company.write({'paperformat_id': paperformat_euro.id})
 
         sup = super(ResCompany, self)
         if hasattr(sup, 'init'):
diff --git a/addons/report/static/src/js/client_action.js b/addons/report/static/src/js/client_action.js
index 041a7af383b0c5ef7dc7777b1d3b0434cd2020dc..60265c0a49dce0d74a5a5e8340dff4882d7900f5 100644
--- a/addons/report/static/src/js/client_action.js
+++ b/addons/report/static/src/js/client_action.js
@@ -180,7 +180,7 @@ var ReportAction = Widget.extend(ControlPanelMixin, {
 
     on_click_print: function () {
         var action = {
-            'type': 'ir.actions.report.xml',
+            'type': 'ir.actions.report',
             'report_type': 'qweb-pdf',
             'report_name': this.report_name,
             'report_file': this.report_file,
diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js
index 3f477bf7d16984e70fdbe44d41b4095a595aaf0b..3c8fee859e393ed6d808ffecce013beb04bed420 100644
--- a/addons/report/static/src/js/qwebactionmanager.js
+++ b/addons/report/static/src/js/qwebactionmanager.js
@@ -44,7 +44,6 @@ var make_report_url = function (action) {
     var report_urls = {
         'qweb-html': '/report/html/' + action.report_name,
         'qweb-pdf': '/report/pdf/' + action.report_name,
-        'controller': action.report_file,
     };
     // We may have to build a query string with `action.data`. It's the place
     // were report's using a wizard to customize the output traditionally put
@@ -69,7 +68,7 @@ var make_report_url = function (action) {
 };
 
 ActionManager.include({
-    ir_actions_report_xml: function (action, options) {
+    ir_actions_report: function (action, options) {
         var self = this;
         action = _.clone(action);
 
@@ -132,14 +131,6 @@ ActionManager.include({
                     return self.do_action('report.client_action', client_action_options);
                 }
             });
-        } else if (action.report_type === 'controller') {
-            framework.blockUI();
-            var response = [
-                report_urls.controller,
-                action.report_type,
-            ];
-            var c = crash_manager;
-            return trigger_download(self.getSession(), response, c, action, options);
         } else {
             return self._super(action, options);
         }
diff --git a/addons/report/tests/test_reports.py b/addons/report/tests/test_reports.py
index d1e85494f48b726b12ece79bf95ab0140d253c96..9995067fdecda614898ae4493fe73f4252e19ae3 100644
--- a/addons/report/tests/test_reports.py
+++ b/addons/report/tests/test_reports.py
@@ -14,7 +14,7 @@ _logger = logging.getLogger(__name__)
 class TestReports(odoo.tests.TransactionCase):
     def test_reports(self):
         domain = [('report_type', 'like', 'qweb')]
-        for report in self.env['ir.actions.report.xml'].search(domain):
+        for report in self.env['ir.actions.report'].search(domain):
             report_model = 'report.%s' % report.report_name
             try:
                 self.env[report_model]
diff --git a/addons/report/views/ir_actions_report_views.xml b/addons/report/views/ir_actions_report_views.xml
index d0202203b7681f57f9670440e8cfa118f4b413eb..7b52158a0471566531078582323049006c0578f9 100644
--- a/addons/report/views/ir_actions_report_views.xml
+++ b/addons/report/views/ir_actions_report_views.xml
@@ -2,9 +2,9 @@
 <odoo>
         <!-- Adding a print_report_name field inside to the report action form view -->
         <record id="act_report_xml_view_inherit_report" model="ir.ui.view">
-            <field name="name">ir.actions.report.xml.form.inherit</field>
+            <field name="name">ir.actions.report.form.inherit</field>
             <field name="inherit_id" ref="base.act_report_xml_view" />
-            <field name="model">ir.actions.report.xml</field>
+            <field name="model">ir.actions.report</field>
             <field name="arch" type="xml">
                 <data>
                     <xpath expr="//field[@name='report_name']" position="after">
@@ -18,7 +18,7 @@
         <record id="act_report_xml_view_inherit" model="ir.ui.view">
             <field name="name">act_report_xml_view_inherit</field>
             <field name="inherit_id" ref="base.act_report_xml_view" />
-            <field name="model">ir.actions.report.xml</field>
+            <field name="model">ir.actions.report</field>
             <field name="arch" type="xml">
                 <data>
                     <xpath expr="//field[@name='report_type']" position="after">
diff --git a/addons/report/views/report_paperformat_views.xml b/addons/report/views/report_paperformat_views.xml
index 433ed8cc3044ae5d2809fd4e6f19d5fd32b7815a..2141f63b91448a106a2116f94be0693a555d2e43 100644
--- a/addons/report/views/report_paperformat_views.xml
+++ b/addons/report/views/report_paperformat_views.xml
@@ -42,7 +42,7 @@
         </record>
         <record id='reports_action' model='ir.actions.act_window'>
             <field name="name">Reports</field>
-            <field name="res_model">ir.actions.report.xml</field>
+            <field name="res_model">ir.actions.report</field>
             <field name="view_type">form</field>
             <field name="view_mode">tree,form</field>
         </record>
diff --git a/addons/report/views/templates.xml b/addons/report/views/templates.xml
index c9f6f6157b44140626c627c0facb121de58a37eb..667013df74f51ac9abe9d3c3620bdeac8998fe30 100644
--- a/addons/report/views/templates.xml
+++ b/addons/report/views/templates.xml
@@ -138,7 +138,7 @@
 <template id="external_layout_background">
     <div class="header o_background_header">
         <div class="pull-right">
-            <h3 class="mt0 text-right" t-field="company.rml_header1"/>
+            <h3 class="mt0 text-right" t-field="company.report_header"/>
         </div>
         <img t-if="company.logo" t-att-src="'data:image/png;base64,%s' % company.logo" class="pull-left"/>
         <div class="pull-left company_address">
@@ -164,7 +164,7 @@
                 <li t-if="company.website"><i class="fa fa-globe"></i> <span t-field="company.website"/></li>
                 <li t-if="company.vat"><i class="fa fa-building-o"></i> VAT: <span t-field="company.vat"/></li>
             </ul>
-            <div t-field="company.rml_footer"/>
+            <div t-field="company.report_footer"/>
             <div class="text-muted">
                 Page:
                 <span class="page"/>
@@ -182,7 +182,7 @@
                 <img t-if="company.logo" t-att-src="'data:image/png;base64,%s' % company.logo"/>
             </div>
             <div class="col-xs-6 text-right mb4">
-                <h4 class="mt0" t-field="company.rml_header1"/>
+                <h4 class="mt0" t-field="company.report_header"/>
                 <div name="company_address" class="mb4">
                     <span class="company_address" t-field="company.partner_id"
                         t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/>
@@ -204,7 +204,7 @@
                 <li t-if="company.website">Web: <span t-field="company.website"/></li>
                 <li t-if="company.vat">VAT: <span t-field="company.vat"/></li>
             </ul>
-            <div t-field="company.rml_footer"/>
+            <div t-field="company.report_footer"/>
             <div>
                 Page: <span class="page"/> / <span class="topage"/>
             </div>
@@ -238,14 +238,14 @@
     <div class="footer o_clean_footer">
         <div class="row mt8">
             <div class="col-xs-3">
-                <span t-field="company.rml_footer"/>
+                <span t-field="company.report_footer"/>
             </div>
             <div class="col-xs-4 text-right">
                 <span class="company_address" t-field="company.partner_id"
                     t-field-options='{"widget": "contact", "fields": ["address"], "no_marker": true}'/>
             </div>
             <div class="col-xs-4">
-                <h4 class="mt0 mb0 text-uppercase" t-field="company.rml_header1"/>
+                <h4 class="mt0 mb0 text-uppercase" t-field="company.report_header"/>
             </div>
             <div class="col-xs-1">
                 <ul class="list-inline pagenumber pull-right text-center">
@@ -262,9 +262,9 @@
             <div class="col-xs-3 mb4">
                 <img t-if="company.logo" t-att-src="'data:image/png;base64,%s' % company.logo" style="max-height: 45px;"/>
             </div>
-            <div class="col-xs-9 text-right" style="margin-top:22px;" t-field="company.rml_header1" name="moto"/>
+            <div class="col-xs-9 text-right" style="margin-top:22px;" t-field="company.report_header" name="moto"/>
         </div>
-        <div t-if="company.logo or company.rml_header1" class="row zero_min_height">
+        <div t-if="company.logo or company.report_header" class="row zero_min_height">
             <div class="col-xs-12">
                 <div style="border-bottom: 1px solid black;"></div>
             </div>
@@ -293,7 +293,7 @@
             </ul>
 
             <div name="financial_infos">
-                <span t-field="company.rml_footer"/>
+                <span t-field="company.report_footer"/>
             </div>
 
             <div class="text-muted">
diff --git a/addons/report_intrastat/report/report_intrastat_report.xml b/addons/report_intrastat/report/report_intrastat_report.xml
index 12df16c12c6c6f4604a1cb5bfd8247f12efc583f..126c059b109249f5c5b1f1afd0349ec141f441c4 100644
--- a/addons/report_intrastat/report/report_intrastat_report.xml
+++ b/addons/report_intrastat/report/report_intrastat_report.xml
@@ -8,7 +8,7 @@
         name="report_intrastat.report_intrastatinvoice"
         file="report_intrastat.report_intrastatinvoice"
     />
-    <record id="account_intrastatinvoices" model="ir.actions.report.xml">
+    <record id="account_intrastatinvoices" model="ir.actions.report">
         <field name="print_report_name">(object.type == 'out_invoice' and object.state == 'draft' and 'Intrastat Invoice' or
         object.type == 'out_invoice' and object.state in ('open','paid') and 'Intrastat Invoice'+'-'+(object.number) or
         object.type == 'out_refund' and object.state == 'draft' and 'Intrastat Credit Note' or
diff --git a/addons/report_intrastat/tests/test_report_intrastat.py b/addons/report_intrastat/tests/test_report_intrastat.py
index 90d688f922bd084830e22e4a3425fb0e39a982c3..89b03830eb7a78e8cd03c5700bfcd8b3947566f7 100644
--- a/addons/report_intrastat/tests/test_report_intrastat.py
+++ b/addons/report_intrastat/tests/test_report_intrastat.py
@@ -29,6 +29,6 @@ class RepoortIntrastatTest(common.TransactionCase):
         })
 
     def test_00_create_pdf(self):
-        data, report_format = self.env['ir.actions.report.xml'].render_report(self.invoice.ids, 'report_intrastat.report_intrastatinvoice', {})
+        data, data_format = self.env.ref('report_intrastat.account_intrastatinvoices').render(self.invoice.ids)
         if tools.config['test_report_directory']:
-            open(os.path.join(tools.config['test_report_directory'], 'report_intrastat-intrastat_report.' + report_format), 'wb+').write(data)
+            open(os.path.join(tools.config['test_report_directory'], 'report_intrastat-intrastat_report.' + data_format), 'wb+').write(data)
diff --git a/addons/sale/report/sale_report.xml b/addons/sale/report/sale_report.xml
index 3e4996dffe2e05eae12764972e3e0aec1169b981..ff8a1f5f15e4b784398c55a471a1220a307c89f4 100644
--- a/addons/sale/report/sale_report.xml
+++ b/addons/sale/report/sale_report.xml
@@ -9,7 +9,7 @@
             file="sale.report_saleorder" 
             name="sale.report_saleorder" 
         />
-        <record id="report_sale_order" model="ir.actions.report.xml">
+        <record id="report_sale_order" model="ir.actions.report">
             <field name="print_report_name">(object.state in ('draft', 'sent') and 'Quotation'+'-'+(object.name) or 'Order'+'-'+(object.name))</field>
         </record>
 
@@ -21,7 +21,7 @@
             name="sale.report_saleproforma"
             file="sale.report_saleorder"
         />
-        <record id="report_proforma_quotation" model="ir.actions.report.xml">
+        <record id="report_proforma_quotation" model="ir.actions.report">
             <field name="print_report_name">'Pro-Forma'+'-'+(object.name)</field>
         </record>
     </data>
diff --git a/addons/stock/report/stock_report_views.xml b/addons/stock/report/stock_report_views.xml
index cb9af6d109e35220efd1972cea6bd7036f6a62a2..84988bfdb6adedc5a2bdd0a5118bfdcbed85cc5d 100644
--- a/addons/stock/report/stock_report_views.xml
+++ b/addons/stock/report/stock_report_views.xml
@@ -9,7 +9,7 @@
             name="stock.report_picking"
             file="stock.report_picking_operations"
         />
-        <record id="action_report_picking" model="ir.actions.report.xml">
+        <record id="action_report_picking" model="ir.actions.report">
             <field name="print_report_name">'Picking Operations'+'-'+(object.partner_id.name or '')+'-'+(object.name)</field>
         </record>
         <report
@@ -20,7 +20,7 @@
             name="stock.report_deliveryslip"
             file="stock.report_deliveryslip"
         />
-        <record id="action_report_delivery" model="ir.actions.report.xml">
+        <record id="action_report_delivery" model="ir.actions.report">
             <field name="print_report_name">'Delivery Slip'+'-'+(object.partner_id.name or '')+'-'+(object.name)</field>
         </record>
         <report
@@ -31,17 +31,17 @@
             name="stock.report_inventory" 
             file="stock.report_inventory" 
         />
-        <record id="action_report_inventory" model="ir.actions.report.xml">
+        <record id="action_report_inventory" model="ir.actions.report">
             <field name="print_report_name">'Inventory'+'-'+(object.name)</field>
         </record>
         <report id="action_report_quant_package_barcode" model="stock.quant.package" report_type="qweb-pdf" name="stock.report_package_barcode" string="Package BarCode with Contents" file="stock.report_package_barcode"/>
         <report id="action_report_quant_package_barcode_small" model="stock.quant.package" report_type="qweb-pdf" name="stock.report_package_barcode_small" string="Package BarCode" file="stock.report_package_barcode"/>
         <report id="action_report_location_barcode" model="stock.location" report_type="qweb-pdf" name="stock.report_location_barcode" string="Location BarCode" file="stock.report_location_barcode"/>
-        <record id="action_report_location_barcode" model="ir.actions.report.xml">
+        <record id="action_report_location_barcode" model="ir.actions.report">
             <field name="print_report_name">(object.name)+'-'+'Location'</field>
         </record>
         <report id="action_report_lot_barcode" model="stock.production.lot" report_type="qweb-pdf" name="stock.report_lot_barcode" string="Lot BarCode" file="stock.report_lot_barcode"/>
-        <record id="action_report_lot_barcode" model="ir.actions.report.xml">
+        <record id="action_report_lot_barcode" model="ir.actions.report">
             <field name="print_report_name">'Lot/Serial'+'-'+(object.name)</field>
         </record>
     </data>
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index 700f19d816879a717753fd387a71f55c5b0815ba..1a86ca97823521219761572e57bbce72ab2c2699 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -1157,7 +1157,7 @@ class Action(http.Controller):
         if base_action:
             ctx = dict(request.context)
             action_type = base_action[0]['type']
-            if action_type == 'ir.actions.report.xml':
+            if action_type == 'ir.actions.report':
                 ctx.update({'bin_size': True})
             if additional_context:
                 ctx.update(additional_context)
@@ -1498,7 +1498,7 @@ class Reports(http.Controller):
             report_struct['format'], 'octet-stream')
         file_name = action.get('name', 'report')
         if 'name' not in action:
-            reports = request.env['ir.actions.report.xml']
+            reports = request.env['ir.actions.report']
             reports = reports.search([('report_name', '=', action['report_name'])])
             if reports:
                 file_name = reports[0].name
diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js
index 934473109a3bff4450e0028505ef3cec9e4338c9..b02376ef6b71c4690a4fbec55fafd2f4a20f1175 100644
--- a/addons/web/static/src/js/chrome/action_manager.js
+++ b/addons/web/static/src/js/chrome/action_manager.js
@@ -861,7 +861,7 @@ var ActionManager = Widget.extend({
                 return self.do_action(action, options);
             });
     },
-    ir_actions_report_xml: function(action, options) {
+    ir_actions_report: function(action, options) {
         var self = this;
         framework.blockUI();
         action = _.clone(action);
diff --git a/addons/website_quote/report/sale_order_reports.xml b/addons/website_quote/report/sale_order_reports.xml
index 1aeaf7c6e0e66fc015220df45744b57fd112bac6..c3c8078545f4b102c4d259062d311121e0bb87f2 100644
--- a/addons/website_quote/report/sale_order_reports.xml
+++ b/addons/website_quote/report/sale_order_reports.xml
@@ -9,7 +9,7 @@
             name="website_quote.report_quote" 
             menu="False"
         />
-        <record id="report_web_quote" model="ir.actions.report.xml">
+        <record id="report_web_quote" model="ir.actions.report">
             <field name="print_report_name">(object.state in ('draft', 'sent') and 'Quotation'+'-'+(object.name) or 'Order'+'-'+(object.name))</field>
         </record>
 </odoo>
diff --git a/doc/api_integration.rst b/doc/api_integration.rst
index 1345915d7979a83162fb621d2aa5dbd60fbfde14..612e91ed85422cd43cf952266c2c9abea9c3627e 100644
--- a/doc/api_integration.rst
+++ b/doc/api_integration.rst
@@ -1298,7 +1298,7 @@ activated as actual fields on the model.
 Report printing
 ---------------
 
-Available reports can be listed by searching the ``ir.actions.report.xml``
+Available reports can be listed by searching the ``ir.actions.report``
 model, fields of interest being
 
 ``model``
diff --git a/doc/howtos/backend.rst b/doc/howtos/backend.rst
index 4d48a6d7de32d778c6cc7671d1dc925a589a7752..bffebe587bbf40382454734ac3963f7e60c644c1 100644
--- a/doc/howtos/backend.rst
+++ b/doc/howtos/backend.rst
@@ -1502,7 +1502,7 @@ Odoo 8.0 comes with a new report engine based on :ref:`reference/qweb`,
 
 A report is a combination two elements:
 
-* an ``ir.actions.report.xml``, for which a ``<report>`` shortcut element is
+* an ``ir.actions.report``, for which a ``<report>`` shortcut element is
   provided, it sets up various basic parameters for the report (default
   type, whether the report should be saved to the database after generation,…)
 
diff --git a/doc/reference/actions.rst b/doc/reference/actions.rst
index fb9d3255cdbe1f038e0dfcc4be282982817b25c2..904cb89db135dd1537f4f74f31bcb469018f3c42 100644
--- a/doc/reference/actions.rst
+++ b/doc/reference/actions.rst
@@ -358,8 +358,8 @@ server actions:
 
 .. _reference/actions/report:
 
-Report Actions (``ir.actions.report.xml``)
-==========================================
+Report Actions (``ir.actions.report``)
+======================================
 
 Triggers the printing of a report
 
diff --git a/doc/reference/data.rst b/doc/reference/data.rst
index c8ebf864a880a5fa72bf6b0c7fb97d24a325a336..fd597fcb4a51a5144067706a6436bd5e0d295e26 100644
--- a/doc/reference/data.rst
+++ b/doc/reference/data.rst
@@ -218,10 +218,10 @@ section of the view, and allowing a few *optional* attributes:
 ``report``
 ----------
 
-Creates a ``ir.actions.report.xml`` record with a few default values.
+Creates a ``ir.actions.report`` record with a few default values.
 
 Mostly just proxies attributes to the corresponding fields on
-``ir.actions.report.xml``, but also automatically creates the item in the
+``ir.actions.report``, but also automatically creates the item in the
 :guilabel:`More` menu of the report's ``model``.
 
 .. ignored url, act_window and ir_set
diff --git a/odoo/__init__.py b/odoo/__init__.py
index 4c074c9beb366920ab769019b0dd592dba1e671e..3c3b14fdadc6deee544f202d6162259af9827224 100644
--- a/odoo/__init__.py
+++ b/odoo/__init__.py
@@ -61,7 +61,6 @@ from . import modules
 from . import netsvc
 from . import osv
 from . import release
-from . import report
 from . import service
 from . import sql_db
 from . import tools
diff --git a/odoo/addons/base/base_data.xml b/odoo/addons/base/base_data.xml
index 322cd3ae3244af72e4f46df60fd38b1de93140c3..7c90d0b96e99b90510ea02de8357b26203014069 100644
--- a/odoo/addons/base/base_data.xml
+++ b/odoo/addons/base/base_data.xml
@@ -67,26 +67,6 @@ Administrator</span>]]></field>
             <field eval="10" name="sequence"/>
         </record>
 
-        <!-- Basic fonts family included in PDF standart, will always be in the font list -->
-        <record model="res.font" id="base.font_helvetica">
-            <field name="name">Helvetica</field>
-            <field name="family">Helvetica</field>
-            <field name="path">/dev/null</field>
-            <field name="mode">all</field>
-        </record>
-        <record model="res.font" id="base.font_times">
-            <field name="name">Times</field>
-            <field name="family">Times</field>
-            <field name="path">/dev/null</field>
-            <field name="mode">all</field>
-        </record>
-        <record model="res.font" id="base.font_courier">
-            <field name="name">Courier</field>
-            <field name="family">Courier</field>
-            <field name="path">/dev/null</field>
-            <field name="mode">all</field>
-        </record>
-
         <record id="public_partner" model="res.partner">
             <field name="name">Public user</field>
             <field name="active" eval="False"/>
diff --git a/odoo/addons/base/ir/ir_actions.py b/odoo/addons/base/ir/ir_actions.py
index b174b1c45e2c2725e076e606419b61c790024b82..959b9b3f740176b019b8680da5368d4d7842aa23 100644
--- a/odoo/addons/base/ir/ir_actions.py
+++ b/odoo/addons/base/ir/ir_actions.py
@@ -11,7 +11,6 @@ from pytz import timezone
 import odoo
 from odoo import api, fields, models, tools, _
 from odoo.exceptions import MissingError, UserError, ValidationError
-from odoo.report.report_sxw import report_sxw, report_rml
 from odoo.tools.safe_eval import safe_eval, test_python_expr
 
 _logger = logging.getLogger(__name__)
@@ -72,24 +71,18 @@ class IrActions(models.Model):
         }
 
 
-class IrActionsReportXml(models.Model):
-    _name = 'ir.actions.report.xml'
+class IrActionsReport(models.Model):
+    _name = 'ir.actions.report'
     _inherit = 'ir.actions.actions'
     _table = 'ir_act_report_xml'
     _sequence = 'ir_actions_id_seq'
     _order = 'name'
 
     name = fields.Char(translate=True)
-    type = fields.Char(default='ir.actions.report.xml')
+    type = fields.Char(default='ir.actions.report')
 
     model = fields.Char(required=True)
-    report_type = fields.Selection([('qweb-pdf', 'PDF'),
-                                    ('qweb-html', 'HTML'),
-                                    ('controller', 'Controller'),
-                                    ('pdf', 'RML pdf (deprecated)'),
-                                    ('sxw', 'RML sxw (deprecated)'),
-                                    ('webkit', 'Webkit (deprecated)')],
-                                   required=True, default="pdf",
+    report_type = fields.Selection([('qweb-pdf', 'PDF'), ('qweb-html', 'HTML')], required=True, default="pdf",
                                    help="HTML will open the report directly in your browser, PDF will use wkhtmltopdf to render the HTML into a PDF file and let you download it, Controller allows you to define the url of a custom controller outputting any kind of report.")
     report_name = fields.Char(string='Template Name', required=True,
                               help="For QWeb reports, name of the template used in the rendering. The method 'render_html' of the model 'report.template_name' will be called (if any) to give the html. For RML reports, this is the LocalService name.")
@@ -108,88 +101,9 @@ class IrActionsReportXml(models.Model):
     parser = fields.Char(string='Parser Class')
     auto = fields.Boolean(string='Custom Python Parser', default=True)
 
-    report_xsl = fields.Char(string='XSL Path')
-    report_xml = fields.Char(string='XML Path')
-
-    report_rml = fields.Char(string='Main Report File Path/controller', help="The path to the main report file/controller (depending on Report Type) or empty if the content is in another data field")
-    report_file = fields.Char(related='report_rml', string='Report File', required=False, readonly=False, store=True,
+    report_file = fields.Char(string='Report File', required=False, readonly=False, store=True,
                               help="The path to the main report file (depending on Report Type) or empty if the content is in another field")
 
-    report_sxw = fields.Char(compute='_compute_report_sxw', string='SXW Path')
-    report_sxw_content_data = fields.Binary(string='SXW Content')
-    report_rml_content_data = fields.Binary(string='RML Content')
-    report_sxw_content = fields.Binary(compute='_compute_report_sxw_content', inverse='_inverse_report_sxw_content', string='SXW Content')
-    report_rml_content = fields.Binary(compute='_compute_report_rml_content', inverse='_inverse_report_rml_content', string='RML Content')
-
-    @api.depends('report_rml')
-    def _compute_report_sxw(self):
-        for report in self:
-            if report.report_rml:
-                self.report_sxw = report.report_rml.replace('.rml', '.sxw')
-
-    def _report_content(self, name):
-        data = self[name + '_content_data']
-        if not data and self[name]:
-            try:
-                with tools.file_open(self[name], mode='rb') as fp:
-                    data = fp.read()
-            except Exception:
-                data = False
-        return data
-
-    @api.depends('report_sxw', 'report_sxw_content_data')
-    def _compute_report_sxw_content(self):
-        for report in self:
-            report.report_sxw_content = report._report_content('report_sxw')
-
-    @api.depends('report_rml', 'report_rml_content_data')
-    def _compute_report_rml_content(self):
-        for report in self:
-            report.report_rml_content = report._report_content('report_rml')
-
-    def _inverse_report_sxw_content(self):
-        for report in self:
-            report.report_sxw_content_data = report.report_sxw_content
-
-    def _inverse_report_rml_content(self):
-        for report in self:
-            report.report_rml_content_data = report.report_rml_content
-
-    @api.model_cr
-    def _lookup_report(self, name):
-        """
-        Look up a report definition.
-        """
-        join = os.path.join
-
-        # First lookup in the deprecated place, because if the report definition
-        # has not been updated, it is more likely the correct definition is there.
-        # Only reports with custom parser sepcified in Python are still there.
-        if 'report.' + name in odoo.report.interface.report_int._reports:
-            return odoo.report.interface.report_int._reports['report.' + name]
-
-        self._cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,))
-        row = self._cr.dictfetchone()
-        if not row:
-            raise Exception("Required report does not exist: %s" % name)
-
-        if row['report_type'] in ('qweb-pdf', 'qweb-html'):
-            return row['report_name']
-        elif row['report_rml'] or row['report_rml_content_data']:
-            kwargs = {}
-            if row['parser']:
-                kwargs['parser'] = getattr(odoo.addons, row['parser'])
-            return report_sxw('report.'+row['report_name'], row['model'],
-                              join('addons', row['report_rml'] or '/'),
-                              header=row['header'], register=False, **kwargs)
-        elif row['report_xsl'] and row['report_xml']:
-            return report_rml('report.'+row['report_name'], row['model'],
-                              join('addons', row['report_xml']),
-                              row['report_xsl'] and join('addons', row['report_xsl']),
-                              register=False)
-        else:
-            raise Exception("Unhandled report type: %s" % row)
-
     @api.multi
     def create_action(self):
         """ Create a contextual action for each report. """
@@ -198,7 +112,7 @@ class IrActionsReportXml(models.Model):
                 'name': report.name,
                 'model': report.model,
                 'key2': 'client_print_multi',
-                'value': "ir.actions.report.xml,%s" % report.id,
+                'value': "ir.actions.report,%s" % report.id,
             })
             report.write({'ir_values_id': ir_values.id})
         return True
@@ -216,21 +130,26 @@ class IrActionsReportXml(models.Model):
         return True
 
     @api.model
-    def render_report(self, res_ids, name, data):
-        """
-        Look up a report definition and render the report for the provided IDs.
-        """
-        report = self._lookup_report(name)
-        if isinstance(report, basestring):  # Qweb report
-            # The only case where a QWeb report is rendered with this method occurs when running
-            # yml tests originally written for RML reports.
-            if tools.config['test_enable'] and not tools.config['test_report_directory']:
-                # Only generate the pdf when a destination folder has been provided.
-                return self.env['report'].get_html(res_ids, report, data=data), 'html'
-            else:
-                return self.env['report'].get_pdf(res_ids, report, data=data), 'pdf'
-        else:
-            return report.create(self._cr, self._uid, res_ids, data, context=self._context)
+    def render_html(self, res_ids, data=None):
+        return self.env['report'].get_html(res_ids, self.report_name, data=data), 'html'
+
+    @api.multi
+    def render_pdf(self, res_ids, data=None):
+        # In case of test environment without enough workers to perform calls to wkhtmltopdf,
+        # fallback to render_html.
+        if tools.config['test_enable'] and not tools.config['test_report_directory']:
+            return self.render_html(res_ids, data=data)
+        return self.env['report'].get_pdf(res_ids, self.report_name, data=data), 'pdf'
+
+    @api.multi
+    def render(self, res_ids, data=None):
+        report_type = self.report_type.lower()
+        if report_type.startswith('qweb-'):
+            report_type = report_type[5:]
+        render_func = getattr(self, 'render_' + report_type, None)
+        if not render_func:
+            return None
+        return render_func(res_ids, data=data)
 
 
 class IrActionsActWindow(models.Model):
diff --git a/odoo/addons/base/ir/ir_actions.xml b/odoo/addons/base/ir/ir_actions.xml
index 750ee14efdb29ac4d66874140b817829e67e11c9..1d26521bb56e4da39edd88697cc23a532ad82072 100644
--- a/odoo/addons/base/ir/ir_actions.xml
+++ b/odoo/addons/base/ir/ir_actions.xml
@@ -45,11 +45,11 @@
         <menuitem id="next_id_6" name="Actions" parent="base.menu_custom" sequence="5"/>
         <menuitem action="ir_sequence_actions" id="menu_ir_sequence_actions" parent="next_id_6"/>
 
-        <!-- ir.actions.report.xml -->
+        <!-- ir.actions.report -->
 
         <record id="act_report_xml_view" model="ir.ui.view">
-            <field name="name">ir.actions.report.xml</field>
-            <field name="model">ir.actions.report.xml</field>
+            <field name="name">ir.actions.report</field>
+            <field name="model">ir.actions.report</field>
             <field name="arch" type="xml">
                 <form string="Report">
                     <field name="ir_values_id" invisible="1"/>
@@ -69,33 +69,18 @@
                             </group>
                             <group>
                                 <field name="model"/>
-                                <field name="report_name" attrs="{'invisible':[('report_type','=', 'controller')]}"/>
-                                <field name="report_rml" attrs="{'invisible':[('report_type','!=', 'controller')]}"/>
+                                <field name="report_name"/>
                             </group>
                         </group>
                         <notebook>
                             <page name="security" string="Security">
                                 <field name="groups_id"/>
                             </page>
-                            <page name='rml' string="RML Configuration" attrs="{'invisible':[('report_type','not in',['pdf','sxw'])]}">
-                                <group>
-                                    <group string="RML Report">
-                                        <field name="header"/>
-                                        <field name="report_file"/>
-                                        <field name="auto"/>
-                                        <field name="parser"/>
-                                    </group>
-                                    <group string="XML Report">
-                                        <field name="report_xsl"/>
-                                        <field name="report_xml"/>
-                                    </group>
-                                </group>
-                            </page>
                             <page name='advanced' string="Advanced Properties">
                                 <group>
                                     <field name="multi"/>
-                                    <field name="attachment_use" attrs="{'invisible':[('report_type','=', 'controller')]}"/>
-                                    <field name="attachment" attrs="{'invisible':[('report_type','=', 'controller')]}"/>
+                                    <field name="attachment_use"/>
+                                    <field name="attachment"/>
                                 </group>
                             </page>
                         </notebook>
@@ -104,8 +89,8 @@
             </field>
         </record>
         <record id="act_report_xml_view_tree" model="ir.ui.view">
-            <field name="name">ir.actions.report.xml.tree</field>
-            <field name="model">ir.actions.report.xml</field>
+            <field name="name">ir.actions.report.tree</field>
+            <field name="model">ir.actions.report</field>
             <field name="arch" type="xml">
                 <tree string="Report xml">
                     <field name="name"/>
@@ -118,8 +103,8 @@
             </field>
         </record>
         <record id="act_report_xml_search_view" model="ir.ui.view">
-            <field name="name">ir.actions.report.xml.search</field>
-            <field name="model">ir.actions.report.xml</field>
+            <field name="name">ir.actions.report.search</field>
+            <field name="model">ir.actions.report</field>
             <field name="arch" type="xml">
                 <search string="Report Xml">
                     <field name="name"
@@ -133,15 +118,15 @@
                 </search>
             </field>
         </record>
-        <record id="ir_action_report_xml" model="ir.actions.act_window">
+        <record id="ir_action_report" model="ir.actions.act_window">
             <field name="name">Reports</field>
             <field name="type">ir.actions.act_window</field>
-            <field name="res_model">ir.actions.report.xml</field>
+            <field name="res_model">ir.actions.report</field>
             <field name="view_type">form</field>
             <field name="view_id" ref="act_report_xml_view_tree"/>
             <field name="search_view_id" ref="act_report_xml_search_view"/>
         </record>
-        <menuitem action="ir_action_report_xml" id="menu_ir_action_report_xml" parent="base.next_id_6"/>
+        <menuitem action="ir_action_report" id="menu_ir_action_report" parent="base.next_id_6"/>
 
         <!-- ir.actions.act_window -->
 
diff --git a/odoo/addons/base/ir/ir_ui_menu.py b/odoo/addons/base/ir/ir_ui_menu.py
index c8a393228350f4d70eac14db23dd63fbd7fc5408..b4bebf0e9a89492f0aeb0722323926a66cab623d 100644
--- a/odoo/addons/base/ir/ir_ui_menu.py
+++ b/odoo/addons/base/ir/ir_ui_menu.py
@@ -37,7 +37,7 @@ class IrUiMenu(models.Model):
                                       "If this field is empty, Odoo will compute visibility based on the related object's read access.")
     complete_name = fields.Char(compute='_compute_complete_name', string='Full Path')
     web_icon = fields.Char(string='Web Icon File')
-    action = fields.Reference(selection=[('ir.actions.report.xml', 'ir.actions.report.xml'),
+    action = fields.Reference(selection=[('ir.actions.report', 'ir.actions.report'),
                                          ('ir.actions.act_window', 'ir.actions.act_window'),
                                          ('ir.actions.act_url', 'ir.actions.act_url'),
                                          ('ir.actions.server', 'ir.actions.server'),
@@ -99,7 +99,7 @@ class IrUiMenu(models.Model):
         access = self.env['ir.model.access']
         MODEL_GETTER = {
             'ir.actions.act_window': lambda action: action.res_model,
-            'ir.actions.report.xml': lambda action: action.model,
+            'ir.actions.report': lambda action: action.model,
             'ir.actions.server': lambda action: action.model_id.model,
         }
         for menu in action_menus:
diff --git a/odoo/addons/base/ir/ir_values.py b/odoo/addons/base/ir/ir_values.py
index ccd971e26e401ea67f240ef1b2fc54899bcee6e9..3672d7811c21e4c914c38954bff28486ed53f66b 100644
--- a/odoo/addons/base/ir/ir_values.py
+++ b/odoo/addons/base/ir/ir_values.py
@@ -10,11 +10,6 @@ from odoo.tools import pickle
 import logging
 _logger = logging.getLogger(__name__)
 
-
-EXCLUDED_FIELDS = set(('code',
-    'report_sxw_content', 'report_rml_content', 'report_sxw', 'report_rml',
-    'report_sxw_content_data', 'report_rml_content_data', 'search_view', ))
-
 #: Possible slots to bind an action to with :meth:`~.set_action`
 ACTION_SLOTS = [
     "client_action_multi",      # sidebar wizard action
@@ -419,14 +414,10 @@ class IrValues(models.Model):
         # process values and their action
         results = {}
         for id, name, action in actions:
-            fields = [field for field in action._fields if field not in EXCLUDED_FIELDS]
             # FIXME: needs cleanup
             try:
-                action_def = {
-                    field: action._fields[field].convert_to_read(action[field], action)
-                    for field in fields
-                }
-                if action._name in ('ir.actions.report.xml', 'ir.actions.act_window'):
+                action_def = dict([(k, v.convert_to_read(action[k], action)) for k, v in action._fields.items()])
+                if action._name in ('ir.actions.report', 'ir.actions.act_window'):
                     if action.groups_id and not action.groups_id & self.env.user.groups_id:
                         if name == 'Menuitem':
                             raise AccessError(_('You do not have the permission to perform this operation!!!'))
diff --git a/odoo/addons/base/module/module.py b/odoo/addons/base/module/module.py
index f95c2b07dc1fac01935f104933383d0eeb85465b..ae36ccd17277716ed906b266fe1df620d3957150 100644
--- a/odoo/addons/base/module/module.py
+++ b/odoo/addons/base/module/module.py
@@ -184,7 +184,7 @@ class Module(models.Model):
     @api.depends('name', 'state')
     def _get_views(self):
         IrModelData = self.env['ir.model.data'].with_context(active_test=True)
-        dmodels = ['ir.ui.view', 'ir.actions.report.xml', 'ir.ui.menu']
+        dmodels = ['ir.ui.view', 'ir.actions.report', 'ir.ui.menu']
 
         for module in self:
             # Skip uninstalled modules below, no data to find anyway.
@@ -210,7 +210,7 @@ class Module(models.Model):
                 return '%s%s (%s)' % (v.inherit_id and '* INHERIT ' or '', v.name, v.type)
 
             module.views_by_module = "\n".join(sorted(map(format_view, browse('ir.ui.view'))))
-            module.reports_by_module = "\n".join(sorted(map(attrgetter('name'), browse('ir.actions.report.xml'))))
+            module.reports_by_module = "\n".join(sorted(map(attrgetter('name'), browse('ir.actions.report'))))
             module.menus_by_module = "\n".join(sorted(map(attrgetter('complete_name'), browse('ir.ui.menu'))))
 
     @api.depends('icon')
diff --git a/odoo/addons/base/report/__init__.py b/odoo/addons/base/report/__init__.py
deleted file mode 100644
index 6ce403b6633706a4dd273b3d18701b3102b693d5..0000000000000000000000000000000000000000
--- a/odoo/addons/base/report/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import preview_report
diff --git a/odoo/addons/base/report/corporate_defaults.xml b/odoo/addons/base/report/corporate_defaults.xml
index 751693e7e8931e923aa188b56e499be41a9603b7..3e99caf9d48d4c899bfbfb40d99f56ea7d702827 100644
--- a/odoo/addons/base/report/corporate_defaults.xml
+++ b/odoo/addons/base/report/corporate_defaults.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <corporate-header>
     <corporation type="zoom" name="company_id">
-        <rml_header1 type="field" name="rml_header1"/>
-        <rml_footer type="field" name="rml_footer"/>
+        <report_header type="field" name="report_header"/>
+        <report_footer type="field" name="report_footer"/>
         <title type="field" name="partner_id.title"/>
         <name type="field" name="partner_id.name"/>
         <street type="field" name="street"/>
diff --git a/odoo/addons/base/report/corporate_sxw_header.xml b/odoo/addons/base/report/corporate_sxw_header.xml
index 6cd8e5a218fbaf5971560a5bc8b90a3b4e230a09..2705f8703725892d85b05ba168036a7a21f68543 100644
--- a/odoo/addons/base/report/corporate_sxw_header.xml
+++ b/odoo/addons/base/report/corporate_sxw_header.xml
@@ -200,7 +200,7 @@
                             <text:p text:style-name="P1">[[ company.partner_id.name ]]</text:p>
                         </table:table-cell>
                         <table:table-cell table:style-name="Table2.A1" table:value-type="string">
-                            <text:p text:style-name="P2">[[ company.rml_header1 ]]</text:p>
+                            <text:p text:style-name="P2">[[ company.report_header ]]</text:p>
                         </table:table-cell>
                     </table:table-row>
                 </table:table>
@@ -233,7 +233,7 @@
                     <table:table-column table:style-name="Table1.A"/>
                     <table:table-row>
                         <table:table-cell table:style-name="Table1.A1" table:value-type="string">
-                            <text:p text:style-name="P7">[[ company.rml_footer ]]</text:p>
+                            <text:p text:style-name="P7">[[ company.report_footer ]]</text:p>
                             <text:p text:style-name="P7">Contact : [[ user.name ]]</text:p>
                         </table:table-cell>
                     </table:table-row>
diff --git a/odoo/addons/base/report/preview_report.py b/odoo/addons/base/report/preview_report.py
deleted file mode 100644
index 68f380984210472163fdb3a85759a003d648e3b9..0000000000000000000000000000000000000000
--- a/odoo/addons/base/report/preview_report.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from odoo.report import report_sxw
-
-class rmlparser(report_sxw.rml_parse):
-    def set_context(self, objects, data, ids, report_type = None):
-        super(rmlparser,self).set_context(objects, data, ids, report_type)
-        self.setCompany(objects[0])
-
-report_sxw.report_sxw('report.preview.report', 'res.company',
-      'addons/base/report/preview_report.rml', parser=rmlparser, header='external')
diff --git a/odoo/addons/base/report/preview_report.rml b/odoo/addons/base/report/preview_report.rml
deleted file mode 100644
index f3a54527a13b1df20acb54c85e57cc0c651ea8c7..0000000000000000000000000000000000000000
--- a/odoo/addons/base/report/preview_report.rml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<document filename="preview_report.pdf">
-  <template title="Preview Report" author="Odoo (sales@odoo.com)" allowSplitting="20">
-    <pageTemplate id="first">
-      <frame id="first" x1="57.0" y1="57.0" width="481" height="728"/>
-    </pageTemplate>
-  </template>
-  <story>
-    <para>
-    </para>
-  </story>
-</document>
diff --git a/odoo/addons/base/res/__init__.py b/odoo/addons/base/res/__init__.py
index ee904734c09e2bb29e6f909f3c98e49d57c73529..1e10e5ee9cd30f0472de880155eeabd8fb6b4f49 100644
--- a/odoo/addons/base/res/__init__.py
+++ b/odoo/addons/base/res/__init__.py
@@ -7,7 +7,6 @@ from . import res_partner
 from . import res_bank
 from . import res_config
 from . import res_currency
-from . import res_font
 from . import res_company
 from . import res_users
 from . import res_request
diff --git a/odoo/addons/base/res/res_company.py b/odoo/addons/base/res/res_company.py
index 18fbd6a0a3ea04edea9ffa23960f6b396367852a..b02255db4bdd7a99a283b61191fc315e8148918c 100644
--- a/odoo/addons/base/res/res_company.py
+++ b/odoo/addons/base/res/res_company.py
@@ -13,98 +13,6 @@ class Company(models.Model):
     _description = 'Companies'
     _order = 'sequence, name'
 
-    _header = """
-<header>
-<pageTemplate>
-    <frame id="first" x1="28.0" y1="28.0" width="%s" height="%s"/>
-    <stylesheet>
-       <!-- Set here the default font to use for all <para> tags -->
-       <paraStyle name='Normal' fontName="DejaVuSans"/>
-    </stylesheet>
-    <pageGraphics>
-        <fill color="black"/>
-        <stroke color="black"/>
-        <setFont name="DejaVuSans" size="8"/>
-        <drawString x="%s" y="%s"> [[ formatLang(time.strftime("%%Y-%%m-%%d"), date=True) ]]  [[ time.strftime("%%H:%%M") ]]</drawString>
-        <setFont name="DejaVuSans-Bold" size="10"/>
-        <drawCentredString x="%s" y="%s">[[ company.partner_id.name ]]</drawCentredString>
-        <stroke color="#000000"/>
-        <lines>%s</lines>
-        <!-- Set here the default font to use for all <drawString> tags -->
-        <!-- don't forget to change the 2 other occurence of <setFont> above if needed --> 
-        <setFont name="DejaVuSans" size="8"/>
-    </pageGraphics>
-</pageTemplate>
-</header>"""
-
-    _header2 = _header % (539, 772, "1.0cm", "28.3cm", "11.1cm", "28.3cm", "1.0cm 28.1cm 20.1cm 28.1cm")
-    _header3 = _header % (786, 525, 25, 555, 440, 555, "25 550 818 550")
-
-    _header_main = """
-<header>
-    <pageTemplate>
-        <frame id="first" x1="1.3cm" y1="3.0cm" height="%s" width="19.0cm"/>
-         <stylesheet>
-            <!-- Set here the default font to use for all <para> tags -->
-            <paraStyle name='Normal' fontName="DejaVuSans"/>
-            <paraStyle name="main_footer" fontSize="8.0" alignment="CENTER"/>
-            <paraStyle name="main_header" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
-         </stylesheet>
-        <pageGraphics>
-            <!-- Set here the default font to use for all <drawString> tags -->
-            <setFont name="DejaVuSans" size="8"/>
-            <!-- You Logo - Change X,Y,Width and Height -->
-            <image x="1.3cm" y="%s" height="40.0" >[[ company.logo or removeParentNode('image') ]]</image>
-            <fill color="black"/>
-            <stroke color="black"/>
-
-            <!-- page header -->
-            <lines>1.3cm %s 20cm %s</lines>
-            <drawRightString x="20cm" y="%s">[[ company.rml_header1 ]]</drawRightString>
-            <drawString x="1.3cm" y="%s">[[ company.partner_id.name ]]</drawString>
-            <place x="1.3cm" y="%s" height="1.8cm" width="15.0cm">
-                <para style="main_header">[[ display_address(company.partner_id) or  '' ]]</para>
-            </place>
-            <drawString x="1.3cm" y="%s">Phone:</drawString>
-            <drawRightString x="7cm" y="%s">[[ company.partner_id.phone or '' ]]</drawRightString>
-            <drawString x="1.3cm" y="%s">Mail:</drawString>
-            <drawRightString x="7cm" y="%s">[[ company.partner_id.email or '' ]]</drawRightString>
-            <lines>1.3cm %s 7cm %s</lines>
-
-            <!-- left margin -->
-            <rotate degrees="90"/>
-            <fill color="grey"/>
-            <drawString x="2.65cm" y="-0.4cm">generated by Odoo.com</drawString>
-            <fill color="black"/>
-            <rotate degrees="-90"/>
-
-            <!--page bottom-->
-            <lines>1.2cm 2.65cm 19.9cm 2.65cm</lines>
-            <place x="1.3cm" y="0cm" height="2.55cm" width="19.0cm">
-                <para style="main_footer">[[ company.rml_footer ]]</para>
-                <para style="main_footer">Contact : [[ user.name ]] - Page: <pageNumber/></para>
-            </place>
-        </pageGraphics>
-    </pageTemplate>
-</header>"""
-
-    _header_a4 = _header_main % ('21.7cm', '27.7cm', '27.7cm', '27.7cm', '27.8cm', '27.3cm', '25.3cm', '25.0cm', '25.0cm', '24.6cm', '24.6cm', '24.5cm', '24.5cm')
-    _header_letter = _header_main % ('20cm', '26.0cm', '26.0cm', '26.0cm', '26.1cm', '25.6cm', '23.6cm', '23.3cm', '23.3cm', '22.9cm', '22.9cm', '22.8cm', '22.8cm')
-
-    def _get_header(self):
-        try:
-            header_file = tools.file_open(os.path.join(
-                'base', 'report', 'corporate_rml_header.rml'))
-            try:
-                return header_file.read()
-            finally:
-                header_file.close()
-        except:
-            return self._header_a4
-
-    def _get_font(self):
-        return self.env['res.font'].search([('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1)
-
     def _get_logo(self):
         return open(os.path.join(tools.config['root_path'], 'addons', 'base', 'res', 'res_company_logo.png'), 'rb') .read().encode('base64')
 
@@ -121,14 +29,8 @@ class Company(models.Model):
     parent_id = fields.Many2one('res.company', string='Parent Company', index=True)
     child_ids = fields.One2many('res.company', 'parent_id', string='Child Companies')
     partner_id = fields.Many2one('res.partner', string='Partner', required=True)
-    rml_header = fields.Text(required=True, default=_get_header)
-    rml_header1 = fields.Text(string='Company Tagline', help="Appears by default on the top right corner of your printed documents (report header).")
-    rml_header2 = fields.Text(string='RML Internal Header', required=True, default=_header2)
-    rml_header3 = fields.Text(string='RML Internal Header for Landscape Reports', required=True, default=_header3)
-    rml_footer = fields.Text(string='Report Footer', translate=True, help="Footer text displayed at the bottom of all reports.")
-    font = fields.Many2one('res.font', string="Font", default=lambda self: self._get_font(),
-                           domain=[('mode', 'in', ('Normal', 'Regular', 'all', 'Book'))],
-                           help="Set the font into the report header, it will be used as default font in the RML reports of the user company")
+    report_header = fields.Text(string='Company Tagline', help="Appears by default on the top right corner of your printed documents (report header).")
+    report_footer = fields.Text(string='Report Footer', translate=True, help="Footer text displayed at the bottom of all reports.")
     logo = fields.Binary(related='partner_id.image', default=_get_logo, string="Company Logo")
     # logo_web: do not store in attachments, since the image is retrieved in SQL for
     # performance reasons (see addons/web/controllers/main.py, Binary.company_logo)
@@ -149,7 +51,6 @@ class Company(models.Model):
     website = fields.Char(related='partner_id.website')
     vat = fields.Char(related='partner_id.vat', string="TIN")
     company_registry = fields.Char()
-    rml_paper_format = fields.Selection([('a4', 'A4'), ('us_letter', 'US Letter')], string="Paper Format", required=True, default='a4', oldname='paper_format')
     sequence = fields.Integer(help='Used to order Companies in the company switcher', default=10)
 
     _sql_constraints = [
@@ -213,20 +114,6 @@ class Company(models.Model):
     def _onchange_state(self):
         self.country_id = self.state_id.country_id
 
-    @api.onchange('font')
-    def _onchange_font_name(self):
-        """ To change default header style of all <para> and drawstring. """
-        def _change_header(header, font):
-            """ Replace default fontname use in header and setfont tag """
-            default_para = re.sub(r'fontName.?=.?".*"', 'fontName="%s"' % font, header)
-            return re.sub(r'(<setFont.?name.?=.?)(".*?")(.)', '\g<1>"%s"\g<3>' % font, default_para)
-
-        if self.font:
-            fontname = self.font.name
-            self.rml_header = _change_header(self.rml_header, fontname)
-            self.rml_header2 = _change_header(self.rml_header2, fontname)
-            self.rml_header3 = _change_header(self.rml_header3, fontname)
-
     @api.multi
     def on_change_country(self, country_id):
         # This function is called from account/models/chart_template.py, hence decorated with `multi`.
@@ -324,18 +211,6 @@ class Company(models.Model):
         self.clear_caches()
         return super(Company, self).write(values)
 
-    @api.onchange('rml_paper_format')
-    def _onchange_rml_paper_format(self):
-        if self.rml_paper_format == 'us_letter':
-            self.rml_header = self._header_letter
-        else:
-            self.rml_header = self._header_a4
-
-    @api.multi
-    def act_discover_fonts(self):
-        self.ensure_one()
-        return self.env["res.font"].font_scan()
-
     @api.constrains('parent_id')
     def _check_parent_id(self):
         if not self._check_recursion():
diff --git a/odoo/addons/base/res/res_company_view.xml b/odoo/addons/base/res/res_company_view.xml
index 4746deeb1b105f0a1455ab03b786991da36e1b78..3a7168dc3f8e145e5d60673698d6f1cbe4d27715 100644
--- a/odoo/addons/base/res/res_company_view.xml
+++ b/odoo/addons/base/res/res_company_view.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <odoo>
     <data>
-        <report id="preview_rml_report" model="res.config.settings" name="preview.report" menu="False" rml="base/report/preview_report.rml" string="Preview RML Report"/>
-
         <record id="view_company_form" model="ir.ui.view">
             <field name="name">res.company.form</field>
             <field name="model">res.company</field>
@@ -31,8 +29,8 @@
                                         <field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True}'/>
                                     </div>
                                     <field name="website" widget="url" placeholder="e.g. www.odoo.com"/>
-                                    <field name="rml_footer" placeholder="e.g. Your Bank Accounts, one per line"/>
-                                    <field name="rml_header1" placeholder="e.g. Global Business Solutions"/>
+                                    <field name="report_footer" placeholder="e.g. Your Bank Accounts, one per line"/>
+                                    <field name="report_header" placeholder="e.g. Global Business Solutions"/>
                                 </group>
                                 <group>
                                     <field name="phone"/>
diff --git a/odoo/addons/base/res/res_font.py b/odoo/addons/base/res/res_font.py
deleted file mode 100644
index ab3ad251c6c8aefa06dac0ba04943b35c229e7cd..0000000000000000000000000000000000000000
--- a/odoo/addons/base/res/res_font.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import logging
-from reportlab.pdfbase import ttfonts
-
-from odoo import api, fields, models
-from odoo.report.render.rml2pdf import customfonts
-
-"""This module allows the mapping of some system-available TTF fonts to
-the reportlab engine.
-
-This file could be customized per distro (although most Linux/Unix ones)
-should have the same filenames, only need the code below).
-
-Due to an awful configuration that ships with reportlab at many Linux
-and Ubuntu distros, we have to override the search path, too.
-"""
-_logger = logging.getLogger(__name__)
-
-# Alternatives for the [broken] builtin PDF fonts. Default order chosen to match
-# the pre-v8 mapping from odoo.report.render.rml2pdf.customfonts.CustomTTFonts.
-# Format: [ (BuiltinFontFamily, mode, [AlternativeFontName, ...]), ...]
-BUILTIN_ALTERNATIVES = [
-    ('Helvetica', "normal", ["DejaVuSans", "LiberationSans"]),
-    ('Helvetica', "bold", ["DejaVuSans-Bold", "LiberationSans-Bold"]),
-    ('Helvetica', 'italic', ["DejaVuSans-Oblique", "LiberationSans-Italic"]),
-    ('Helvetica', 'bolditalic', ["DejaVuSans-BoldOblique", "LiberationSans-BoldItalic"]),
-    ('Times', 'normal', ["LiberationSerif", "DejaVuSerif"]),
-    ('Times', 'bold', ["LiberationSerif-Bold", "DejaVuSerif-Bold"]),
-    ('Times', 'italic', ["LiberationSerif-Italic", "DejaVuSerif-Italic"]),
-    ('Times', 'bolditalic', ["LiberationSerif-BoldItalic", "DejaVuSerif-BoldItalic"]),
-    ('Courier', 'normal', ["FreeMono", "DejaVuSansMono"]),
-    ('Courier', 'bold', ["FreeMonoBold", "DejaVuSansMono-Bold"]),
-    ('Courier', 'italic', ["FreeMonoOblique", "DejaVuSansMono-Oblique"]),
-    ('Courier', 'bolditalic', ["FreeMonoBoldOblique", "DejaVuSansMono-BoldOblique"]),
-]
-
-
-class ResFont(models.Model):
-    _name = "res.font"
-    _description = 'Fonts available'
-    _order = 'family,name,id'
-    _rec_name = 'family'
-
-    family = fields.Char(string="Font family", required=True)
-    name = fields.Char(string="Font Name", required=True)
-    path = fields.Char(required=True)
-    mode = fields.Char(required=True)
-
-    _sql_constraints = [
-        ('name_font_uniq', 'unique(family, name)', 'You can not register two fonts with the same name'),
-    ]
-
-    @api.model
-    def font_scan(self, lazy=False):
-        """Action of loading fonts
-        In lazy mode will scan the filesystem only if there is no founts in the database and sync if no font in CustomTTFonts
-        In not lazy mode will force scan filesystem and sync
-        """
-        if lazy:
-            # lazy loading, scan only if no fonts in db
-            fonts = self.search([('path', '!=', '/dev/null')])
-            if not fonts:
-                # no scan yet or no font found on the system, scan the filesystem
-                self._scan_disk()
-            elif len(customfonts.CustomTTFonts) == 0:
-                # CustomTTFonts list is empty
-                self._sync()
-        else:
-            self._scan_disk()
-        return True
-
-    def _scan_disk(self):
-        """Scan the file system and register the result in database"""
-        found_fonts = []
-        for font_path in customfonts.list_all_sysfonts():
-            try:
-                font = ttfonts.TTFontFile(font_path)
-                _logger.debug("Found font %s at %s", font.name, font_path)
-                found_fonts.append((font.familyName, font.name, font_path, font.styleName))
-            except Exception as ex:
-                _logger.warning("Could not register Font %s: %s", font_path, ex)
-
-        for family, name, path, mode in found_fonts:
-            if not self.search([('family', '=', family), ('name', '=', name)]):
-                self.create({'family': family, 'name': name, 'path': path, 'mode': mode})
-
-        # remove fonts not present on the disk anymore
-        existing_font_names = [name for (family, name, path, mode) in found_fonts]
-        # Remove inexistent fonts
-        self.search([('name', 'not in', existing_font_names), ('path', '!=', '/dev/null')]).unlink()
-
-        self.pool.cache_invalidated = True
-        return self._sync()
-
-    def _sync(self):
-        """Set the customfonts.CustomTTFonts list to the content of the database"""
-        customfonts.CustomTTFonts = []
-        local_family_modes = set()
-        local_font_paths = {}
-        for font in self.search([('path', '!=', '/dev/null')]):
-            local_family_modes.add((font.family, font.mode))
-            local_font_paths[font.name] = font.path
-            customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode))
-
-        # Attempt to remap the builtin fonts (Helvetica, Times, Courier) to better alternatives
-        # if available, because they only support a very small subset of unicode
-        # (missing 'č' for example)
-        for builtin_font_family, mode, alts in BUILTIN_ALTERNATIVES:
-            if (builtin_font_family, mode) not in local_family_modes:
-                # No local font exists with that name, try alternatives
-                for altern_font in alts:
-                    if local_font_paths.get(altern_font):
-                        altern_def = (builtin_font_family, altern_font,
-                                      local_font_paths[altern_font], mode)
-                        customfonts.CustomTTFonts.append(altern_def)
-                        _logger.debug("Builtin remapping %r", altern_def)
-                        break
-                else:
-                    _logger.warning("No local alternative found for builtin font `%s` (%s mode)." 
-                                    "Consider installing the DejaVu fonts if you have problems "
-                                    "with unicode characters in RML reports",
-                                    builtin_font_family, mode)
-        return True
-
-    @classmethod
-    def clear_caches(cls):
-        """Force worker to resync at next report loading by setting an empty font list"""
-        customfonts.CustomTTFonts = []
-        return super(ResFont, cls).clear_caches()
diff --git a/odoo/addons/base/security/ir.model.access.csv b/odoo/addons/base/security/ir.model.access.csv
index 284fc1549ddc1f40aa2f4f913806c7db64f8b47b..50a0d8ec7622a76ada85154a05dab08d3dddcfa5 100644
--- a/odoo/addons/base/security/ir.model.access.csv
+++ b/odoo/addons/base/security/ir.model.access.csv
@@ -70,8 +70,8 @@
 "access_ir_actions_act_window_system","ir_actions_act_window_system","model_ir_actions_act_window","group_system",1,1,1,1
 "access_ir_actions_act_window_close_all","ir_actions_act_window_close_all","model_ir_actions_act_window_close",,1,0,0,0
 "access_ir_actions_act_window_close_group_system","ir_actions_act_window_close_group_system","model_ir_actions_act_window_close","group_system",1,1,1,1
-"access_ir_actions_report_xml_all","ir_actions_report_xml","model_ir_actions_report_xml",,1,0,0,0
-"access_ir_actions_report_xml_group_system","ir_actions_report_xml_group_system","model_ir_actions_report_xml","group_system",1,1,1,1
+"access_ir_actions_report_all","ir_actions_report","model_ir_actions_report",,1,0,0,0
+"access_ir_actions_report_group_system","ir_actions_report_group_system","model_ir_actions_report","group_system",1,1,1,1
 "access_ir_actions_todo_group_system","ir_actions_todo group system","model_ir_actions_todo","group_system",1,1,1,1
 "access_ir_actions_act_window_view_all","ir_actions_act_window_view_all","model_ir_actions_act_window_view",,1,0,0,0
 "access_ir_actions_act_window_view_group_system","ir_actions_act_window_view_group_system","model_ir_actions_act_window_view","group_system",1,1,1,1
@@ -91,6 +91,4 @@
 "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_res_font_all","res_res_font all","model_res_font",,1,0,0,0
-"access_res_font_group_user","res_res_font group_user","model_res_font","group_user",1,1,1,1
 "access_ir_logging","ir_logging admin","model_ir_logging","group_erp_manager",1,1,1,1
diff --git a/odoo/addons/base/tests/test_ir_values.py b/odoo/addons/base/tests/test_ir_values.py
index 5a10f3537d96814beb18d98e11920e0de36ab3de..a4365f7e0aad10d15e0943fcc20d9f5a937a0f04 100644
--- a/odoo/addons/base/tests/test_ir_values.py
+++ b/odoo/addons/base/tests/test_ir_values.py
@@ -63,9 +63,9 @@ class TestIrValues(TransactionCase):
         ir_values.set_action('OnDblClick Action 2', action_slot='tree_but_open', model='res.partner', action='ir.actions.act_window,%d' % act_id_2, res_id=False)
         ir_values.set_action('Side Wizard', action_slot='client_action_multi', model='res.partner', action='ir.actions.act_window,%d' % act_id_3, res_id=False)
 
-        reports = self.env['ir.actions.report.xml'].search([])
+        reports = self.env['ir.actions.report'].search([])
         report_id = next(report.id for report in reports if not report.groups_id)
-        ir_values.set_action('Nice Report', action_slot='client_print_multi', model='res.partner', action='ir.actions.report.xml,%d' % report_id, res_id=False)
+        ir_values.set_action('Nice Report', action_slot='client_print_multi', model='res.partner', action='ir.actions.report,%d' % report_id, res_id=False)
 
         # Replace one action binding to set a new name.
         ir_values.set_action('OnDblClick Action New', action_slot='tree_but_open', model='res.partner', action='ir.actions.act_window,%d' % act_id_1, res_id=False)
diff --git a/odoo/conf/__init__.py b/odoo/conf/__init__.py
index b9722b9fff602d51f4088e0242ea606d6e1caf45..2216701c5d68f3fefb9e231445ab5ce32bdf5cd9 100644
--- a/odoo/conf/__init__.py
+++ b/odoo/conf/__init__.py
@@ -15,8 +15,6 @@ must be used.
 
 """
 
-from . import deprecation
-
 # Paths to search for OpenERP addons.
 addons_paths = []
 
diff --git a/odoo/conf/deprecation.py b/odoo/conf/deprecation.py
deleted file mode 100644
index 3f64def1fd019c39151bead95cd41df3d45083fe..0000000000000000000000000000000000000000
--- a/odoo/conf/deprecation.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-""" Regroup variables for deprecated features.
-
-To keep the OpenERP server backward compatible with older modules, some
-additional code is needed throughout the core library. This module keeps
-track of those specific measures by providing variables that can be unset
-by the user to check if her code is future proof.
-
-In a perfect world, all these variables are set to False, the corresponding
-code removed, and thus these variables made unnecessary.
-"""
-
-# If True, the Python modules inside the openerp namespace are made available
-# without the 'openerp.' prefix. E.g. openerp.osv.osv and osv.osv refer to the
-# same module.
-# Introduced around 2011.02.
-# Change to False around 2013.02.
-open_openerp_namespace = False
-
-# If True, openerp.netsvc.LocalService() can be used to lookup reports or to
-# Introduced around 2013.03.
-# Among the related code:
-# - The openerp.netsvc.LocalService() function.
-# - The openerp.report.interface.report_int._reports dictionary.
-# - The register attribute in openerp.report.interface.report_int (and in its
-# - auto column in ir.actions.report.xml.
-# inheriting classes).
-allow_local_service = True
-
-# Applies for the register attribute in openerp.report.interface.report_int.
-# See comments for allow_local_service above.
-# Introduced around 2013.03.
-allow_report_int_registration = True
diff --git a/odoo/import_xml.rng b/odoo/import_xml.rng
index d85cd05a0bad3a149f1d9be195147c114c0a4039..adcbd19e0333a431f58fdc6aa0a551bf87cecca1 100644
--- a/odoo/import_xml.rng
+++ b/odoo/import_xml.rng
@@ -77,15 +77,11 @@
             <rng:optional><rng:attribute name="multi"/></rng:optional>
             <rng:optional><rng:attribute name="menu"/></rng:optional>
             <rng:optional><rng:attribute name="keyword"/></rng:optional>
-            <rng:optional><rng:attribute name="rml"/></rng:optional><!-- pending deprecation after v6.0 -->
             <rng:optional><rng:attribute name="file"/></rng:optional>
-            <rng:optional><rng:attribute name="sxw"/></rng:optional>
             <rng:optional><rng:attribute name="xml"/></rng:optional>
-            <rng:optional><rng:attribute name="xsl"/></rng:optional>
             <rng:optional><rng:attribute name="parser"/></rng:optional>
             <rng:optional> <rng:attribute name="auto" /> </rng:optional>
             <rng:optional> <rng:attribute name="header" /> </rng:optional>
-            <rng:optional> <rng:attribute name="webkit_header" /> </rng:optional>
             <rng:optional> <rng:attribute name="attachment" /> </rng:optional>
             <rng:optional> <rng:attribute name="attachment_use" /> </rng:optional>
             <rng:optional> <rng:attribute name="groups"/> </rng:optional>
diff --git a/odoo/models.py b/odoo/models.py
index b993596f332aa8b0eff4a2462d48039f2e4f6f8a..a1535123c9db832935fe7e53342f0a293141a983 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -1304,24 +1304,18 @@ class BaseModel(object):
 
         # Add related action information if aksed
         if toolbar:
-            toclean = ('report_sxw_content', 'report_rml_content', 'report_sxw', 'report_rml', 'report_sxw_content_data', 'report_rml_content_data')
-            def clean(x):
-                x = x[2]
-                for key in toclean:
-                    x.pop(key, None)
-                return x
             IrValues = self.env['ir.values']
             resprint = IrValues.get_actions('client_print_multi', self._name)
             resaction = IrValues.get_actions('client_action_multi', self._name)
             resrelate = IrValues.get_actions('client_action_relate', self._name)
-            resprint = [clean(print_)
+            resprint = [print_[2]
                         for print_ in resprint
                         if view_type == 'tree' or not print_[2].get('multi')]
-            resaction = [clean(action)
+            resaction = [action[2]
                          for action in resaction
                          if view_type == 'tree' or not action[2].get('multi')]
             #When multi="True" set it will display only in More of the list view
-            resrelate = [clean(action)
+            resrelate = [action[2]
                          for action in resrelate
                          if (action[2].get('multi') and view_type == 'tree') or (not action[2].get('multi') and view_type == 'form')]
 
@@ -3981,17 +3975,6 @@ class BaseModel(object):
     get_xml_id = get_external_id
     _get_xml_ids = _get_external_ids
 
-    @api.multi
-    def print_report(self, name, data):
-        """
-        Render the report ``name`` for the given IDs. The report must be defined
-        for this model, not another.
-        """
-        report = self.env['ir.actions.report.xml']._lookup_report(name)
-        assert self._name == report.table
-        cr, uid, context = self.env.args
-        return report.create(cr, uid, self.ids, data, context)
-
     # Transience
     @classmethod
     def is_transient(cls):
diff --git a/odoo/netsvc.py b/odoo/netsvc.py
index 3832ae10cd6f96b0ff675b02bc77e7d879081eef..a44984f391cdd23c8c249f2fcd1de5cbc41ee500 100644
--- a/odoo/netsvc.py
+++ b/odoo/netsvc.py
@@ -25,26 +25,6 @@ def log(logger, level, prefix, msg, depth=None):
         logger.log(level, indent+line)
         indent=indent_after
 
-def LocalService(name):
-    """
-    The odoo.netsvc.LocalService() function is deprecated. It still works
-    in one case: reports. For reports, odoo.report.render_report() should
-    be used (methods on the Model should be provided too in the future).
-    """
-    assert odoo.conf.deprecation.allow_local_service
-    _logger.warning("LocalService() is deprecated since march 2013 (it was called with '%s')." % name)
-
-    if name.startswith('report.'):
-        report = odoo.report.interface.report_int._reports.get(name)
-        if report:
-            return report
-        else:
-            dbname = getattr(threading.currentThread(), 'dbname', None)
-            if dbname:
-                registry = odoo.registry(dbname)
-                with registry.cursor() as cr:
-                    return registry['ir.actions.report.xml']._lookup_report(cr, name[len('report.'):])
-
 path_prefix = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
 
 class PostgreSQLHandler(logging.Handler):
diff --git a/odoo/report/__init__.py b/odoo/report/__init__.py
deleted file mode 100644
index 1000d4991c65e4c26654724a9c82f83a8c1e02dd..0000000000000000000000000000000000000000
--- a/odoo/report/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from odoo import api
-from . import custom
-from . import int_to_text
-from . import interface
-from . import print_fnc
-from . import print_xml
-from . import printscreen
-from . import render
-from . import report_sxw
-
-def render_report(cr, uid, ids, name, data, context=None):
-    """
-    Helper to call ``ir.actions.report.xml.render_report()``.
-    """
-    env = api.Environment(cr, uid, context or {})
-    return env['ir.actions.report.xml'].render_report(ids, name, data)
diff --git a/odoo/report/common.py b/odoo/report/common.py
deleted file mode 100644
index dffcffa859cf4d567ee47e96c68407f75a150ff8..0000000000000000000000000000000000000000
--- a/odoo/report/common.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-pageSize = {
-    'A4': (210,297),
-    'A5': (148.5,105)
-}
-
-odt_namespace = {
-    "office":"{urn:oasis:names:tc:opendocument:xmlns:office:1.0}",
-    "style":"{urn:oasis:names:tc:opendocument:xmlns:style:1.0}",
-    "text":"{urn:oasis:names:tc:opendocument:xmlns:text:1.0}",
-    "table":"{urn:oasis:names:tc:opendocument:xmlns:table:1.0}",
-    "draw":"{urn:oasis:names:tc:opendocument:xmlns:drawing:1.0}",
-    "fo":"{urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0}",
-    "xlink":"{http://www.w3.org/1999/xlink}",
-    "dc":"{http://purl.org/dc/elements/1.1/}",
-    "meta":"{urn:oasis:names:tc:opendocument:xmlns:meta:1.0}",
-    "number":"{urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0}",
-    "svg":"{urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0}",
-    "chart":"{urn:oasis:names:tc:opendocument:xmlns:chart:1.0}",
-    "dr3d":"{urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0}",
-    "math":"{http://www.w3.org/1998/Math/MathML}",
-    "form":"{urn:oasis:names:tc:opendocument:xmlns:form:1.0}",
-    "script":"{urn:oasis:names:tc:opendocument:xmlns:script:1.0}",
-    "ooo":"{http://openoffice.org/2004/office}",
-    "ooow":"{http://openoffice.org/2004/writer}",
-    "oooc":"{http://openoffice.org/2004/calc}",
-    "dom":"{http://www.w3.org/2001/xml-events}" }
-
-sxw_namespace = {
-    "office":"{http://openoffice.org/2000/office}",
-    "style":"{http://openoffice.org/2000/style}",
-    "text":"{http://openoffice.org/2000/text}",
-    "table":"{http://openoffice.org/2000/table}",
-    "draw":"{http://openoffice.org/2000/drawing}",
-    "fo":"{http://www.w3.org/1999/XSL/Format}",
-    "xlink":"{http://www.w3.org/1999/xlink}",
-    "dc":"{http://purl.org/dc/elements/1.1/}",
-    "meta":"{http://openoffice.org/2000/meta}",
-    "number":"{http://openoffice.org/2000/datastyle}",
-    "svg":"{http://www.w3.org/2000/svg}",
-    "chart":"{http://openoffice.org/2000/chart}",
-    "dr3d":"{http://openoffice.org/2000/dr3d}",
-    "math":"{http://www.w3.org/1998/Math/MathML}",
-    "form":"{http://openoffice.org/2000/form}",
-    "script":"{http://openoffice.org/2000/script}",
-    "ooo":"{http://openoffice.org/2004/office}",
-    "ooow":"{http://openoffice.org/2004/writer}",
-    "oooc":"{http://openoffice.org/2004/calc}",
-    "dom":"{http://www.w3.org/2001/xml-events}"}
diff --git a/odoo/report/custom.py b/odoo/report/custom.py
deleted file mode 100644
index 1eb68f0890fbbcffa99cd7596200f46b3795794e..0000000000000000000000000000000000000000
--- a/odoo/report/custom.py
+++ /dev/null
@@ -1,587 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import cStringIO
-import os
-import time
-
-from lxml import etree
-from pychart import area, arrow, axis, bar_plot, canvas, category_coord, \
-                    fill_style, legend, line_plot, line_style, pie_plot, theme
-
-import odoo
-import odoo.tools as tools
-from odoo.exceptions import UserError
-from odoo.models import BaseModel
-from odoo.tools.safe_eval import safe_eval
-from odoo.tools.translate import _
-from . import common
-from . import misc
-from . import render
-from .interface import report_int
-
-
-class external_pdf(render.render):
-    def __init__(self, pdf):
-        render.render.__init__(self)
-        self.pdf = pdf
-        self.output_type='pdf'
-    def _render(self):
-        return self.pdf
-
-theme.use_color = 1
-
-
-#TODO: devrait heriter de report_rml a la place de report_int 
-# -> pourrait overrider que create_xml a la place de tout create
-# heuu, ca marche pas ds tous les cas car graphs sont generes en pdf directment
-# par pychart, et on passe donc pas par du rml
-class report_custom(report_int):
-    def __init__(self, name):
-        report_int.__init__(self, name)
-
-    #
-    # PRE:
-    #    fields = [['address','city'],['name'], ['zip']]
-    #    conditions = [[('zip','==','3'),(,)],(,),(,)] #same structure as fields
-    #    row_canvas = ['Rue', None, None]
-    # POST:
-    #    [ ['ville','name','zip'] ]
-    #
-    def _row_get(self, cr, uid, objs, fields, conditions, row_canvas=None, group_by=None):
-        result = []
-        for obj in objs:
-            tobreak = False
-            for cond in conditions:
-                if cond and cond[0]:
-                    c = cond[0]
-                    temp = c[0](safe_eval('obj.'+c[1],{'obj': obj}))
-                    if not safe_eval('\''+temp+'\''+' '+c[2]+' '+'\''+str(c[3])+'\''):
-                        tobreak = True
-            if tobreak:
-                break
-            levels = {}
-            row = []
-            for i in range(len(fields)):
-                if not fields[i]:
-                    row.append(row_canvas and row_canvas[i])
-                    if row_canvas[i]:
-                        row_canvas[i]=False
-                elif len(fields[i])==1:
-                    if obj:
-                        row.append(str(safe_eval('obj.'+fields[i][0],{'obj': obj})))
-                    else:
-                        row.append(None)
-                else:
-                    row.append(None)
-                    levels[fields[i][0]]=True
-            if not levels:
-                result.append(row)
-            else:
-                # Process group_by data first
-                key = []
-                if group_by is not None and fields[group_by] is not None:
-                    if fields[group_by][0] in levels.keys():
-                        key.append(fields[group_by][0])
-                    for l in levels.keys():
-                        if l != fields[group_by][0]:
-                            key.append(l)
-                else:
-                    key = levels.keys()
-                for l in key:
-                    objs = safe_eval('obj.'+l,{'obj': obj})
-                    if not isinstance(objs, (BaseModel, list)):
-                        objs = [objs]
-                    field_new = []
-                    cond_new = []
-                    for f in range(len(fields)):
-                        if (fields[f] and fields[f][0])==l:
-                            field_new.append(fields[f][1:])
-                            cond_new.append(conditions[f][1:])
-                        else:
-                            field_new.append(None)
-                            cond_new.append(None)
-                    if len(objs):
-                        result += self._row_get(cr, uid, objs, field_new, cond_new, row, group_by)
-                    else:
-                        result.append(row)
-        return result 
-
-    def create(self, cr, uid, ids, datas, context=None):
-        env = odoo.api.Environment(cr, uid, context or {})
-        report = env['ir.report.custom'].browse([datas['report_id']])
-        datas['model'] = report.model_id.model
-        if report.menu_id:
-            ids = env[report.model_id.model].search([]).ids
-            datas['ids'] = ids
-
-        report = report.read()[0]
-        fields = env['ir.report.custom.fields'].browse(report['fields_child0']).read()
-        fields.sort(key=lambda x: x['sequence'])
-        model_name = env['ir.model'].sudo().browse(report['model_id'][0]).model
-
-        fct = {
-            'id': lambda x: x,
-            'gety': lambda x: x.split('-')[0],
-           'in': lambda x: x.split(',')
-        }
-        new_fields = []
-        new_cond = []
-        for f in fields:
-            row = []
-            cond = []
-            for i in range(4):
-                field_child = f['field_child'+str(i)]
-                if field_child:
-                    row.append(
-                        env['ir.model.fields'].sudo().browse(field_child[0]).name
-                    )
-                    if f['fc'+str(i)+'_operande']:
-                        fct_name = 'id'
-                        cond_op =  f['fc'+str(i)+'_op']
-                        if len(f['fc'+str(i)+'_op'].split(',')) == 2:
-                            cond_op =  f['fc'+str(i)+'_op'].split(',')[1]
-                            fct_name = f['fc'+str(i)+'_op'].split(',')[0]
-                        cond.append((fct[fct_name], f['fc'+str(i)+'_operande'][1], cond_op, f['fc'+str(i)+'_condition']))
-                    else:
-                        cond.append(None)
-            new_fields.append(row)
-            new_cond.append(cond)
-        objs = env[model_name].browse(ids)
-
-        # Group by
-        groupby = None
-        idx = 0
-        for f in fields:
-            if f['groupby']:
-                groupby = idx
-            idx += 1
-
-
-        results = []
-        if report['field_parent']:
-            level = []
-            def build_tree(obj, level, depth):
-                res = self._row_get(cr, uid, [obj], new_fields, new_cond)
-                level.append(depth)
-                new_obj = safe_eval('obj.'+report['field_parent'][1], {'obj': obj})
-                if not isinstance(new_obj, list) :
-                    new_obj = [new_obj]
-                for o in new_obj:
-                    if o:
-                        res += build_tree(o, level, depth+1)
-                return res
-
-            for obj in objs:
-                results += build_tree(obj, level, 0)
-        else:
-            results = self._row_get(cr, uid, objs, new_fields, new_cond, group_by=groupby)
-
-        fct = {
-            'calc_sum': lambda l: reduce(lambda x,y: float(x)+float(y), filter(None, l), 0),
-            'calc_avg': lambda l: reduce(lambda x,y: float(x)+float(y), filter(None, l), 0) / (len(filter(None, l)) or 1.0),
-            'calc_max': lambda l: reduce(lambda x,y: max(x,y), [(i or 0.0) for i in l], 0),
-            'calc_min': lambda l: reduce(lambda x,y: min(x,y), [(i or 0.0) for i in l], 0),
-            'calc_count': lambda l: len(filter(None, l)),
-            'False': lambda l: '\r\n'.join(filter(None, l)),
-            'groupby': lambda l: reduce(lambda x,y: x or y, l)
-        }
-        new_res = []
-
-        prev = None
-        if groupby is not None:
-            res_dic = {}
-            for line in results:
-                if not line[groupby] and prev in res_dic:
-                    res_dic[prev].append(line)
-                else:
-                    prev = line[groupby]
-                    res_dic.setdefault(line[groupby], [])
-                    res_dic[line[groupby]].append(line)
-
-            #we use the keys in results since they are ordered, whereas in res_dic.heys() they aren't
-            for key in filter(None, [x[groupby] for x in results]):
-                row = []
-                for col in range(len(fields)):
-                    if col == groupby:
-                        row.append(fct['groupby'](map(lambda x: x[col], res_dic[key])))
-                    else:
-                        row.append(fct[str(fields[col]['operation'])](map(lambda x: x[col], res_dic[key])))
-                new_res.append(row)
-            results = new_res
-
-        if report['type']=='table':
-            if report['field_parent']:
-                res = self._create_tree(uid, ids, report, fields, level, results, context)
-            else:
-                sort_idx = 0
-                for idx in range(len(fields)):
-                    if fields[idx]['name'] == report['sortby']:
-                        sort_idx = idx
-                        break
-                try :
-                    results.sort(key=lambda x: float(x[sort_idx]))
-                except :
-                    results.sort(key=lambda x: x[sort_idx])
-                if report['limitt']:
-                    results = results[:int(report['limitt'])]
-                res = self._create_table(uid, ids, report, fields, None, results, context)
-
-        elif report['type'] in ('pie','bar', 'line'):
-            results2 = []
-            prev = False
-            for r in results:
-                row = []
-                for j in range(len(r)):
-                    if j == 0 and not r[j]:
-                        row.append(prev)
-                    elif j == 0 and r[j]:
-                        prev = r[j]
-                        row.append(r[j])
-                    else:
-                        try:
-                            row.append(float(r[j]))
-                        except Exception:
-                            row.append(r[j])
-                results2.append(row)
-            if report['type']=='pie':
-                res = self._create_pie(cr,uid, ids, report, fields, results2, context)
-            elif report['type']=='bar':
-                res = self._create_bars(cr,uid, ids, report, fields, results2, context)
-            elif report['type']=='line':
-                res = self._create_lines(cr,uid, ids, report, fields, results2, context)
-
-        return self.obj.get(), 'pdf'
-
-    def _create_tree(self, uid, ids, report, fields, level, results, context):
-        pageSize=common.pageSize.get(report['print_format'], [210.0,297.0])
-        if report['print_orientation']=='landscape':
-            pageSize=[pageSize[1],pageSize[0]]
-
-        new_doc = etree.Element('report')
-
-        config = etree.SubElement(new_doc, 'config')
-
-        def _append_node(name, text):
-            n = etree.SubElement(config, name)
-            n.text = text
-
-        _append_node('date', time.strftime('%d/%m/%Y'))
-        _append_node('PageFormat', '%s' % report['print_format'])
-        _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
-        _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
-        _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
-
-        length = pageSize[0]-30-reduce(lambda x,y:x+(y['width'] or 0), fields, 0)
-        count = 0
-        for f in fields:
-            if not f['width']: count+=1
-        for f in fields:
-            if not f['width']:
-                f['width']=round((float(length)/count)-0.5)
-
-        _append_node('tableSize', '%s' %  ','.join(map(lambda x: '%.2fmm' % (x['width'],), fields)))
-        _append_node('report-header', '%s' % (report['title'],))
-        _append_node('report-footer', '%s' % (report['footer'],))
-
-        header = etree.SubElement(new_doc, 'header')
-        for f in fields:
-            field = etree.SubElement(header, 'field')
-            field.text = f['name']
-
-        lines = etree.SubElement(new_doc, 'lines')
-        level.reverse()
-        for line in results:
-            shift = level.pop()
-            node_line = etree.SubElement(lines, 'row')
-            prefix = '+'
-            for f in range(len(fields)):
-                col = etree.SubElement(node_line, 'col')
-                if f == 0:
-                    col.attrib.update(para='yes',
-                                      tree='yes',
-                                      space=str(3*shift)+'mm')
-                if line[f] is not None:
-                    col.text = prefix+str(line[f]) or ''
-                else:
-                    col.text = '/'
-                prefix = ''
-
-        transform = etree.XSLT(
-            etree.parse(os.path.join(tools.config['root_path'],
-                                     'addons/base/report/custom_new.xsl')))
-        rml = etree.tostring(transform(new_doc))
-
-        self.obj = render.rml(rml)
-        self.obj.render()
-        return True
-
-    def _create_lines(self, cr, uid, ids, report, fields, results, context):
-        env = odoo.api.Environment(cr, uid, context or {})
-        pdf_string = cStringIO.StringIO()
-
-        can = canvas.init(fname=pdf_string, format='pdf')
-        can.show(80,380,'/16/H'+report['title'])
-
-        ar = area.T(size=(350,350),
-                    #x_coord = category_coord.T(['2005-09-01','2005-10-22'],0),
-                    x_axis=axis.X(label = fields[0]['name'], format="/a-30{}%s"),
-                    y_axis=axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
-
-        process_date = {
-            'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
-            'M': lambda x: x.split('-')[1],
-            'Y': lambda x: x.split('-')[0]
-        }
-
-        abscissa = []
-
-        idx = 0 
-        date_idx = None
-        fct = {}
-        for f in fields:
-            field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
-            if field_id:
-                ttype = env['ir.model.fields'].sudo().browse(field_id).ttype
-                if ttype == 'date':
-                    date_idx = idx
-                    fct[idx] = process_date[report['frequency']] 
-                else:
-                    fct[idx] = lambda x : x
-            else:
-                fct[idx] = lambda x : x
-            idx+=1
-
-        # plots are usually displayed year by year
-        # so we do so if the first field is a date
-        data_by_year = {}
-        if date_idx is not None:
-            for r in results:
-                key = process_date['Y'](r[date_idx])
-                if key not in data_by_year:
-                    data_by_year[key] = []
-                for i in range(len(r)):
-                    r[i] = fct[i](r[i])
-                data_by_year[key].append(r)
-        else:
-            data_by_year[''] = results
-
-        idx0 = 0
-        nb_bar = len(data_by_year)*(len(fields)-1)
-        colors = map(lambda x:line_style.T(color=x), misc.choice_colors(nb_bar))
-        abscissa = {}
-        for line in data_by_year.keys():
-            fields_bar = []
-            # sum data and save it in a list. An item for a fields
-            for d in data_by_year[line]:
-                for idx in range(len(fields)-1):
-                    fields_bar.append({})
-                    if d[0] in fields_bar[idx]:
-                        fields_bar[idx][d[0]] += d[idx+1]
-                    else:
-                        fields_bar[idx][d[0]] = d[idx+1]
-            for idx  in range(len(fields)-1):
-                data = {}
-                for k in fields_bar[idx].keys():
-                    if k in data:
-                        data[k] += fields_bar[idx][k]
-                    else:
-                        data[k] = fields_bar[idx][k]
-                data_cum = []
-                prev = 0.0
-                keys = data.keys()
-                keys.sort()
-                # cumulate if necessary
-                for k in keys:
-                    data_cum.append([k, float(data[k])+float(prev)])
-                    if fields[idx+1]['cumulate']:
-                        prev += data[k]
-                idx0 = 0
-                plot = line_plot.T(label=fields[idx+1]['name']+' '+str(line), data = data_cum, line_style=colors[idx0*(len(fields)-1)+idx])
-                ar.add_plot(plot)
-                abscissa.update(fields_bar[idx])
-                idx0 += 1
-
-        abscissa = map(lambda x : [x, None], abscissa)
-        ar.x_coord = category_coord.T(abscissa,0)
-        ar.draw(can)
-
-        can.close()
-        self.obj = external_pdf(pdf_string.getvalue())
-        self.obj.render()
-        pdf_string.close()
-        return True
-
-    def _create_bars(self, cr, uid, ids, report, fields, results, context):
-        env = odoo.api.Environment(cr, uid, context or {})
-        pdf_string = cStringIO.StringIO()
-
-        can = canvas.init(fname=pdf_string, format='pdf')
-        can.show(80,380,'/16/H'+report['title'])
-
-        process_date = {
-            'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
-            'M': lambda x: x.split('-')[1],
-            'Y': lambda x: x.split('-')[0]
-        }
-
-        ar = area.T(size=(350,350),
-                    x_axis=axis.X(label = fields[0]['name'], format="/a-30{}%s"),
-                    y_axis=axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
-
-        idx = 0 
-        date_idx = None
-        fct = {}
-        for f in fields:
-            field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
-            if field_id:
-                ttype = env['ir.model.fields'].sudo().browse(field_id).ttype
-                if ttype == 'date':
-                    date_idx = idx
-                    fct[idx] = process_date[report['frequency']] 
-                else:
-                    fct[idx] = lambda x : x
-            else:
-                fct[idx] = lambda x : x
-            idx+=1
-
-        # plot are usually displayed year by year
-        # so we do so if the first field is a date
-        data_by_year = {}
-        if date_idx is not None:
-            for r in results:
-                key = process_date['Y'](r[date_idx])
-                if key not in data_by_year:
-                    data_by_year[key] = []
-                for i in range(len(r)):
-                    r[i] = fct[i](r[i])
-                data_by_year[key].append(r)
-        else:
-            data_by_year[''] = results
-
-
-        nb_bar = len(data_by_year)*(len(fields)-1)
-        colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(nb_bar))
-
-        abscissa = {}
-        for line in data_by_year.keys():
-            fields_bar = []
-            # sum data and save it in a list. An item for a fields
-            for d in data_by_year[line]:
-                for idx in range(len(fields)-1):
-                    fields_bar.append({})
-                    if d[0] in fields_bar[idx]:
-                        fields_bar[idx][d[0]] += d[idx+1]
-                    else:
-                        fields_bar[idx][d[0]] = d[idx+1]
-            for idx  in range(len(fields)-1):
-                data = {}
-                for k in fields_bar[idx].keys():
-                    if k in data:
-                        data[k] += fields_bar[idx][k]
-                    else:
-                        data[k] = fields_bar[idx][k]
-                data_cum = []
-                prev = 0.0
-                keys = data.keys()
-                keys.sort()
-                # cumulate if necessary
-                for k in keys:
-                    data_cum.append([k, float(data[k])+float(prev)])
-                    if fields[idx+1]['cumulate']:
-                        prev += data[k]
-
-                idx0 = 0
-                plot = bar_plot.T(label=fields[idx+1]['name']+' '+str(line), data = data_cum, cluster=(idx0*(len(fields)-1)+idx,nb_bar), fill_style=colors[idx0*(len(fields)-1)+idx])
-                ar.add_plot(plot)
-                abscissa.update(fields_bar[idx])
-            idx0 += 1
-        abscissa = map(lambda x : [x, None], abscissa)
-        abscissa.sort()
-        ar.x_coord = category_coord.T(abscissa,0)
-        ar.draw(can)
-
-        can.close()
-        self.obj = external_pdf(pdf_string.getvalue())
-        self.obj.render()
-        pdf_string.close()
-        return True
-
-    def _create_pie(self, cr, uid, ids, report, fields, results, context):
-        pdf_string = cStringIO.StringIO()
-        can = canvas.init(fname=pdf_string, format='pdf')
-        ar = area.T(size=(350,350), legend=legend.T(),
-                    x_grid_style = None, y_grid_style = None)
-        colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(len(results)))
-
-        if reduce(lambda x,y : x+y, map(lambda x : x[1],results)) == 0.0:
-            raise UserError(_("The sum of the data (2nd field) is null.\nWe can't draw a pie chart !"))
-
-        plot = pie_plot.T(data=results, arc_offsets=[0,10,0,10],
-                          shadow = (2, -2, fill_style.gray50),
-                          label_offset = 25,
-                          arrow_style = arrow.a3,
-                          fill_styles=colors)
-        ar.add_plot(plot)
-        ar.draw(can)
-        can.close()
-        self.obj = external_pdf(pdf_string.getvalue())
-        self.obj.render()
-        pdf_string.close()
-        return True
-
-    def _create_table(self, uid, ids, report, fields, tree, results, context):
-        pageSize=common.pageSize.get(report['print_format'], [210.0,297.0])
-        if report['print_orientation']=='landscape':
-            pageSize=[pageSize[1],pageSize[0]]
-
-        new_doc = etree.Element('report')
-        config = etree.SubElement(new_doc, 'config')
-
-        def _append_node(name, text):
-            n = etree.SubElement(config, name)
-            n.text = text
-
-        _append_node('date', time.strftime('%d/%m/%Y'))
-        _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
-        _append_node('PageFormat', '%s' % report['print_format'])
-        _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
-        _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
-
-        length = pageSize[0]-30-reduce(lambda x,y:x+(y['width'] or 0), fields, 0)
-        count = 0
-        for f in fields:
-            if not f['width']: count+=1
-        for f in fields:
-            if not f['width']:
-                f['width']=round((float(length)/count)-0.5)
-
-        _append_node('tableSize', '%s' %  ','.join(map(lambda x: '%.2fmm' % (x['width'],), fields)))
-        _append_node('report-header', '%s' % (report['title'],))
-        _append_node('report-footer', '%s' % (report['footer'],))
-
-        header = etree.SubElement(new_doc, 'header')
-        for f in fields:
-            field = etree.SubElement(header, 'field')
-            field.text = f['name']
-
-        lines = etree.SubElement(new_doc, 'lines')
-        for line in results:
-            node_line = etree.SubElement(lines, 'row')
-            for f in range(len(fields)):
-                col = etree.SubElement(node_line, 'col', tree='no')
-                if line[f] is not None:
-                    col.text = line[f] or ''
-                else:
-                    col.text = '/'
-
-        transform = etree.XSLT(
-            etree.parse(os.path.join(tools.config['root_path'],
-                                     'addons/base/report/custom_new.xsl')))
-        rml = etree.tostring(transform(new_doc))
-
-        self.obj = render.rml(rml)
-        self.obj.render()
-        return True
-
-report_custom('report.custom')
diff --git a/odoo/report/int_to_text.py b/odoo/report/int_to_text.py
deleted file mode 100644
index 96e07f179bb8ccb03e288834a813a764ff263947..0000000000000000000000000000000000000000
--- a/odoo/report/int_to_text.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-unites = {
-    0: '', 1:'un', 2:'deux', 3:'trois', 4:'quatre', 5:'cinq', 6:'six', 7:'sept', 8:'huit', 9:'neuf',
-    10:'dix', 11:'onze', 12:'douze', 13:'treize', 14:'quatorze', 15:'quinze', 16:'seize',
-    21:'vingt et un', 31:'trente et un', 41:'quarante et un', 51:'cinquante et un', 61:'soixante et un',
-    71:'septante et un', 91:'nonante et un', 80:'quatre-vingts'
-}
-
-dizaine = {
-    1: 'dix', 2:'vingt', 3:'trente',4:'quarante', 5:'cinquante', 6:'soixante', 7:'septante', 8:'quatre-vingt', 9:'nonante'
-}
-
-centaine = {
-    0:'', 1: 'cent', 2:'deux cent', 3:'trois cent',4:'quatre cent', 5:'cinq cent', 6:'six cent', 7:'sept cent', 8:'huit cent', 9:'neuf cent'
-}
-
-mille = {
-    0:'', 1:'mille'
-}
-
-def _100_to_text(chiffre):
-    if chiffre in unites:
-        return unites[chiffre]
-    else:
-        if chiffre%10>0:
-            return dizaine[chiffre / 10]+'-'+unites[chiffre % 10]
-        else:
-            return dizaine[chiffre / 10]
-
-def _1000_to_text(chiffre):
-    d = _100_to_text(chiffre % 100)
-    d2 = chiffre/100
-    if d2>0 and d:
-        return centaine[d2]+' '+d
-    elif d2>1 and not d:
-        return centaine[d2]+'s'
-    else:
-        return centaine[d2] or d
-
-def _10000_to_text(chiffre):
-    if chiffre==0:
-        return 'zero'
-    part1 = _1000_to_text(chiffre % 1000)
-    part2 = mille.get(chiffre / 1000,  _1000_to_text(chiffre / 1000)+' mille')
-    if part2 and part1:
-        part1 = ' '+part1
-    return part2+part1
-
-def int_to_text(i):
-    return _10000_to_text(i)
-
-if __name__=='__main__':
-    for i in range(1,999999,139):
-        print int_to_text(i)
diff --git a/odoo/report/interface.py b/odoo/report/interface.py
deleted file mode 100644
index ef0784fb518c5027e89303e533a78ae87850f9cc..0000000000000000000000000000000000000000
--- a/odoo/report/interface.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import os
-import re
-import urllib
-
-from lxml import etree
-
-import odoo
-import odoo.tools as tools
-from . import print_xml
-from . import render
-from odoo.modules import get_module_resource
-
-#
-# coerce any type to a unicode string (to preserve non-ascii characters)
-# and escape XML entities
-#
-def toxml(value):
-    unicode_value = tools.ustr(value)
-    return unicode_value.replace('&', '&amp;').replace('<','&lt;').replace('>','&gt;')
-
-
-class report_int(object):
-
-    _reports = {}
-    
-    def __init__(self, name, register=True):
-        if register:
-            assert odoo.conf.deprecation.allow_report_int_registration
-            assert name.startswith('report.'), 'Report names should start with "report.".'
-            assert name not in self._reports, 'The report "%s" already exists.' % name
-            self._reports[name] = self
-        else:
-            # The report is instanciated at each use site, which is ok.
-            pass
-
-        self.__name = name
-
-        self.name = name
-        self.id = 0
-        self.name2 = '.'.join(name.split('.')[1:])
-        # TODO the reports have methods with a 'title' kwarg that is redundant with this attribute
-        self.title = None
-
-    def create(self, cr, uid, ids, datas, context=None):
-        return False
-
-
-class report_rml(report_int):
-    """
-        Automatically builds a document using the transformation process:
-            XML -> DATAS -> RML -> PDF -> HTML
-        using a XSL:RML transformation
-    """
-    def __init__(self, name, table, tmpl, xsl, register=True):
-        super(report_rml, self).__init__(name, register=register)
-        self.table = table
-        self.internal_header=False
-        self.tmpl = tmpl
-        self.xsl = xsl
-        self.bin_datas = {}
-        self.generators = {
-            'pdf': self.create_pdf,
-            'html': self.create_html,
-            'raw': self.create_raw,
-            'sxw': self.create_sxw,
-            'txt': self.create_txt,
-            'odt': self.create_odt,
-            'html2html' : self.create_html2html,
-            'makohtml2html' :self.create_makohtml2html,
-        }
-
-    def create(self, cr, uid, ids, datas, context=None):
-        env = odoo.api.Environment(cr, uid, context or {})
-        xml = self.create_xml(cr, uid, ids, datas, context)
-        xml = tools.ustr(xml).encode('utf8')
-        report_type = datas.get('report_type', 'pdf')
-        if report_type == 'raw':
-            return xml, report_type
-
-        env['res.font'].sudo().font_scan(lazy=True)
-
-        rml = self.create_rml(cr, xml, uid, context)
-        reports = env['ir.actions.report.xml'].search([('report_name', '=', self.name[7:])])
-        self.title = reports[0].name if reports else 'Odoo Report'
-        create_doc = self.generators[report_type]
-        pdf = create_doc(rml, title=self.title)
-        return pdf, report_type
-
-    def create_xml(self, cr, uid, ids, datas, context=None):
-        doc = print_xml.document(cr, uid, datas, {})
-        self.bin_datas.update( doc.bin_datas  or {})
-        doc.parse(self.tmpl, ids, self.table, context)
-        xml = doc.xml_get()
-        doc.close()
-        return self.post_process_xml_data(cr, uid, xml, context)
-
-    def post_process_xml_data(self, cr, uid, xml, context=None):
-        # find the position of the 3rd tag
-        # (skip the <?xml ...?> and the "root" tag)
-        iter = re.finditer('<[^>]*>', xml)
-        i = iter.next()
-        i = iter.next()
-        pos_xml = i.end()
-
-        doc = print_xml.document(cr, uid, {}, {})
-        tmpl_path = get_module_resource('base', 'report', 'corporate_defaults.xml')
-        doc.parse(tmpl_path, [uid], 'res.users', context)
-        corporate_header = doc.xml_get()
-        doc.close()
-
-        # find the position of the tag after the <?xml ...?> tag
-        iter = re.finditer('<[^>]*>', corporate_header)
-        i = iter.next()
-        pos_header = i.end()
-
-        return xml[:pos_xml] + corporate_header[pos_header:] + xml[pos_xml:]
-
-    #
-    # TODO: The translation doesn't work for "<tag t="1">textext<tag> tex</tag>text</tag>"
-    #
-    def create_rml(self, cr, xml, uid, context=None):
-        if self.tmpl=='' and not self.internal_header:
-            self.internal_header=True
-        env = odoo.api.Environment(cr, uid, context or {})
-        Translation = env['ir.translation']
-
-        # In some case we might not use xsl ...
-        if not self.xsl:
-            return xml
-
-        stylesheet_file = tools.file_open(self.xsl)
-        try:
-            stylesheet = etree.parse(stylesheet_file)
-            xsl_path, _ = os.path.split(self.xsl)
-            for import_child in stylesheet.findall('./import'):
-                if 'href' in import_child.attrib:
-                    imp_file = import_child.get('href')
-                    _, imp_file = tools.file_open(imp_file, subdir=xsl_path, pathinfo=True)
-                    import_child.set('href', urllib.quote(str(imp_file)))
-                    imp_file.close()
-        finally:
-            stylesheet_file.close()
-
-        #TODO: get all the translation in one query. That means we have to:
-        # * build a list of items to translate,
-        # * issue the query to translate them,
-        # * (re)build/update the stylesheet with the translated items
-
-        def translate(doc, lang):
-            translate_aux(doc, lang, False)
-
-        def translate_aux(doc, lang, t):
-            for node in doc:
-                t = t or node.get("t")
-                if t:
-                    text = None
-                    tail = None
-                    if node.text:
-                        text = node.text.strip().replace('\n',' ')
-                    if node.tail:
-                        tail = node.tail.strip().replace('\n',' ')
-                    if text:
-                        text1 = Translation._get_source(self.name2, 'xsl', lang, text)
-                        if text1:
-                            node.text = node.text.replace(text, text1)
-                    if tail:
-                        tail1 = Translation._get_source(self.name2, 'xsl', lang, tail)
-                        if tail1:
-                            node.tail = node.tail.replace(tail, tail1)
-                translate_aux(node, lang, t)
-
-        if env.lang:
-            translate(stylesheet.iter(), env.lang)
-
-        transform = etree.XSLT(stylesheet)
-        xml = etree.tostring(
-            transform(etree.fromstring(xml)))
-
-        return xml
-
-    def create_pdf(self, rml, localcontext=None, logo=None, title=None):
-        if not localcontext:
-            localcontext = {}
-        localcontext.update({'internal_header':self.internal_header})
-        if logo:
-            self.bin_datas['logo'] = logo
-        else:
-            if 'logo' in self.bin_datas:
-                del self.bin_datas['logo']
-        obj = render.rml(rml, localcontext, self.bin_datas, self._get_path(), title)
-        obj.render()
-        return obj.get()
-
-    def create_html(self, rml, localcontext=None, logo=None, title=None):
-        obj = render.rml2html(rml, localcontext, self.bin_datas)
-        obj.render()
-        return obj.get()
-
-    def create_txt(self, rml,localcontext, logo=None, title=None):
-        obj = render.rml2txt(rml, localcontext, self.bin_datas)
-        obj.render()
-        return obj.get().encode('utf-8')
-
-    def create_html2html(self, rml, localcontext=None, logo=None, title=None):
-        obj = render.html2html(rml, localcontext, self.bin_datas)
-        obj.render()
-        return obj.get()
-
-
-    def create_raw(self,rml, localcontext=None, logo=None, title=None):
-        obj = render.odt2odt(etree.XML(rml),localcontext)
-        obj.render()
-        return etree.tostring(obj.get())
-
-    def create_sxw(self,rml,localcontext=None):
-        obj = render.odt2odt(rml,localcontext)
-        obj.render()
-        return obj.get()
-
-    def create_odt(self,rml,localcontext=None):
-        obj = render.odt2odt(rml,localcontext)
-        obj.render()
-        return obj.get()
-
-    def create_makohtml2html(self,html,localcontext=None):
-        obj = render.makohtml2html(html,localcontext)
-        obj.render()
-        return obj.get()
-
-    def _get_path(self):
-        return [
-            self.tmpl.replace(os.path.sep, '/').rsplit('/', 1)[0],
-            'addons',
-            tools.config['root_path']
-        ]
diff --git a/odoo/report/misc.py b/odoo/report/misc.py
deleted file mode 100644
index 0b735abca7c5814fde814d43ccc1277fcf0e1013..0000000000000000000000000000000000000000
--- a/odoo/report/misc.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from pychart import color
-
-colorline = [color.T(r=((r+3) % 11)/10.0,
-                     g=((g+6) % 11)/10.0,
-                     b=((b+9) % 11)/10.0)
-             for r in range(11) for g in range(11) for b in range(11)]
-
-def choice_colors(n):
-    if n:
-        return colorline[0:-1:len(colorline)/n]
-    return []
-
-if __name__=='__main__':
-    print choice_colors(10)
diff --git a/odoo/report/preprocess.py b/odoo/report/preprocess.py
deleted file mode 100644
index 16f35e1f49ac5ffbf5c96e712733e5eb72a8de72..0000000000000000000000000000000000000000
--- a/odoo/report/preprocess.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import re
-
-from lxml import etree
-
-rml_parents = ['tr','story','section']
-html_parents = ['tr','body','div']
-sxw_parents = ['{http://openoffice.org/2000/table}table-row','{http://openoffice.org/2000/office}body','{http://openoffice.org/2000/text}section']
-odt_parents = ['{urn:oasis:names:tc:opendocument:xmlns:office:1.0}body','{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table-row','{urn:oasis:names:tc:opendocument:xmlns:text:1.0}section']
-
-
-class report(object):
-    def preprocess_rml(self, root_node,type='pdf'):
-        _regex1 = re.compile("\[\[(.*?)(repeatIn\(.*?\s*,\s*[\'\"].*?[\'\"]\s*(?:,\s*(.*?)\s*)?\s*\))(.*?)\]\]")
-        _regex11= re.compile("\[\[(.*?)(repeatIn\(.*?\s*\(.*?\s*[\'\"].*?[\'\"]\s*\),[\'\"].*?[\'\"](?:,\s*(.*?)\s*)?\s*\))(.*?)\]\]")
-        _regex2 = re.compile("\[\[(.*?)(removeParentNode\(\s*(?:['\"](.*?)['\"])\s*\))(.*?)\]\]")
-        _regex3 = re.compile("\[\[\s*(.*?setTag\(\s*['\"](.*?)['\"]\s*,\s*['\"].*?['\"]\s*(?:,.*?)?\).*?)\s*\]\]")
-        for node in root_node:
-            if node.tag == etree.Comment:
-                continue
-            if node.text or node.tail:
-                def _sub3(txt):
-                    n = node
-                    while n.tag != txt.group(2):
-                        n = n.getparent()
-                    n.set('rml_tag', txt.group(1))
-                    return "[[ '' ]]"
-                def _sub2(txt):
-                    if txt.group(3):
-                        n = node
-                        try:
-                            while n.tag != txt.group(3):
-                                n = n.getparent()
-                        except Exception:
-                            n = node
-                    else:
-                        n = node.getparent()
-                    n.set('rml_except', txt.group(0)[2:-2])
-                    return txt.group(0)
-                def _sub1(txt):
-                    if len(txt.group(4)) > 1:
-                        return " "
-                    match = rml_parents
-                    if type == 'odt':
-                        match = odt_parents
-                    if type == 'sxw':
-                        match = sxw_parents
-                    if type =='html2html':
-                        match = html_parents
-                    if txt.group(3):
-                        group_3 = txt.group(3)
-                        if group_3.startswith("'") or group_3.startswith('"'):
-                            group_3 = group_3[1:-1]
-                        match = [group_3]
-                    n = node
-                    while n.tag not in match:
-                        n = n.getparent()
-                    n.set('rml_loop', txt.group(2))
-                    return '[['+txt.group(1)+"''"+txt.group(4)+']]'
-                t = _regex1.sub(_sub1, node.text or node.tail)
-                if t == " ":
-                    t = _regex11.sub(_sub1, node.text  or node.tail)
-                t = _regex3.sub(_sub3, t)
-                node.text = _regex2.sub(_sub2, t)
-            self.preprocess_rml(node,type)
-        return root_node
-
-if __name__=='__main__':
-    node = etree.XML('''<story>
-    <para>This is a test[[ setTag('para','xpre') ]]</para>
-    <blockTable>
-    <tr>
-        <td><para>Row 1 [[ setTag('tr','tr',{'style':'TrLevel'+str(a['level']), 'paraStyle':('Level'+str(a['level']))}) ]] </para></td>
-        <td>Row 2 [[ True and removeParentNode('td') ]] </td>
-    </tr><tr>
-        <td>Row 1 [[repeatIn(o.order_line,'o')]] </td>
-        <td>Row 2</td>
-    </tr>
-    </blockTable>
-    <p>This isa test</p>
-</story>''')
-    a = report()
-    result = a.preprocess_rml(node)
-    print etree.tostring(result)
diff --git a/odoo/report/print_fnc.py b/odoo/report/print_fnc.py
deleted file mode 100644
index 80ad11546717a501e8e5e5f8cd0c21de19ff9df9..0000000000000000000000000000000000000000
--- a/odoo/report/print_fnc.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import time
-
-functions = {
-    'today': lambda x: time.strftime('%d/%m/%Y', time.localtime()).decode('latin1')
-}
-
-#
-# TODO: call an object internal function too
-#
-def print_fnc(fnc, arg):
-    if fnc in functions:
-        return functions[fnc](arg)
-    return ''
diff --git a/odoo/report/print_xml.py b/odoo/report/print_xml.py
deleted file mode 100644
index 3fe9b959f88a0f5fa0415f0ed29e749b709e2adc..0000000000000000000000000000000000000000
--- a/odoo/report/print_xml.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from lxml import etree
-
-import odoo
-import odoo.tools as tools
-from . import print_fnc
-from odoo.models import BaseModel
-from odoo.tools.safe_eval import safe_eval
-
-
-class InheritDict(dict):
-    # Might be useful when we're doing name lookup for call or eval.
-    def __init__(self, parent=None):
-        self.parent = parent
-
-    def __getitem__(self, name):
-        if name in self:
-            return super(InheritDict, self).__getitem__(name)
-        else:
-            if not self.parent:
-                raise KeyError
-            else:
-                return self.parent[name]
-
-
-def tounicode(val):
-    if isinstance(val, str):
-        unicode_val = unicode(val, 'utf-8')
-    elif isinstance(val, unicode):
-        unicode_val = val
-    else:
-        unicode_val = unicode(val)
-    return unicode_val
-
-
-class document(object):
-    def __init__(self, cr, uid, datas, func=False):
-        # create a new document
-        self.cr = cr
-        self.uid = uid
-        self.datas = datas
-        self.func = func or {}
-        self.bin_datas = {}
-
-    def node_attrs_get(self, node):
-        if len(node.attrib):
-            return node.attrib
-        return {}
-
-    def get_value(self, browser, field_path):
-        fields = field_path.split('.')
-
-        if not len(fields):
-            return ''
-
-        value = browser
-
-        for f in fields:
-            if isinstance(value, (BaseModel, list)):
-                if not value:
-                    return ''
-                value = value[0]
-            value = value[f]
-
-        return value or ''
-
-    def get_value2(self, browser, field_path):
-        value = self.get_value(browser, field_path)
-        if isinstance(value, BaseModel):
-            return value.id
-        else:
-            return value
-
-    def eval(self, record, expr):
-#TODO: support remote variables (eg address.title) in expr
-# how to do that: parse the string, find dots, replace those dotted variables by temporary
-# "simple ones", fetch the value of those variables and add them (temporarily) to the _data
-# dictionary passed to eval
-
-#FIXME: it wont work if the data hasn't been fetched yet... this could
-# happen if the eval node is the first one using this Record
-# the next line is a workaround for the problem: it causes the resource to be loaded
-#Pinky: Why not this ? eval(expr, browser) ?
-#       name = browser.name
-#       data_dict = browser._data[self.get_value(browser, 'id')]
-        return safe_eval(expr, {}, {'obj': record})
-
-    def parse_node(self, node, parent, browser, datas=None):
-        env = odoo.api.Environment(self.cr, self.uid, {})
-        attrs = self.node_attrs_get(node)
-        if 'type' in attrs:
-            if attrs['type']=='field':
-                value = self.get_value(browser, attrs['name'])
-                #TODO: test this
-                if value == '' and 'default' in attrs:
-                    value = attrs['default']
-                el = etree.SubElement(parent, node.tag)
-                el.text = tounicode(value)
-                #TODO: test this
-                for key, value in attrs.iteritems():
-                    if key not in ('type', 'name', 'default'):
-                        el.set(key, value)
-
-            elif attrs['type']=='attachment':
-                model = browser._name
-                value = self.get_value(browser, attrs['name'])
-
-                atts = env['ir.attachment'].search([('res_model','=',model),('res_id','=',int(value))])
-                datas = atts.read()
-
-                if len(datas):
-                    # if there are several, pick first
-                    datas = datas[0]
-                    fname = str(datas['datas_fname'])
-                    ext = fname.split('.')[-1].lower()
-                    if ext in ('jpg','jpeg', 'png'):
-                        import base64
-                        from StringIO import StringIO
-                        dt = base64.decodestring(datas['datas'])
-                        fp = StringIO()
-                        fp.write(dt)
-                        i = str(len(self.bin_datas))
-                        self.bin_datas[i] = fp
-                        el = etree.SubElement(parent, node.tag)
-                        el.text = i
-
-            elif attrs['type']=='data':
-                #TODO: test this
-                txt = self.datas.get('form', {}).get(attrs['name'], '')
-                el = etree.SubElement(parent, node.tag)
-                el.text = txt
-
-            elif attrs['type']=='function':
-                if attrs['name'] in self.func:
-                    txt = self.func[attrs['name']](node)
-                else:
-                    txt = print_fnc.print_fnc(attrs['name'], node)
-                el = etree.SubElement(parent, node.tag)
-                el.text = txt
-
-            elif attrs['type']=='eval':
-                value = self.eval(browser, attrs['expr'])
-                el = etree.SubElement(parent, node.tag)
-                el.text = str(value)
-
-            elif attrs['type']=='fields':
-                fields = attrs['name'].split(',')
-                vals = {}
-                for b in browser:
-                    value = tuple([self.get_value2(b, f) for f in fields])
-                    if not value in vals:
-                        vals[value]=[]
-                    vals[value].append(b)
-                keys = vals.keys()
-                keys.sort()
-
-                if 'order' in attrs and attrs['order']=='desc':
-                    keys.reverse()
-
-                v_list = [vals[k] for k in keys]
-                for v in v_list:
-                    el = etree.SubElement(parent, node.tag)
-                    for el_cld in node:
-                        self.parse_node(el_cld, el, v)
-
-            elif attrs['type']=='call':
-                if len(attrs['args']):
-                    #TODO: test this
-                    # fetches the values of the variables which names where passed in the args attribute
-                    args = [self.eval(browser, arg) for arg in attrs['args'].split(',')]
-                else:
-                    args = []
-                # get the object
-                if 'model' in attrs:
-                    obj = env[attrs['model']]
-                else:
-                    obj = browser       # the record(set) is an instance of the model
-
-                # get the ids
-                if 'ids' in attrs:
-                    ids = self.eval(browser, attrs['ids'])
-                else:
-                    ids = browser.ids
-
-                # call the method itself
-                newdatas = getattr(obj, attrs['name'])(*args)
-
-                def parse_result_tree(node, parent, datas):
-                    if not node.tag == etree.Comment:
-                        el = etree.SubElement(parent, node.tag)
-                        atr = self.node_attrs_get(node)
-                        if 'value' in atr:
-                            if not isinstance(datas[atr['value']], (str, unicode)):
-                                txt = str(datas[atr['value']])
-                            else:
-                                txt = datas[atr['value']]
-                            el.text = txt
-                        else:
-                            for el_cld in node:
-                                parse_result_tree(el_cld, el, datas)
-                if not isinstance(newdatas, (BaseModel, list)):
-                    newdatas = [newdatas]
-                for newdata in newdatas:
-                    parse_result_tree(node, parent, newdata)
-
-            elif attrs['type']=='zoom':
-                value = self.get_value(browser, attrs['name'])
-                if value:
-                    if not isinstance(value, (BaseModel, list)):
-                        v_list = [value]
-                    else:
-                        v_list = value
-                    for v in v_list:
-                        el = etree.SubElement(parent, node.tag)
-                        for el_cld in node:
-                            self.parse_node(el_cld, el, v)
-        else:
-            # if there is no "type" attribute in the node, copy it to the xml data and parse its children
-            if not node.tag == etree.Comment:
-                if node.tag == parent.tag:
-                    el = parent
-                else:
-                    el = etree.SubElement(parent, node.tag)
-                for el_cld in node:
-                    self.parse_node(el_cld,el, browser)
-
-    def xml_get(self):
-        return etree.tostring(self.doc,encoding="utf-8",xml_declaration=True,pretty_print=True)
-
-    def parse_tree(self, ids, model, context=None):
-        env = odoo.api.Environment(self.cr, self.uid, context or {})
-        browser = env[model].browse(ids)
-        self.parse_node(self.dom, self.doc, browser)
-
-    def parse_string(self, xml, ids, model, context=None):
-        # parses the xml template to memory
-        self.dom = etree.XML(xml)
-        # create the xml data from the xml template
-        self.parse_tree(ids, model, context)
-
-    def parse(self, filename, ids, model, context=None):
-        # parses the xml template to memory
-        src_file = tools.file_open(filename)
-        try:
-            self.dom = etree.XML(src_file.read())
-            self.doc = etree.Element(self.dom.tag)
-            self.parse_tree(ids, model, context)
-        finally:
-            src_file.close()
-
-    def close(self):
-        self.doc = None
-        self.dom = None
diff --git a/odoo/report/printscreen/__init__.py b/odoo/report/printscreen/__init__.py
deleted file mode 100644
index 5c442c68695740f77dd5a04d0f3ce343c27b0d9d..0000000000000000000000000000000000000000
--- a/odoo/report/printscreen/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from . import ps_list
-from . import ps_form
-
-
-""" A special report, that is automatically formatted to look like the
-    screen contents of Form/List Views.
-"""
diff --git a/odoo/report/printscreen/ps_form.py b/odoo/report/printscreen/ps_form.py
deleted file mode 100644
index c063d04f3d5a183525e4b10296c74cf40412c642..0000000000000000000000000000000000000000
--- a/odoo/report/printscreen/ps_form.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import os
-import time
-
-from lxml import etree
-
-import odoo
-import odoo.tools as tools
-from odoo.report import render
-from odoo.report.interface import report_int
-
-
-class report_printscreen_list(report_int):
-    def _parse_node(self, root_node):
-        result = []
-        for node in root_node:
-            if node.tag == 'field':
-                attrsa = node.attrib
-                attrs = {}
-                if not attrsa is None:
-                    for key,val in attrsa.items():
-                        attrs[key] = val
-                result.append(attrs['name'])
-            else:
-                result.extend(self._parse_node(node))
-        return result
-
-    def _parse_string(self, view):
-        dom = etree.XML(view)
-        return self._parse_node(dom)
-
-    def create(self, cr, uid, ids, datas, context=None):
-        if not context:
-            context={}
-        env = odoo.api.Environment(cr, uid, context)
-        datas['ids'] = ids
-        records = env[datas['model']].browse(ids)
-        # title come from description of model which are specified in py file.
-        self.title = records._description
-        result = records.fields_view_get(view_type='form')
-
-        fields_order = self._parse_string(result['arch'])
-        rows = records.read(list(result['fields']))
-        self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, records._description)
-        return self.obj.get(), 'pdf'
-
-    def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
-        pageSize=[297.0,210.0]
-
-        new_doc = etree.Element("report")
-        config = etree.SubElement(new_doc, 'config')
-
-        # build header
-        def _append_node(name, text):
-            n = etree.SubElement(config, name)
-            n.text = text
-
-        _append_node('date', time.strftime('%d/%m/%Y'))
-        _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
-        _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
-        _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
-        _append_node('report-header', title)
-
-        l = []
-        t = 0
-        strmax = (pageSize[0]-40) * 2.8346
-        for f in fields_order:
-            s = 0
-            if fields[f]['type'] in ('date','time','float','integer'):
-                s = 60
-                strmax -= s
-            else:
-                t += fields[f].get('size', 56) / 28 + 1
-            l.append(s)
-        for pos in range(len(l)):
-            if not l[pos]:
-                s = fields[fields_order[pos]].get('size', 56) / 28 + 1
-                l[pos] = strmax * s / t
-        _append_node('tableSize', ','.join(map(str,l)) )
-
-        header = etree.SubElement(new_doc, 'header')
-        for f in fields_order:
-            field = etree.SubElement(header, 'field')
-            field.text = fields[f]['string'] or ''
-
-        lines = etree.SubElement(new_doc, 'lines')
-        for line in results:
-            node_line = etree.SubElement(lines, 'row')
-            for f in fields_order:
-                if fields[f]['type']=='many2one' and line[f]:
-                    line[f] = line[f][1]
-                if fields[f]['type'] in ('one2many','many2many') and line[f]:
-                    line[f] = '( '+str(len(line[f])) + ' )'
-                if fields[f]['type'] == 'float':
-                    precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
-                    line[f]=round(line[f],precision)
-                col = etree.SubElement(node_line, 'col', tree='no')
-                if line[f] is not None:
-                    col.text = tools.ustr(line[f] or '')
-                else:
-                    col.text = '/'
-
-        transform = etree.XSLT(
-            etree.parse(os.path.join(tools.config['root_path'],
-                                     'addons/base/report/custom_new.xsl')))
-        rml = etree.tostring(transform(new_doc))
-
-        self.obj = render.rml(rml, self.title)
-        self.obj.render()
-        return True
-
-report_printscreen_list('report.printscreen.form')
diff --git a/odoo/report/printscreen/ps_list.py b/odoo/report/printscreen/ps_list.py
deleted file mode 100644
index 5ef2ac831428ed97884b9e0ab88eca4d81cdec97..0000000000000000000000000000000000000000
--- a/odoo/report/printscreen/ps_list.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import locale
-import os
-import time
-from datetime import datetime
-
-from lxml  import etree
-
-import odoo
-import odoo.tools as tools
-from odoo.report import render, report_sxw
-from odoo.report.interface import report_int
-from odoo.tools.safe_eval import safe_eval
-
-
-class report_printscreen_list(report_int):
-    def __init__(self, name):
-        super(report_printscreen_list, self).__init__(name)
-        self.context = {}
-        self.groupby = []
-        self.cr = ''
-
-    def _parse_node(self, root_node):
-        result = []
-        for node in root_node:
-            field_name = node.get('name')
-            if not safe_eval(str(node.attrib.get('invisible',False)),{'context':self.context}):
-                if node.tag == 'field':
-                    if field_name in self.groupby:
-                        continue
-                    result.append(field_name)
-                else:
-                    result.extend(self._parse_node(node))
-        return result
-
-    def _parse_string(self, view):
-        try:
-            dom = etree.XML(view.encode('utf-8'))
-        except Exception:
-            dom = etree.XML(view)
-        return self._parse_node(dom)
-
-    def create(self, cr, uid, ids, datas, context=None):
-        if not context:
-            context = {}
-        self.cr = cr
-        self.context = context
-        self.groupby = context.get('group_by',[])
-        self.groupby_no_leaf = context.get('group_by_no_leaf', False)
-        env = odoo.api.Environment(cr, uid, context)
-        Model = env[datas['model']]
-        model = env['ir.model']._get(Model._name)
-        model_desc = model.name or Model._description
-        self.title = model_desc
-        datas['ids'] = ids
-        result = Model.fields_view_get(view_type='tree')
-        fields_order =  self.groupby + self._parse_string(result['arch'])
-        if self.groupby:
-            rows = []
-            def get_groupby_data(groupby = [], domain = []):
-                records =  Model.read_group(domain, fields_order, groupby, 0, None)
-                for rec in records:
-                    rec['__group'] = True
-                    rec['__no_leaf'] = self.groupby_no_leaf
-                    rec['__grouped_by'] = groupby[0] if (isinstance(groupby, list) and groupby) else groupby
-                    for f in fields_order:
-                        if f not in rec:
-                            rec.update({f:False})
-                        elif isinstance(rec[f], tuple):
-                            rec[f] = rec[f][1]
-                    rows.append(rec)
-                    inner_groupby = (rec.get('__context', {})).get('group_by',[])
-                    inner_domain = rec.get('__domain', [])
-                    if inner_groupby:
-                        get_groupby_data(inner_groupby, inner_domain)
-                    else:
-                        if self.groupby_no_leaf:
-                            continue
-                        children = Model.search(inner_domain)
-                        res = children.read(list(result['fields']))
-                        res.sort(key=lambda x: ids.index(x['id']))
-                        rows.extend(res)
-            dom = [('id','in',ids)]
-            if self.groupby_no_leaf and len(ids) and not ids[0]:
-                dom = datas.get('_domain',[])
-            get_groupby_data(self.groupby, dom)
-        else:
-            rows = Model.browse(ids).read(list(result['fields']))
-            if datas['ids'] != rows.ids: # sorted ids were not taken into consideration for print screen
-                rows_new = []
-                for id in datas['ids']:
-                    rows_new += [elem for elem in rows if elem['id'] == id]
-                rows = rows_new
-        res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
-        return self.obj.get(), 'pdf'
-
-    def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
-        pageSize=[297.0, 210.0]
-
-        new_doc = etree.Element("report")
-        config = etree.SubElement(new_doc, 'config')
-
-        def _append_node(name, text):
-            n = etree.SubElement(config, name)
-            n.text = text
-
-        #_append_node('date', time.strftime('%d/%m/%Y'))
-        _append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
-        _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
-        _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
-        _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
-        _append_node('report-header', title)
-
-        env = odoo.api.Environment(self.cr, uid, {})
-        Users = env['res.users']
-        _append_node('company', Users.browse(uid).company_id.name)
-        rml_obj = report_sxw.rml_parse(self.cr, uid, Users._name, context)
-        _append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")))
-        l = []
-        t = 0
-        strmax = (pageSize[0]-40) * 2.8346
-        temp = []
-        tsum = []
-        for i in range(0, len(fields_order)):
-            temp.append(0)
-            tsum.append(0)
-        ince = -1
-        for f in fields_order:
-            s = 0
-            ince += 1
-            if fields[f]['type'] in ('date','time','datetime','float','integer'):
-                s = 60
-                strmax -= s
-                if fields[f]['type'] in ('float','integer'):
-                    temp[ince] = 1
-            else:
-                t += fields[f].get('size', 80) / 28 + 1
-
-            l.append(s)
-        for pos in range(len(l)):
-            if not l[pos]:
-                s = fields[fields_order[pos]].get('size', 80) / 28 + 1
-                l[pos] = strmax * s / t
-
-        _append_node('tableSize', ','.join(map(str,l)) )
-
-        header = etree.SubElement(new_doc, 'header')
-        for f in fields_order:
-            field = etree.SubElement(header, 'field')
-            field.text = tools.ustr(fields[f]['string'] or '')
-
-        lines = etree.SubElement(new_doc, 'lines')
-        for line in results:
-            node_line = etree.SubElement(lines, 'row')
-            count = -1
-            for f in fields_order:
-                float_flag = 0
-                count += 1
-                if fields[f]['type']=='many2one' and line[f]:
-                    if not line.get('__group'):
-                        line[f] = line[f][1]
-                if fields[f]['type']=='selection' and line[f]:
-                    for key, value in fields[f]['selection']:
-                        if key == line[f]:
-                            line[f] = value
-                            break
-                if fields[f]['type'] in ('one2many','many2many') and line[f]:
-                    line[f] = '( '+tools.ustr(len(line[f])) + ' )'
-                if fields[f]['type'] == 'float' and line[f]:
-                    precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
-                    prec ='%.' + str(precision) +'f'
-                    line[f]=prec%(line[f])
-                    float_flag = 1
-
-                if fields[f]['type'] == 'date' and line[f]:
-                    new_d1 = line[f]
-                    if not line.get('__group'):
-                        format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))
-                        d1 = datetime.strptime(line[f],'%Y-%m-%d')
-                        new_d1 = d1.strftime(format)
-                    line[f] = new_d1
-
-                if fields[f]['type'] == 'time' and line[f]:
-                    new_d1 = line[f]
-                    if not line.get('__group'):
-                        format = str(locale.nl_langinfo(locale.T_FMT))
-                        d1 = datetime.strptime(line[f], '%H:%M:%S')
-                        new_d1 = d1.strftime(format)
-                    line[f] = new_d1
-
-                if fields[f]['type'] == 'datetime' and line[f]:
-                    new_d1 = line[f]
-                    if not line.get('__group'):
-                        format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))+' '+str(locale.nl_langinfo(locale.T_FMT))
-                        d1 = datetime.strptime(line[f], '%Y-%m-%d %H:%M:%S')
-                        new_d1 = d1.strftime(format)
-                    line[f] = new_d1
-
-
-                if line.get('__group'):
-                    col = etree.SubElement(node_line, 'col', para='group', tree='no')
-                else:
-                    col = etree.SubElement(node_line, 'col', para='yes', tree='no')
-
-                # Prevent empty labels in groups
-                if f == line.get('__grouped_by') and line.get('__group') and not line[f] and not float_flag and not temp[count]:
-                    col.text = line[f] = 'Undefined'
-                    col.set('tree', 'undefined')
-
-                if line[f] is not None:
-                    col.text = tools.ustr(line[f] or '')
-                    if float_flag:
-                        col.set('tree','float')
-                    if line.get('__no_leaf') and temp[count] == 1 and f != 'id' and not line['__context']['group_by']:
-                        tsum[count] = float(tsum[count]) + float(line[f])
-                    if not line.get('__group') and f != 'id' and temp[count] == 1:
-                        tsum[count] = float(tsum[count])  + float(line[f])
-                else:
-                    col.text = '/'
-
-        node_line = etree.SubElement(lines, 'row')
-        for f in range(0, len(fields_order)):
-            col = etree.SubElement(node_line, 'col', para='group', tree='no')
-            col.set('tree', 'float')
-            if tsum[f] is not None:
-                if tsum[f] != 0.0:
-                    digits = fields[fields_order[f]].get('digits', (16, 2))
-                    prec = '%%.%sf' % (digits[1], )
-                    total = prec % (tsum[f], )
-                    txt = str(total or '')
-                else:
-                    txt = str(tsum[f] or '')
-            else:
-                txt = '/'
-            if f == 0:
-                txt ='Total'
-                col.set('tree','no')
-            col.text = tools.ustr(txt or '')
-
-        transform = etree.XSLT(
-            etree.parse(os.path.join(tools.config['root_path'],
-                                     'addons/base/report/custom_new.xsl')))
-        rml = etree.tostring(transform(new_doc))
-        self.obj = render.rml(rml, title=self.title)
-        self.obj.render()
-        return True
-
-report_printscreen_list('report.printscreen.list')
diff --git a/odoo/report/render/__init__.py b/odoo/report/render/__init__.py
deleted file mode 100644
index 228de009bd1b54756f3e3c9696ae192179a7b695..0000000000000000000000000000000000000000
--- a/odoo/report/render/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .simple import simple
-from .rml import rml, rml2html, rml2txt, odt2odt , html2html, makohtml2html
-from .render import render
-
-try:
-    from PIL import Image
-except ImportError:
-    import logging
-    _logger = logging.getLogger(__name__)
-    _logger.warning('Python Imaging not installed, you can use only .JPG pictures !')
diff --git a/odoo/report/render/html2html/__init__.py b/odoo/report/render/html2html/__init__.py
deleted file mode 100644
index 41fa95cf4a0d8e897b2c3a864f9d0dc08fd04a1a..0000000000000000000000000000000000000000
--- a/odoo/report/render/html2html/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .html2html import parseString
diff --git a/odoo/report/render/html2html/html2html.py b/odoo/report/render/html2html/html2html.py
deleted file mode 100644
index bb6ea8bae0d9ff57b0c1ace009713257565cfb39..0000000000000000000000000000000000000000
--- a/odoo/report/render/html2html/html2html.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import base64
-import copy
-import cStringIO
-import re
-
-from reportlab.lib.utils import ImageReader
-
-from odoo.report.render.rml2pdf import utils
-
-_regex = re.compile('\[\[(.+?)\]\]')
-utils._regex = re.compile('\[\[\s*(.+?)\s*\]\]',re.DOTALL)
-class html2html(object):
-    def __init__(self, html, localcontext):
-        self.localcontext = localcontext
-        self.etree = html
-        self._node = None
-
-
-    def render(self):
-        def process_text(node,new_node):
-            if new_node.tag in ['story','tr','section']:
-                new_node.attrib.clear()
-            for child in utils._child_get(node, self):
-                new_child = copy.deepcopy(child)
-                new_node.append(new_child)
-                if len(child):
-                    for n in new_child:
-                        new_child.text  = utils._process_text(self, child.text)
-                        new_child.tail  = utils._process_text(self, child.tail)
-                        new_child.remove(n)
-                    process_text(child, new_child)
-                else:
-                    if new_child.tag=='img' and new_child.get('name'):
-                        if _regex.findall(new_child.get('name')) :
-                            src =  utils._process_text(self, new_child.get('name'))
-                            if src :
-                                new_child.set('src','data:image/gif;base64,%s'%src)
-                                output = cStringIO.StringIO(base64.decodestring(src))
-                                img = ImageReader(output)
-                                (width,height) = img.getSize()
-                                if not new_child.get('width'):
-                                    new_child.set('width',str(width))
-                                if not new_child.get('height') :
-                                    new_child.set('height',str(height))
-                            else :
-                                new_child.getparent().remove(new_child)
-                    new_child.text  = utils._process_text(self, child.text)
-                    new_child.tail  = utils._process_text(self, child.tail)
-        self._node = copy.deepcopy(self.etree)
-        for n in self._node:
-            self._node.remove(n)
-        process_text(self.etree, self._node)
-        return self._node
-        
-    def url_modify(self,root):
-        for n in root:
-            if (n.text.find('<a ')>=0 or n.text.find('&lt;a')>=0) and n.text.find('href')>=0 and n.text.find('style')<=0 :
-                node = (n.tag=='span' and n.getparent().tag=='u') and n.getparent().getparent() or ((n.tag=='span') and n.getparent()) or n
-                style = node.get('color') and "style='color:%s; text-decoration: none;'"%node.get('color') or ''
-                if n.text.find('&lt;a')>=0:
-                    t = '&lt;a '
-                else :
-                    t = '<a '
-                href = n.text.split(t)[-1]
-                n.text = ' '.join([t,style,href])
-            self.url_modify(n)
-        return root
-
-def parseString(node, localcontext = {}):
-    r = html2html(node, localcontext)
-    root = r.render()
-    root = r.url_modify(root)
-    return root
diff --git a/odoo/report/render/makohtml2html/__init__.py b/odoo/report/render/makohtml2html/__init__.py
deleted file mode 100644
index ad0404301ae8a560556512d4389426d737166165..0000000000000000000000000000000000000000
--- a/odoo/report/render/makohtml2html/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .makohtml2html import parseNode
diff --git a/odoo/report/render/makohtml2html/makohtml2html.py b/odoo/report/render/makohtml2html/makohtml2html.py
deleted file mode 100644
index f044d1d8f36fe3745950ebf5304364f3611cedf6..0000000000000000000000000000000000000000
--- a/odoo/report/render/makohtml2html/makohtml2html.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import logging
-import os
-
-import mako
-from mako.lookup import TemplateLookup
-from mako.template import Template
-from lxml import etree
-
-_logger = logging.getLogger(__name__)
-
-class makohtml2html(object):
-    def __init__(self, html, localcontext):
-        self.localcontext = localcontext
-        self.html = html
-
-    def format_header(self, html):
-        head = html.findall('head')
-        header = ''
-        for node in head:
-            header += etree.tostring(node)
-        return header
-
-    def format_footer(self, footer):
-        html_footer = ''
-        for node in footer[0].getchildren():
-            html_footer += etree.tostring(node)
-        return html_footer
-
-    def format_body(self, html):
-        body = html.findall('body')
-        body_list = []
-        footer =  self.format_footer(body[-1].getchildren())
-        for b in body[:-1]:
-            body_list.append(etree.tostring(b).replace('\t', '').replace('\n',''))
-        html_body ='''
-        <script type="text/javascript">
-
-        var indexer = 0;
-        var aryTest = %s ;
-        function nextData()
-            {
-            if(indexer < aryTest.length -1)
-                {
-                indexer += 1;
-                document.forms[0].prev.disabled = false;
-                document.getElementById("openerp_data").innerHTML=aryTest[indexer];
-                document.getElementById("counter").innerHTML= indexer + 1 + ' / ' + aryTest.length;
-                }
-            else
-               {
-                document.forms[0].next.disabled = true;
-               }
-            }
-        function prevData()
-            {
-            if (indexer > 0)
-                {
-                indexer -= 1;
-                document.forms[0].next.disabled = false;
-                document.getElementById("openerp_data").innerHTML=aryTest[indexer];
-                document.getElementById("counter").innerHTML=  indexer + 1 + ' / ' + aryTest.length;
-                }
-            else
-               {
-                document.forms[0].prev.disabled = true;
-               }
-            }
-    </script>
-    </head>
-    <body>
-        <div id="openerp_data">
-            %s
-        </div>
-        <div>
-        %s
-        </div>
-        <br>
-        <form>
-            <table>
-                <tr>
-                    <td td align="left">
-                        <input name = "prev" type="button" value="Previous" onclick="prevData();">
-                    </td>
-                    <td>
-                        <div id = "counter">%s / %s</div>
-                    </td>
-                    <td align="right">
-                        <input name = "next" type="button" value="Next" onclick="nextData();">
-                    </td>
-                </tr>
-            </table>
-        </form>
-    </body></html>'''%(body_list,body_list[0],footer,'1',len(body_list))
-        return html_body
-
-    def render(self):
-        path = os.path.realpath('addons/base/report')
-        temp_lookup = TemplateLookup(directories=[path],output_encoding='utf-8', encoding_errors='replace')
-        template = Template(self.html, lookup=temp_lookup)
-        self.localcontext.update({'css_path':path})
-        final_html ='''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-                    <html>'''
-        try:
-            html = template.render_unicode(**self.localcontext)
-            etree_obj = etree.HTML(html)
-            final_html += self.format_header(etree_obj)
-            final_html += self.format_body(etree_obj)
-            return final_html
-        except Exception:
-            _logger.exception('report :')
-
-def parseNode(html, localcontext = {}):
-    r = makohtml2html(html, localcontext)
-    return r.render()
diff --git a/odoo/report/render/odt2odt/__init__.py b/odoo/report/render/odt2odt/__init__.py
deleted file mode 100644
index b1d94607dab96ca3a3e8a01e57c03c015bf9b27f..0000000000000000000000000000000000000000
--- a/odoo/report/render/odt2odt/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .odt2odt import parseNode
diff --git a/odoo/report/render/odt2odt/odt2odt.py b/odoo/report/render/odt2odt/odt2odt.py
deleted file mode 100644
index 8eea37b8fb489465dc73ec71bb51e71795a7598b..0000000000000000000000000000000000000000
--- a/odoo/report/render/odt2odt/odt2odt.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import copy
-
-from odoo.report.render.rml2pdf import utils
-
-class odt2odt(object):
-    def __init__(self, odt, localcontext):
-        self.localcontext = localcontext
-        self.etree = odt
-        self._node = None
-
-    def render(self):
-        def process_text(node,new_node):
-            for child in utils._child_get(node, self):
-                new_child = copy.deepcopy(child)
-                new_node.append(new_child)
-                if len(child):
-                    for n in new_child:
-                        new_child.text  = utils._process_text(self, child.text)
-                        new_child.tail  = utils._process_text(self, child.tail)
-                        new_child.remove(n)
-                    process_text(child, new_child)
-                else:
-                    new_child.text  = utils._process_text(self, child.text)
-                    new_child.tail  = utils._process_text(self, child.tail)
-        self._node = copy.deepcopy(self.etree)
-        for n in self._node:
-            self._node.remove(n)
-        process_text(self.etree, self._node)
-        return self._node
-
-def parseNode(node, localcontext = {}):
-    r = odt2odt(node, localcontext)
-    return r.render()
diff --git a/odoo/report/render/render.py b/odoo/report/render/render.py
deleted file mode 100644
index 988c1bbd52cad10654dab76e94d308a3c1b23481..0000000000000000000000000000000000000000
--- a/odoo/report/render/render.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-# Why doing some multi-thread instead of using OSE capabilities ?
-# For progress bar.
-
-#
-# Add a transparant multi-thread layer to all report rendering layers
-#
-
-# TODO: method to stock on the disk
-class render(object):
-    """ Represents a report job being rendered.
-    
-    @param bin_datas a dictionary of name:<binary content> of images etc.
-    @param path the path in which binary files can be discovered, useful
-            for components (images) of the report. It can be:
-               - a string, relative or absolute path to images
-               - a list, containing strings of paths.
-            If a string is absolute path, it will be opened as such, else
-            it will be passed to tools.file_open() which also considers zip
-            addons.
-
-    Reporting classes must subclass this class and redefine the __init__ and
-    _render methods (not the other methods).
-
-    """
-    def __init__(self, bin_datas=None, path='.'):
-        self.done = False
-        if bin_datas is None:
-            self.bin_datas = {}
-        else:
-            self.bin_datas = bin_datas
-        self.path = path
-    
-    def _render(self):
-        return None
-
-    def render(self):
-        self.done = False
-        self._result = self._render()
-        self.done = True
-        return True
-    
-    def is_done(self):
-        return self.done
-
-    def get(self):
-        if self.is_done():
-            return self._result
-        else:
-            return None
diff --git a/odoo/report/render/rml.py b/odoo/report/render/rml.py
deleted file mode 100644
index d87a3a54ae2dfb0afbf462e65715d2434da0d97c..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from . import render
-from . import rml2pdf
-from . import rml2html as htmlizer
-from . import rml2txt as txtizer
-from . import odt2odt as odt
-from . import html2html as html
-from . import makohtml2html as makohtml
-
-
-class rml(render.render):
-    def __init__(self, rml, localcontext = None, datas=None, path='.', title=None):
-        render.render.__init__(self, datas, path)
-        self.localcontext = localcontext
-        self.rml = rml
-        self.output_type = 'pdf'
-        self.title=title
-
-    def _render(self):
-        return rml2pdf.parseNode(self.rml, self.localcontext, images=self.bin_datas, path=self.path,title=self.title)
-
-
-class rml2html(render.render):
-    def __init__(self, rml,localcontext = None, datas=None):
-        super(rml2html, self).__init__(datas)
-        self.rml = rml
-        self.localcontext = localcontext
-        self.output_type = 'html'
-
-    def _render(self):
-        return htmlizer.parseString(self.rml,self.localcontext)
-
-
-class rml2txt(render.render):
-    def __init__(self, rml, localcontext= None, datas=None):
-        super(rml2txt, self).__init__(datas)
-        self.rml = rml
-        self.localcontext = localcontext
-        self.output_type = 'txt'
-
-    def _render(self):
-        return txtizer.parseString(self.rml, self.localcontext)
-
-
-class odt2odt(render.render):
-    def __init__(self, rml, localcontext=None, datas=None):
-        render.render.__init__(self, datas)
-        self.rml_dom = rml
-        self.localcontext = localcontext
-        self.output_type = 'odt'
-
-    def _render(self):
-        return odt.parseNode(self.rml_dom,self.localcontext)
-
-
-class html2html(render.render):
-    def __init__(self, rml, localcontext=None, datas=None):
-        render.render.__init__(self, datas)
-        self.rml_dom = rml
-        self.localcontext = localcontext
-        self.output_type = 'html'
-
-    def _render(self):
-        return html.parseString(self.rml_dom,self.localcontext)
-
-
-class makohtml2html(render.render):
-    def __init__(self, html, localcontext = None):
-        render.render.__init__(self)
-        self.html = html
-        self.localcontext = localcontext
-        self.output_type = 'html'
-
-    def _render(self):
-        return makohtml.parseNode(self.html,self.localcontext)
diff --git a/odoo/report/render/rml2html/__init__.py b/odoo/report/render/rml2html/__init__.py
deleted file mode 100644
index 5f27854c99f0708422329e0bc5f16c001e4d74d8..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2html/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .rml2html import parseString
diff --git a/odoo/report/render/rml2html/rml2html.py b/odoo/report/render/rml2html/rml2html.py
deleted file mode 100644
index bdf04f7d6c5f9fdcc60b48b0a2cb45b3356cce94..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2html/rml2html.py
+++ /dev/null
@@ -1,423 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import copy
-import cStringIO
-import sys
-
-from lxml import etree
-
-from odoo.report.render.rml2pdf import utils
-
-class _flowable(object):
-    def __init__(self, template, doc, localcontext = None):
-        self._tags = {
-            'title': self._tag_title,
-            'spacer': self._tag_spacer,
-            'para': self._tag_para,
-            'section':self._section,
-            'nextFrame': self._tag_next_frame,
-            'blockTable': self._tag_table,
-            'pageBreak': self._tag_page_break,
-            'setNextTemplate': self._tag_next_template,
-        }
-        self.template = template
-        self.doc = doc
-        self.localcontext = localcontext
-        self._cache = {}
-
-    def _tag_page_break(self, node):
-        return '<br/>'*3
-
-    def _tag_next_template(self, node):
-        return ''
-
-    def _tag_next_frame(self, node):
-        result=self.template.frame_stop()
-        result+='<br/>'
-        result+=self.template.frame_start()
-        return result
-
-    def _tag_title(self, node):
-        node.tag='h1'
-        return etree.tostring(node)
-
-    def _tag_spacer(self, node):
-        length = 1+int(utils.unit_get(node.get('length')))/35
-        return "<br/>"*length
-
-    def _tag_table(self, node):
-        new_node = copy.deepcopy(node)
-        for child in new_node:
-            new_node.remove(child)
-        new_node.tag = 'table'
-        def process(node,new_node):
-            for child in utils._child_get(node,self):
-                new_child = copy.deepcopy(child)
-                new_node.append(new_child)
-                if len(child):
-                    for n in new_child:
-                        new_child.remove(n)
-                    process(child, new_child)
-                else:
-                    new_child.text  = utils._process_text(self, child.text)
-                    new_child.tag = 'p'
-                    try:
-                        if new_child.get('style').find('terp_tblheader')!= -1:
-                            new_node.tag = 'th'
-                    except Exception:
-                        pass
-        process(node,new_node)
-        if new_node.get('colWidths',False):
-            sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(','))
-            tr = etree.SubElement(new_node, 'tr')
-            for s in sizes:
-                etree.SubElement(tr, 'td', width=str(s))
-
-        return etree.tostring(new_node)
-
-    def _tag_para(self, node):
-        new_node = copy.deepcopy(node)
-        new_node.tag = 'p'
-        if new_node.attrib.get('style',False):
-            new_node.set('class', new_node.get('style'))
-        new_node.text = utils._process_text(self, node.text)
-        return etree.tostring(new_node)
-
-    def _section(self, node):
-        result = ''
-        for child in utils._child_get(node, self):
-            if child.tag in self._tags:
-                result += self._tags[child.tag](child)
-        return result
-
-    def render(self, node):
-        result = self.template.start()
-        result += self.template.frame_start()
-        for n in utils._child_get(node, self):
-            if n.tag in self._tags:
-                result += self._tags[n.tag](n)
-            else:
-                pass
-        result += self.template.frame_stop()
-        result += self.template.end()
-        return result.encode('utf-8').replace('"',"\'").replace('°','&deg;')
-
-class _rml_tmpl_tag(object):
-    def __init__(self, *args):
-        pass
-    def tag_start(self):
-        return ''
-    def tag_end(self):
-        return False
-    def tag_stop(self):
-        return ''
-    def tag_mergeable(self):
-        return True
-
-class _rml_tmpl_frame(_rml_tmpl_tag):
-    def __init__(self, posx, width):
-        self.width = width
-        self.posx = posx
-    def tag_start(self):
-        return "<table border=\'0\' width=\'%d\'><tr><td width=\'%d\'>&nbsp;</td><td>" % (self.width+self.posx,self.posx)
-    def tag_end(self):
-        return True
-    def tag_stop(self):
-        return '</td></tr></table><br/>'
-    def tag_mergeable(self):
-        return False
-
-    def merge(self, frame):
-        pass
-
-class _rml_tmpl_draw_string(_rml_tmpl_tag):
-    def __init__(self, node, style,localcontext = {}):
-        self.localcontext = localcontext
-        self.posx = utils.unit_get(node.get('x'))
-        self.posy =  utils.unit_get(node.get('y'))
-
-        aligns = {
-            'drawString': 'left',
-            'drawRightString': 'right',
-            'drawCentredString': 'center'
-        }
-        align = aligns[node.tag]
-        self.pos = [(self.posx, self.posy, align, utils._process_text(self, node.text), style.get('td'), style.font_size_get('td'))]
-
-    def tag_start(self):
-        self.pos.sort()
-        res = "<table border='0' cellpadding='0' cellspacing='0'><tr>"
-        posx = 0
-        i = 0
-        for (x,y,align,txt, style, fs) in self.pos:
-            if align=="left":
-                pos2 = len(txt)*fs
-                res+="<td width=\'%d\'></td><td style=\'%s\' width=\'%d\'>%s</td>" % (x - posx, style, pos2, txt)
-                posx = x+pos2
-            if align=="right":
-                res+="<td width=\'%d\' align=\'right\' style=\'%s\'>%s</td>" % (x - posx, style, txt)
-                posx = x
-            if align=="center":
-                res+="<td width=\'%d\' align=\'center\' style=\'%s\'>%s</td>" % ((x - posx)*2, style, txt)
-                posx = 2*x-posx
-            i+=1
-        res+='</tr></table>'
-        return res
-    def merge(self, ds):
-        self.pos+=ds.pos
-
-class _rml_tmpl_draw_lines(_rml_tmpl_tag):
-    def __init__(self, node, style, localcontext = {}):
-        self.localcontext = localcontext
-        coord = [utils.unit_get(x) for x in utils._process_text(self, node.text).split(' ')]
-        self.ok = False
-        self.posx = coord[0]
-        self.posy = coord[1]
-        self.width = coord[2]-coord[0]
-        self.ok = coord[1]==coord[3]
-        self.style = style
-        self.style = style.get('hr')
-
-    def tag_start(self):
-        if self.ok:
-            return "<table border=\'0\' cellpadding=\'0\' cellspacing=\'0\' width=\'%d\'><tr><td width=\'%d\'></td><td><hr width=\'100%%\' style=\'margin:0px; %s\'></td></tr></table>" % (self.posx+self.width,self.posx,self.style)
-        else:
-            return ''
-
-class _rml_stylesheet(object):
-    def __init__(self, localcontext, stylesheet, doc):
-        self.doc = doc
-        self.localcontext = localcontext
-        self.attrs = {}
-        self._tags = {
-            'fontSize': lambda x: ('font-size',str(utils.unit_get(x)+5.0)+'px'),
-            'alignment': lambda x: ('text-align',str(x))
-        }
-        result = ''
-        for ps in stylesheet.findall('paraStyle'):
-            attr = {}
-            attrs = ps.attrib
-            for key, val in attrs.items():
-                attr[key] = val
-            attrs = []
-            for a in attr:
-                if a in self._tags:
-                    attrs.append('%s:%s' % self._tags[a](attr[a]))
-            if len(attrs):
-                result += 'p.'+attr['name']+' {'+'; '.join(attrs)+'}\n'
-        self.result = result
-
-    def render(self):
-        return self.result
-
-class _rml_draw_style(object):
-    def __init__(self):
-        self.style = {}
-        self._styles = {
-            'fill': lambda x: {'td': {'color':x.get('color')}},
-            'setFont': lambda x: {'td': {'font-size':x.get('size')+'px'}},
-            'stroke': lambda x: {'hr': {'color':x.get('color')}},
-        }
-    def update(self, node):
-        if node.tag in self._styles:
-            result = self._styles[node.tag](node)
-            for key in result:
-                if key in self.style:
-                    self.style[key].update(result[key])
-                else:
-                    self.style[key] = result[key]
-    def font_size_get(self,tag):
-        size  = utils.unit_get(self.style.get('td', {}).get('font-size','16'))
-        return size
-
-    def get(self,tag):
-        if not tag in self.style:
-            return ""
-        return ';'.join(['%s:%s' % (x[0],x[1]) for x in self.style[tag].items()])
-
-class _rml_template(object):
-    def __init__(self, template, localcontext=None):
-        self.frame_pos = -1
-        self.localcontext = localcontext
-        self.frames = []
-        self.template_order = []
-        self.page_template = {}
-        self.loop = 0
-        self._tags = {
-            'drawString': _rml_tmpl_draw_string,
-            'drawRightString': _rml_tmpl_draw_string,
-            'drawCentredString': _rml_tmpl_draw_string,
-            'lines': _rml_tmpl_draw_lines
-        }
-        self.style = _rml_draw_style()
-        rc = 'data:image/png;base64,'
-        self.data = ''
-        for pt in template.findall('pageTemplate'):
-            frames = {}
-            id = pt.get('id')
-            self.template_order.append(id)
-            for tmpl in pt.findall('frame'):
-                posy = int(utils.unit_get(tmpl.get('y1')))
-                posx = int(utils.unit_get(tmpl.get('x1')))
-                frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width')))
-            for tmpl in pt.findall('pageGraphics'):
-                for n in tmpl:
-                    if n.tag == 'image':
-                        self.data = rc + utils._process_text(self, n.text)
-                    if n.tag in self._tags:
-                        t = self._tags[n.tag](n, self.style,self.localcontext)
-                        frames[(t.posy,t.posx,n.tag)] = t
-                    else:
-                        self.style.update(n)
-            keys = frames.keys()
-            keys.sort()
-            keys.reverse()
-            self.page_template[id] = []
-            for key in range(len(keys)):
-                if key>0 and keys[key-1][0] == keys[key][0]:
-                    if type(self.page_template[id][-1]) == type(frames[keys[key]]):
-                        if self.page_template[id][-1].tag_mergeable():
-                            self.page_template[id][-1].merge(frames[keys[key]])
-                        continue
-                self.page_template[id].append(frames[keys[key]])
-        self.template = self.template_order[0]
-
-    def _get_style(self):
-        return self.style
-
-    def set_next_template(self):
-        self.template = self.template_order[(self.template_order.index(name)+1) % self.template_order]
-        self.frame_pos = -1
-
-    def set_template(self, name):
-        self.template = name
-        self.frame_pos = -1
-
-    def frame_start(self):
-        result = ''
-        frames = self.page_template[self.template]
-        ok = True
-        while ok:
-            self.frame_pos += 1
-            if self.frame_pos>=len(frames):
-                self.frame_pos=0
-                self.loop=1
-                ok = False
-                continue
-            f = frames[self.frame_pos]
-            result+=f.tag_start()
-            ok = not f.tag_end()
-            if ok:
-                result+=f.tag_stop()
-        return result
-
-    def frame_stop(self):
-        frames = self.page_template[self.template]
-        f = frames[self.frame_pos]
-        result=f.tag_stop()
-        return result
-
-    def start(self):
-        return ''
-
-    def end(self):
-        result = ''
-        while not self.loop:
-            result += self.frame_start()
-            result += self.frame_stop()
-        return result
-
-class _rml_doc(object):
-    def __init__(self, data, localcontext):
-        self.dom = etree.XML(data)
-        self.localcontext = localcontext
-        self.filename = self.dom.get('filename')
-        self.result = ''
-
-    def render(self, out):
-        self.result += '''<!DOCTYPE HTML PUBLIC "-//w3c//DTD HTML 4.0 Frameset//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <style type="text/css">
-        p {margin:0px; font-size:12px;}
-        td {font-size:14px;}
-'''
-        style = self.dom.findall('stylesheet')[0]
-        s = _rml_stylesheet(self.localcontext, style, self.dom)
-        self.result += s.render()
-        self.result+='''
-    </style>
-'''
-        list_story =[]
-        for story in utils._child_get(self.dom, self, 'story'):
-            template = _rml_template(self.dom.findall('template')[0], self.localcontext)
-            f = _flowable(template, self.dom, localcontext = self.localcontext)
-            story_text = f.render(story)
-            list_story.append(story_text)
-        del f
-        if template.data:
-            tag = '''<img src = '%s' width=80 height=72/>'''% template.data
-        else:
-            tag = ''
-        self.result +='''
-            <script type="text/javascript">
-
-            var indexer = 0;
-            var aryTest = %s ;
-            function nextData()
-                {
-                if(indexer < aryTest.length -1)
-                    {
-                    indexer += 1;
-                    document.getElementById("tiny_data").innerHTML=aryTest[indexer];
-                    }
-                }
-            function prevData()
-                {
-                if (indexer > 0)
-                    {
-                    indexer -= 1;
-                    document.getElementById("tiny_data").innerHTML=aryTest[indexer];
-                    }
-                }
-        </script>
-        </head>
-        <body>
-            %s
-            <div id="tiny_data">
-                %s
-            </div>
-            <br>
-            <input type="button" value="next" onclick="nextData();">
-            <input type="button" value="prev" onclick="prevData();">
-
-        </body></html>'''%(list_story,tag,list_story[0])
-        out.write( self.result)
-
-def parseString(data,localcontext = {}, fout=None):
-    r = _rml_doc(data, localcontext)
-    if fout:
-        fp = file(fout,'wb')
-        r.render(fp)
-        fp.close()
-        return fout
-    else:
-        fp = cStringIO.StringIO()
-        r.render(fp)
-        return fp.getvalue()
-
-def rml2html_help():
-    print 'Usage: rml2html input.rml >output.html'
-    print 'Render the standard input (RML) and output an HTML file'
-    sys.exit(0)
-
-if __name__=="__main__":
-    if len(sys.argv)>1:
-        if sys.argv[1]=='--help':
-            rml2html_help()
-        print parseString(file(sys.argv[1], 'r').read()),
-    else:
-        print 'Usage: rml2html input.rml >output.html'
-        print 'Try \'rml2html --help\' for more information.'
diff --git a/odoo/report/render/rml2html/utils.py b/odoo/report/render/rml2html/utils.py
deleted file mode 100644
index 5143665efbd1ce4bdfd16a44099bb690bcdcf1eb..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2html/utils.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import re
-import reportlab
-import reportlab.lib.units
-
-units = [
-    (re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
-    (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
-    (re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
-    (re.compile('^(-?[0-9\.]+)\s*px$'), 0.7),
-    (re.compile('^(-?[0-9\.]+)\s*$'), 1)
-]
-
-def unit_get(size):
-    global units
-    for unit in units:
-        res = unit[0].search(size, 0)
-        if res:
-            return int(unit[1]*float(res.group(1))*1.3)
-    return False
-
-def tuple_int_get(node, attr_name, default=None):
-    if not node.get(attr_name):
-        return default
-    res = [int(x) for x in node.get(attr_name).split(',')]
-    return res
-
-def bool_get(value):
-    return (str(value)=="1") or (value.lower()=='yes')
-
-def attr_get(node, attrs, dict=None):
-    if dict is None:
-        dict = {}
-    res = {}
-    for name in attrs:
-        if node.get(name):
-            res[name] =  unit_get(node.get(name))
-    for key in dict:
-        if node.get(key):
-            if dict[key]=='str':
-                res[key] = str(node.get(key))
-            elif dict[key]=='bool':
-                res[key] = bool_get(node.get(key))
-            elif dict[key]=='int':
-                res[key] = int(node.get(key))
-    return res
diff --git a/odoo/report/render/rml2pdf/__init__.py b/odoo/report/render/rml2pdf/__init__.py
deleted file mode 100644
index 166e0f2d9a282fc8180174b5512ff93e6e038666..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2pdf/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .trml2pdf import parseString, parseNode
diff --git a/odoo/report/render/rml2pdf/color.py b/odoo/report/render/rml2pdf/color.py
deleted file mode 100644
index 60767cdf8abf96fb1193264907106bccee93ebb7..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2pdf/color.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import re
-
-from reportlab.lib import colors
-
-allcols = colors.getAllNamedColors()
-
-regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)')
-regex_h = re.compile('#([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])')
-
-def get(col_str):
-    if col_str is None:
-        col_str = ''
-    global allcols
-    if col_str in allcols.keys():
-        return allcols[col_str]
-    res = regex_t.search(col_str, 0)
-    if res:
-        return float(res.group(1)), float(res.group(2)), float(res.group(3))
-    res = regex_h.search(col_str, 0)
-    if res:
-        return tuple([ float(int(res.group(i),16))/255 for i in range(1,4)])
-    return colors.red
diff --git a/odoo/report/render/rml2pdf/customfonts.py b/odoo/report/render/rml2pdf/customfonts.py
deleted file mode 100644
index c34088ab0855fd957c93b8d371878bfaa515db16..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2pdf/customfonts.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import glob
-import logging
-import os
-
-from reportlab import rl_config
-
-# .apidoc title: TTF Font Table
-
-"""This module allows the mapping of some system-available TTF fonts to
-the reportlab engine.
-
-This file could be customized per distro (although most Linux/Unix ones)
-should have the same filenames, only need the code below).
-
-Due to an awful configuration that ships with reportlab at many Linux
-and Ubuntu distros, we have to override the search path, too.
-"""
-_logger = logging.getLogger(__name__)
-
-CustomTTFonts = []
-
-# Search path for TTF files, in addition of rl_config.TTFSearchPath
-TTFSearchPath = [
-            '/usr/share/fonts/truetype', # SuSE
-            '/usr/share/fonts/dejavu', '/usr/share/fonts/liberation', # Fedora, RHEL
-            '/usr/share/fonts/truetype/*','/usr/local/share/fonts' # Ubuntu,
-            '/usr/share/fonts/TTF/*', # Mandriva/Mageia
-            '/usr/share/fonts/TTF', # Arch Linux
-            '/usr/lib/openoffice/share/fonts/truetype/',
-            '~/.fonts',
-            '~/.local/share/fonts',
-
-            # mac os X - from
-            # http://developer.apple.com/technotes/tn/tn2024.html
-            '~/Library/Fonts',
-            '/Library/Fonts',
-            '/Network/Library/Fonts',
-            '/System/Library/Fonts',
-
-            # windows
-            'c:/winnt/fonts',
-            'c:/windows/fonts'
-]
-
-def list_all_sysfonts():
-    """
-        This function returns list of font directories of system.
-    """
-    filepath = []
-
-    # Perform the search for font files ourselves, as reportlab's
-    # TTFOpenFile is not very good at it.
-    searchpath = list(set(TTFSearchPath + rl_config.TTFSearchPath))
-    for dirname in searchpath:
-        for filename in glob.glob(os.path.join(os.path.expanduser(dirname), '*.[Tt][Tt][FfCc]')):
-            filepath.append(filename)
-    return filepath
-
-def SetCustomFonts(rmldoc):
-    """ Map some font names to the corresponding TTF fonts
-
-        The ttf font may not even have the same name, as in
-        Times -> Liberation Serif.
-        This function is called once per report, so it should
-        avoid system-wide processing (cache it, instead).
-    """
-    for family, font, filename, mode in CustomTTFonts:
-        if os.path.isabs(filename) and os.path.exists(filename):
-            rmldoc.setTTFontMapping(family, font, filename, mode)
-    return True
diff --git a/odoo/report/render/rml2pdf/trml2pdf.py b/odoo/report/render/rml2pdf/trml2pdf.py
deleted file mode 100644
index 47ab8d313a568043381845c6699efecd5f82b4ca..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2pdf/trml2pdf.py
+++ /dev/null
@@ -1,1067 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import base64
-import copy
-import logging
-import os
-import re
-import sys
-import traceback
-from distutils.version import LooseVersion
-
-try:
-    from cStringIO import StringIO
-    _hush_pyflakes = [ StringIO ]
-except ImportError:
-    from StringIO import StringIO
-
-import reportlab
-from reportlab import platypus
-from reportlab.lib.pagesizes import A4, letter
-from reportlab.pdfbase import pdfmetrics
-from reportlab.pdfgen import canvas
-from reportlab.platypus.doctemplate import ActionFlowable
-from lxml import etree
-
-from odoo.tools.misc import file_open
-from odoo.tools.safe_eval import safe_eval
-from . import color
-from . import utils
-
-try:
-    from .customfonts import SetCustomFonts
-except ImportError:
-    SetCustomFonts=lambda x:None
-
-_logger = logging.getLogger(__name__)
-
-encoding = 'utf-8'
-
-def select_fontname(fontname, default_fontname):
-    if fontname not in pdfmetrics.getRegisteredFontNames()\
-         or fontname not in pdfmetrics.standardFonts:
-        # let reportlab attempt to find it
-        try:
-            pdfmetrics.getFont(fontname)
-        except Exception:
-            addition = ""
-            if " " in fontname:
-                addition = ". Your font contains spaces which is not valid in RML."
-            _logger.warning('Could not locate font %s, substituting default: %s%s',
-                fontname, default_fontname, addition)
-            fontname = default_fontname
-    return fontname
-
-
-def _open_image(filename, path=None):
-    """Attempt to open a binary file and return the descriptor
-    """
-    if os.path.isfile(filename):
-        return open(filename, 'rb')
-    for p in (path or []):
-        if p and os.path.isabs(p):
-            fullpath = os.path.join(p, filename)
-            if os.path.isfile(fullpath):
-                return open(fullpath, 'rb')
-        try:
-            if p:
-                fullpath = os.path.join(p, filename)
-            else:
-                fullpath = filename
-            return file_open(fullpath)
-        except IOError:
-            pass
-    raise IOError("File %s cannot be found in image path" % filename)
-
-class NumberedCanvas(canvas.Canvas):
-    def __init__(self, *args, **kwargs):
-        canvas.Canvas.__init__(self, *args, **kwargs)
-        self._saved_page_states = []
-
-    def showPage(self):
-        self._startPage()
-
-    def save(self):
-        """add page info to each page (page x of y)"""
-        for state in self._saved_page_states:
-            self.__dict__.update(state)
-            self.draw_page_number()
-            canvas.Canvas.showPage(self)
-        canvas.Canvas.save(self)
-
-    def draw_page_number(self):
-        page_count = len(self._saved_page_states)
-        self.setFont("Helvetica", 8)
-        self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40),
-            " %(this)i / %(total)i" % {
-               'this': self._pageNumber,
-               'total': page_count,
-            }
-        )
-
-
-class PageCount(platypus.Flowable):
-    def __init__(self, story_count=0):
-        platypus.Flowable.__init__(self)
-        self.story_count = story_count
-
-    def draw(self):
-        self.canv.beginForm("pageCount%d" % self.story_count)
-        self.canv.setFont("Helvetica", utils.unit_get(str(8)))
-        self.canv.drawString(0, 0, str(self.canv.getPageNumber()))
-        self.canv.endForm()
-
-class PageReset(platypus.Flowable):
-    def draw(self):
-        """Flag to close current story page numbering and prepare for the next
-        should be executed after the rendering of the full story"""
-        self.canv._doPageReset = True
-
-class _rml_styles(object,):
-    def __init__(self, nodes, localcontext):
-        self.localcontext = localcontext
-        self.styles = {}
-        self.styles_obj = {}
-        self.names = {}
-        self.table_styles = {}
-        self.default_style = reportlab.lib.styles.getSampleStyleSheet()
-
-        for node in nodes:
-            for style in node.findall('blockTableStyle'):
-                self.table_styles[style.get('id')] = self._table_style_get(style)
-            for style in node.findall('paraStyle'):
-                sname = style.get('name')
-                self.styles[sname] = self._para_style_update(style)
-                if self.default_style.has_key(sname):
-                    for key, value in self.styles[sname].items():                    
-                        setattr(self.default_style[sname], key, value)
-                else:
-                    self.styles_obj[sname] = reportlab.lib.styles.ParagraphStyle(sname, self.default_style["Normal"], **self.styles[sname])
-            for variable in node.findall('initialize'):
-                for name in variable.findall('name'):
-                    self.names[ name.get('id')] = name.get('value')
-
-    def _para_style_update(self, node):
-        data = {}
-        for attr in ['textColor', 'backColor', 'bulletColor', 'borderColor']:
-            if node.get(attr):
-                data[attr] = color.get(node.get(attr))
-        for attr in ['bulletFontName', 'fontName']:
-            if node.get(attr):
-                fontname= select_fontname(node.get(attr), None)
-                if fontname is not None:
-                    data['fontName'] = fontname
-        for attr in ['bulletText']:
-            if node.get(attr):
-                data[attr] = node.get(attr)
-        for attr in ['fontSize', 'leftIndent', 'rightIndent', 'spaceBefore', 'spaceAfter',
-            'firstLineIndent', 'bulletIndent', 'bulletFontSize', 'leading',
-            'borderWidth','borderPadding','borderRadius']:
-            if node.get(attr):
-                data[attr] = utils.unit_get(node.get(attr))
-        if node.get('alignment'):
-            align = {
-                'right':reportlab.lib.enums.TA_RIGHT,
-                'center':reportlab.lib.enums.TA_CENTER,
-                'justify':reportlab.lib.enums.TA_JUSTIFY
-            }
-            data['alignment'] = align.get(node.get('alignment').lower(), reportlab.lib.enums.TA_LEFT)
-        data['splitLongWords'] = 0
-        return data
-
-    def _table_style_get(self, style_node):
-        styles = []
-        for node in style_node:
-            start = utils.tuple_int_get(node, 'start', (0,0) )
-            stop = utils.tuple_int_get(node, 'stop', (-1,-1) )
-            if node.tag=='blockValign':
-                styles.append(('VALIGN', start, stop, str(node.get('value'))))
-            elif node.tag=='blockFont':
-                styles.append(('FONT', start, stop, str(node.get('name'))))
-            elif node.tag=='blockTextColor':
-                styles.append(('TEXTCOLOR', start, stop, color.get(str(node.get('colorName')))))
-            elif node.tag=='blockLeading':
-                styles.append(('LEADING', start, stop, utils.unit_get(node.get('length'))))
-            elif node.tag=='blockAlignment':
-                styles.append(('ALIGNMENT', start, stop, str(node.get('value'))))
-            elif node.tag=='blockSpan':
-                styles.append(('SPAN', start, stop))
-            elif node.tag=='blockLeftPadding':
-                styles.append(('LEFTPADDING', start, stop, utils.unit_get(node.get('length'))))
-            elif node.tag=='blockRightPadding':
-                styles.append(('RIGHTPADDING', start, stop, utils.unit_get(node.get('length'))))
-            elif node.tag=='blockTopPadding':
-                styles.append(('TOPPADDING', start, stop, utils.unit_get(node.get('length'))))
-            elif node.tag=='blockBottomPadding':
-                styles.append(('BOTTOMPADDING', start, stop, utils.unit_get(node.get('length'))))
-            elif node.tag=='blockBackground':
-                styles.append(('BACKGROUND', start, stop, color.get(node.get('colorName'))))
-            if node.get('size'):
-                styles.append(('FONTSIZE', start, stop, utils.unit_get(node.get('size'))))
-            elif node.tag=='lineStyle':
-                kind = node.get('kind')
-                kind_list = [ 'GRID', 'BOX', 'OUTLINE', 'INNERGRID', 'LINEBELOW', 'LINEABOVE','LINEBEFORE', 'LINEAFTER' ]
-                assert kind in kind_list
-                thick = 1
-                if node.get('thickness'):
-                    thick = float(node.get('thickness'))
-                styles.append((kind, start, stop, thick, color.get(node.get('colorName'))))
-        return platypus.tables.TableStyle(styles)
-
-    def para_style_get(self, node):
-        style = False
-        sname = node.get('style')
-        if sname:
-            if sname in self.styles_obj:
-                style = self.styles_obj[sname]
-            else:
-                _logger.debug('Warning: style not found, %s - setting default!', node.get('style'))
-        if not style:
-            style = self.default_style['Normal']
-        para_update = self._para_style_update(node)
-        if para_update:
-            # update style only is necessary
-            style = copy.deepcopy(style)
-            style.__dict__.update(para_update)
-        return style
-
-class _rml_doc(object):
-    def __init__(self, node, localcontext=None, images=None, path='.', title=None):
-        if images is None:
-            images = {}
-        if localcontext is None:
-            localcontext = {}
-        self.localcontext = localcontext
-        self.etree = node
-        self.filename = self.etree.get('filename')
-        self.images = images
-        self.path = path
-        self.title = title
-
-    def docinit(self, els):
-        from reportlab.lib.fonts import addMapping
-        from reportlab.pdfbase import pdfmetrics
-        from reportlab.pdfbase.ttfonts import TTFont
-
-        for node in els:
-
-            for font in node.findall('registerFont'):
-                name = font.get('fontName').encode('ascii')
-                fname = font.get('fontFile').encode('ascii')
-                if name not in pdfmetrics._fonts:
-                    pdfmetrics.registerFont(TTFont(name, fname))
-                #by default, we map the fontName to each style (bold, italic, bold and italic), so that 
-                #if there isn't any font defined for one of these style (via a font family), the system
-                #will fallback on the normal font.
-                addMapping(name, 0, 0, name)    #normal
-                addMapping(name, 0, 1, name)    #italic
-                addMapping(name, 1, 0, name)    #bold
-                addMapping(name, 1, 1, name)    #italic and bold
-
-            #if registerFontFamily is defined, we register the mapping of the fontName to use for each style.
-            for font_family in node.findall('registerFontFamily'):
-                family_name = font_family.get('normal').encode('ascii')
-                if font_family.get('italic'):
-                    addMapping(family_name, 0, 1, font_family.get('italic').encode('ascii'))
-                if font_family.get('bold'):
-                    addMapping(family_name, 1, 0, font_family.get('bold').encode('ascii'))
-                if font_family.get('boldItalic'):
-                    addMapping(family_name, 1, 1, font_family.get('boldItalic').encode('ascii'))
-
-    def setTTFontMapping(self,face, fontname, filename, mode='all'):
-        from reportlab.lib.fonts import addMapping
-        from reportlab.pdfbase.ttfonts import TTFont
-
-        if mode:
-            mode = mode.lower()
-
-        if fontname not in pdfmetrics._fonts:
-            pdfmetrics.registerFont(TTFont(fontname, filename))
-        if mode == 'all':
-            addMapping(face, 0, 0, fontname)    #normal
-            addMapping(face, 0, 1, fontname)    #italic
-            addMapping(face, 1, 0, fontname)    #bold
-            addMapping(face, 1, 1, fontname)    #italic and bold
-        elif mode in ['italic', 'oblique']:
-            addMapping(face, 0, 1, fontname)    #italic
-        elif mode == 'bold':
-            addMapping(face, 1, 0, fontname)    #bold
-        elif mode in ('bolditalic', 'bold italic','boldoblique', 'bold oblique'):
-            addMapping(face, 1, 1, fontname)    #italic and bold
-        else:
-            addMapping(face, 0, 0, fontname)    #normal
-
-    def _textual_image(self, node):
-        rc = ''
-        for n in node:
-            rc +=( etree.tostring(n) or '') + n.tail
-        return base64.decodestring(node.tostring())
-
-    def _images(self, el):
-        result = {}
-        for node in el.findall('.//image'):
-            rc =( node.text or '')
-            result[node.get('name')] = base64.decodestring(rc)
-        return result
-
-    def render(self, out):
-        el = self.etree.findall('.//docinit')
-        if el:
-            self.docinit(el)
-
-        el = self.etree.findall('.//stylesheet')
-        self.styles = _rml_styles(el,self.localcontext)
-
-        el = self.etree.findall('.//images')
-        if el:
-            self.images.update( self._images(el[0]) )
-
-        el = self.etree.findall('.//template')
-        if len(el):
-            pt_obj = _rml_template(self.localcontext, out, el[0], self, images=self.images, path=self.path, title=self.title)
-            el = utils._child_get(self.etree, self, 'story')
-            pt_obj.render(el)
-        else:
-            self.canvas = canvas.Canvas(out)
-            pd = self.etree.find('pageDrawing')[0]
-            pd_obj = _rml_canvas(self.canvas, self.localcontext, None, self, self.images, path=self.path, title=self.title)
-            pd_obj.render(pd)
-
-            self.canvas.showPage()
-            self.canvas.save()
-
-class _rml_canvas(object):
-    def __init__(self, canvas, localcontext, doc_tmpl=None, doc=None, images=None, path='.', title=None):
-        if images is None:
-            images = {}
-        self.localcontext = localcontext
-        self.canvas = canvas
-        self.styles = doc.styles
-        self.doc_tmpl = doc_tmpl
-        self.doc = doc
-        self.images = images
-        self.path = path
-        self.title = title
-        if self.title:
-            self.canvas.setTitle(self.title)
-
-    def _textual(self, node, x=0, y=0):
-        text = node.text and node.text.encode('utf-8') or ''
-        rc = utils._process_text(self, text)
-        for n in node:
-            if n.tag == 'seq':
-                from reportlab.lib.sequencer import getSequencer
-                seq = getSequencer()
-                rc += str(seq.next(n.get('id')))
-            if n.tag == 'pageCount':
-                if x or y:
-                    self.canvas.translate(x,y)
-                self.canvas.doForm('pageCount%s' % (self.canvas._storyCount,))
-                if x or y:
-                    self.canvas.translate(-x,-y)
-            if n.tag == 'pageNumber':
-                rc += str(self.canvas.getPageNumber())
-            rc += utils._process_text(self, n.tail)
-        return rc.replace('\n','')
-
-    def _drawString(self, node):
-        v = utils.attr_get(node, ['x','y'])
-        text=self._textual(node, **v)
-        text = utils.xml2str(text)
-        try:
-            self.canvas.drawString(text=text, **v)
-        except TypeError:
-            _logger.info("Bad RML: <drawString> tag requires attributes 'x' and 'y'!")
-            raise
-
-    def _drawCenteredString(self, node):
-        v = utils.attr_get(node, ['x','y'])
-        text=self._textual(node, **v)
-        text = utils.xml2str(text)
-        self.canvas.drawCentredString(text=text, **v)
-
-    def _drawRightString(self, node):
-        v = utils.attr_get(node, ['x','y'])
-        text=self._textual(node, **v)
-        text = utils.xml2str(text)
-        self.canvas.drawRightString(text=text, **v)
-
-    def _rect(self, node):
-        if node.get('round'):
-            self.canvas.roundRect(radius=utils.unit_get(node.get('round')), **utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'}))
-        else:
-            self.canvas.rect(**utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'}))
-
-    def _ellipse(self, node):
-        x1 = utils.unit_get(node.get('x'))
-        x2 = utils.unit_get(node.get('width'))
-        y1 = utils.unit_get(node.get('y'))
-        y2 = utils.unit_get(node.get('height'))
-
-        self.canvas.ellipse(x1,y1,x2,y2, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
-
-    def _curves(self, node):
-        line_str = node.text.split()
-        lines = []
-        while len(line_str)>7:
-            self.canvas.bezier(*[utils.unit_get(l) for l in line_str[0:8]])
-            line_str = line_str[8:]
-
-    def _lines(self, node):
-        line_str = node.text.split()
-        lines = []
-        while len(line_str)>3:
-            lines.append([utils.unit_get(l) for l in line_str[0:4]])
-            line_str = line_str[4:]
-        self.canvas.lines(lines)
-
-    def _grid(self, node):
-        xlist = [utils.unit_get(s) for s in node.get('xs').split(',')]
-        ylist = [utils.unit_get(s) for s in node.get('ys').split(',')]
-
-        self.canvas.grid(xlist, ylist)
-
-    def _translate(self, node):
-        dx = utils.unit_get(node.get('dx')) or 0
-        dy = utils.unit_get(node.get('dy')) or 0
-        self.canvas.translate(dx,dy)
-
-    def _circle(self, node):
-        self.canvas.circle(x_cen=utils.unit_get(node.get('x')), y_cen=utils.unit_get(node.get('y')), r=utils.unit_get(node.get('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
-
-    def _place(self, node):
-        flows = _rml_flowable(self.doc, self.localcontext, images=self.images, path=self.path, title=self.title, canvas=self.canvas).render(node)
-        infos = utils.attr_get(node, ['x','y','width','height'])
-
-        infos['y']+=infos['height']
-        for flow in flows:
-            w,h = flow.wrap(infos['width'], infos['height'])
-            if w<=infos['width'] and h<=infos['height']:
-                infos['y']-=h
-                flow.drawOn(self.canvas,infos['x'],infos['y'])
-                infos['height']-=h
-            else:
-                raise ValueError("Not enough space")
-
-    def _line_mode(self, node):
-        ljoin = {'round':1, 'mitered':0, 'bevelled':2}
-        lcap = {'default':0, 'round':1, 'square':2}
-
-        if node.get('width'):
-            self.canvas.setLineWidth(utils.unit_get(node.get('width')))
-        if node.get('join'):
-            self.canvas.setLineJoin(ljoin[node.get('join')])
-        if node.get('cap'):
-            self.canvas.setLineCap(lcap[node.get('cap')])
-        if node.get('miterLimit'):
-            self.canvas.setDash(utils.unit_get(node.get('miterLimit')))
-        if node.get('dash'):
-            dashes = node.get('dash').split(',')
-            for x in range(len(dashes)):
-                dashes[x]=utils.unit_get(dashes[x])
-            self.canvas.setDash(node.get('dash').split(','))
-
-    def _image(self, node):
-        import urllib
-        import urlparse
-        from reportlab.lib.utils import ImageReader
-        nfile = node.get('file')
-        if not nfile:
-            if node.get('name'):
-                image_data = self.images[node.get('name')]
-                _logger.debug("Image %s used", node.get('name'))
-                s = StringIO(image_data)
-            else:
-                newtext = node.text
-                if self.localcontext:
-                    res = utils._regex.findall(newtext)
-                    for key in res:
-                        newtext = safe_eval(key, {}, self.localcontext) or ''
-                image_data = None
-                if newtext:
-                    image_data = base64.decodestring(newtext)
-                if image_data:
-                    s = StringIO(image_data)
-                else:
-                    _logger.debug("No image data!")
-                    return False
-        else:
-            if nfile in self.images:
-                s = StringIO(self.images[nfile])
-            else:
-                try:
-                    up = urlparse.urlparse(str(nfile))
-                except ValueError:
-                    up = False
-                if up and up.scheme:
-                    # RFC: do we really want to open external URLs?
-                    # Are we safe from cross-site scripting or attacks?
-                    _logger.debug("Retrieve image from %s", nfile)
-                    u = urllib.urlopen(str(nfile))
-                    s = StringIO(u.read())
-                else:
-                    _logger.debug("Open image file %s ", nfile)
-                    s = _open_image(nfile, path=self.path)
-        try:
-            img = ImageReader(s)
-            (sx,sy) = img.getSize()
-            _logger.debug("Image is %dx%d", sx, sy)
-            args = { 'x': 0.0, 'y': 0.0, 'mask': 'auto'}
-            for tag in ('width','height','x','y'):
-                if node.get(tag):
-                    args[tag] = utils.unit_get(node.get(tag))
-            if ('width' in args) and (not 'height' in args):
-                args['height'] = sy * args['width'] / sx
-            elif ('height' in args) and (not 'width' in args):
-                args['width'] = sx * args['height'] / sy
-            elif ('width' in args) and ('height' in args):
-                if (float(args['width'])/args['height'])>(float(sx)>sy):
-                    args['width'] = sx * args['height'] / sy
-                else:
-                    args['height'] = sy * args['width'] / sx
-            self.canvas.drawImage(img, **args)
-        finally:
-            s.close()
-#        self.canvas._doc.SaveToFile(self.canvas._filename, self.canvas)
-
-    def _path(self, node):
-        self.path = self.canvas.beginPath()
-        self.path.moveTo(**utils.attr_get(node, ['x','y']))
-        for n in utils._child_get(node, self):
-            if not n.text :
-                if n.tag=='moveto':
-                    vals = utils.text_get(n).split()
-                    self.path.moveTo(utils.unit_get(vals[0]), utils.unit_get(vals[1]))
-                elif n.tag=='curvesto':
-                    vals = utils.text_get(n).split()
-                    while len(vals)>5:
-                        pos=[]
-                        while len(pos)<6:
-                            pos.append(utils.unit_get(vals.pop(0)))
-                        self.path.curveTo(*pos)
-            elif n.text:
-                data = n.text.split()               # Not sure if I must merge all TEXT_NODE ?
-                while len(data)>1:
-                    x = utils.unit_get(data.pop(0))
-                    y = utils.unit_get(data.pop(0))
-                    self.path.lineTo(x,y)
-        if (not node.get('close')) or utils.bool_get(node.get('close')):
-            self.path.close()
-        self.canvas.drawPath(self.path, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
-
-    def setFont(self, node):
-        fontname = select_fontname(node.get('name'), self.canvas._fontname)
-        return self.canvas.setFont(fontname, utils.unit_get(node.get('size')))
-
-    def render(self, node):
-        tags = {
-            'drawCentredString': self._drawCenteredString,
-            'drawRightString': self._drawRightString,
-            'drawString': self._drawString,
-            'rect': self._rect,
-            'ellipse': self._ellipse,
-            'lines': self._lines,
-            'grid': self._grid,
-            'curves': self._curves,
-            'fill': lambda node: self.canvas.setFillColor(color.get(node.get('color'))),
-            'stroke': lambda node: self.canvas.setStrokeColor(color.get(node.get('color'))),
-            'setFont': self.setFont ,
-            'place': self._place,
-            'circle': self._circle,
-            'lineMode': self._line_mode,
-            'path': self._path,
-            'rotate': lambda node: self.canvas.rotate(float(node.get('degrees'))),
-            'translate': self._translate,
-            'image': self._image
-        }
-        for n in utils._child_get(node, self):
-            if n.tag in tags:
-                tags[n.tag](n)
-
-class _rml_draw(object):
-    def __init__(self, localcontext, node, styles, images=None, path='.', title=None):
-        if images is None:
-            images = {}
-        self.localcontext = localcontext
-        self.node = node
-        self.styles = styles
-        self.canvas = None
-        self.images = images
-        self.path = path
-        self.canvas_title = title
-
-    def render(self, canvas, doc):
-        canvas.saveState()
-        cnv = _rml_canvas(canvas, self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
-        cnv.render(self.node)
-        canvas.restoreState()
-
-class _rml_Illustration(platypus.flowables.Flowable):
-    def __init__(self, node, localcontext, styles, self2):
-        self.localcontext = (localcontext or {}).copy()
-        self.node = node
-        self.styles = styles
-        self.width = utils.unit_get(node.get('width'))
-        self.height = utils.unit_get(node.get('height'))
-        self.self2 = self2
-    def wrap(self, *args):
-        return self.width, self.height
-    def draw(self):
-        drw = _rml_draw(self.localcontext ,self.node,self.styles, images=self.self2.images, path=self.self2.path, title=self.self2.title)
-        drw.render(self.canv, None)
-
-# Workaround for issue #15: https://bitbucket.org/rptlab/reportlab/issue/15/infinite-pages-produced-when-splitting 
-original_pto_split = platypus.flowables.PTOContainer.split
-def split(self, availWidth, availHeight):
-    res = original_pto_split(self, availWidth, availHeight)
-    if len(res) > 2 and len(self._content) > 0:
-        header = self._content[0]._ptoinfo.header
-        trailer = self._content[0]._ptoinfo.trailer
-        if isinstance(res[-2], platypus.flowables.UseUpSpace) and len(header + trailer) == len(res[:-2]):
-            return []
-    return res
-platypus.flowables.PTOContainer.split = split
-
-class _rml_flowable(object):
-    def __init__(self, doc, localcontext, images=None, path='.', title=None, canvas=None):
-        if images is None:
-            images = {}
-        self.localcontext = localcontext
-        self.doc = doc
-        self.styles = doc.styles
-        self.images = images
-        self.path = path
-        self.title = title
-        self.canvas = canvas
-
-    def _textual(self, node):
-        rc1 = utils._process_text(self, node.text or '')
-        for n in utils._child_get(node,self):
-            txt_n = copy.deepcopy(n)
-            for key in txt_n.attrib.keys():
-                if key in ('rml_except', 'rml_loop', 'rml_tag'):
-                    del txt_n.attrib[key]
-            if not n.tag == 'bullet':
-                if n.tag == 'pageNumber': 
-                    txt_n.text = self.canvas and str(self.canvas.getPageNumber()) or ''
-                else:
-                    txt_n.text = utils.xml2str(self._textual(n))
-            txt_n.tail = n.tail and utils.xml2str(utils._process_text(self, n.tail.replace('\n',''))) or ''
-            rc1 += etree.tostring(txt_n)
-        return rc1
-
-    def _table(self, node):
-        children = utils._child_get(node,self,'tr')
-        if not children:
-            return None
-        length = 0
-        colwidths = None
-        rowheights = None
-        data = []
-        styles = []
-        posy = 0
-        for tr in children:
-            paraStyle = None
-            if tr.get('style'):
-                st = copy.deepcopy(self.styles.table_styles[tr.get('style')])
-                for si in range(len(st._cmds)):
-                    s = list(st._cmds[si])
-                    s[1] = (s[1][0],posy)
-                    s[2] = (s[2][0],posy)
-                    st._cmds[si] = tuple(s)
-                styles.append(st)
-            if tr.get('paraStyle'):
-                paraStyle = self.styles.styles[tr.get('paraStyle')]
-            data2 = []
-            posx = 0
-            for td in utils._child_get(tr, self,'td'):
-                if td.get('style'):
-                    st = copy.deepcopy(self.styles.table_styles[td.get('style')])
-                    for s in st._cmds:
-                        s[1][1] = posy
-                        s[2][1] = posy
-                        s[1][0] = posx
-                        s[2][0] = posx
-                    styles.append(st)
-                if td.get('paraStyle'):
-                    # TODO: merge styles
-                    paraStyle = self.styles.styles[td.get('paraStyle')]
-                posx += 1
-
-                flow = []
-                for n in utils._child_get(td, self):
-                    if n.tag == etree.Comment:
-                        n.text = ''
-                        continue
-                    fl = self._flowable(n, extra_style=paraStyle)
-                    if isinstance(fl,list):
-                        flow  += fl
-                    else:
-                        flow.append( fl )
-
-                if not len(flow):
-                    flow = self._textual(td)
-                data2.append( flow )
-            if len(data2)>length:
-                length=len(data2)
-                for ab in data:
-                    while len(ab)<length:
-                        ab.append('')
-            while len(data2)<length:
-                data2.append('')
-            data.append( data2 )
-            posy += 1
-
-        if node.get('colWidths'):
-            assert length == len(node.get('colWidths').split(','))
-            colwidths = [utils.unit_get(f.strip()) for f in node.get('colWidths').split(',')]
-        if node.get('rowHeights'):
-            rowheights = [utils.unit_get(f.strip()) for f in node.get('rowHeights').split(',')]
-            if len(rowheights) == 1:
-                rowheights = rowheights[0]
-        table = platypus.LongTable(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'})))
-        if node.get('style'):
-            table.setStyle(self.styles.table_styles[node.get('style')])
-        for s in styles:
-            table.setStyle(s)
-        return table
-
-    def _illustration(self, node):
-        return _rml_Illustration(node, self.localcontext, self.styles, self)
-
-    def _textual_image(self, node):
-        return base64.decodestring(node.text)
-
-    def _pto(self, node):
-        sub_story = []
-        pto_header = None
-        pto_trailer = None
-        for node in utils._child_get(node, self):
-            if node.tag == etree.Comment:
-                node.text = ''
-                continue
-            elif node.tag=='pto_header':
-                pto_header = self.render(node)
-            elif node.tag=='pto_trailer':
-                pto_trailer = self.render(node)
-            else:
-                flow = self._flowable(node)
-                if flow:
-                    if isinstance(flow,list):
-                        sub_story = sub_story + flow
-                    else:
-                        sub_story.append(flow)
-        return platypus.flowables.PTOContainer(sub_story, trailer=pto_trailer, header=pto_header)
-
-    def _flowable(self, node, extra_style=None):
-        if node.tag=='pto':
-            return self._pto(node)
-        if node.tag=='para':
-            style = self.styles.para_style_get(node)
-            if extra_style:
-                style.__dict__.update(extra_style)
-            text_node = self._textual(node).strip().replace('\n\n', '\n').replace('\n', '<br/>')
-            instance = platypus.Paragraph(text_node, style, **(utils.attr_get(node, [], {'bulletText':'str'})))
-            result = [instance]
-            if LooseVersion(reportlab.Version) > LooseVersion('3.0') and not instance.getPlainText().strip() and instance.text.strip():
-                result.append(platypus.Paragraph('&nbsp;<br/>', style, **(utils.attr_get(node, [], {'bulletText': 'str'}))))
-            return result
-        elif node.tag=='barCode':
-            try:
-                from reportlab.graphics.barcode import code128
-                from reportlab.graphics.barcode import code39
-                from reportlab.graphics.barcode import code93
-                from reportlab.graphics.barcode import common
-                from reportlab.graphics.barcode import fourstate
-                from reportlab.graphics.barcode import usps
-                from reportlab.graphics.barcode import createBarcodeDrawing
-
-            except ImportError:
-                _logger.warning("Cannot use barcode renderers:", exc_info=True)
-                return None
-            args = utils.attr_get(node, [], {'ratio':'float','xdim':'unit','height':'unit','checksum':'int','quiet':'int','width':'unit','stop':'bool','bearers':'int','barWidth':'float','barHeight':'float'})
-            codes = {
-                'codabar': lambda x: common.Codabar(x, **args),
-                'code11': lambda x: common.Code11(x, **args),
-                'code128': lambda x: code128.Code128(str(x), **args),
-                'standard39': lambda x: code39.Standard39(str(x), **args),
-                'standard93': lambda x: code93.Standard93(str(x), **args),
-                'i2of5': lambda x: common.I2of5(x, **args),
-                'extended39': lambda x: code39.Extended39(str(x), **args),
-                'extended93': lambda x: code93.Extended93(str(x), **args),
-                'msi': lambda x: common.MSI(x, **args),
-                'fim': lambda x: usps.FIM(x, **args),
-                'postnet': lambda x: usps.POSTNET(x, **args),
-                'ean13': lambda x: createBarcodeDrawing('EAN13', value=str(x), **args),
-                'qrcode': lambda x: createBarcodeDrawing('QR', value=x, **args),
-            }
-            code = 'code128'
-            if node.get('code'):
-                code = node.get('code').lower()
-            return codes[code](self._textual(node))
-        elif node.tag=='name':
-            self.styles.names[ node.get('id')] = node.get('value')
-            return None
-        elif node.tag=='xpre':
-            style = self.styles.para_style_get(node)
-            return platypus.XPreformatted(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str','dedent':'int','frags':'int'})))
-        elif node.tag=='pre':
-            style = self.styles.para_style_get(node)
-            return platypus.Preformatted(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str','dedent':'int'})))
-        elif node.tag=='illustration':
-            return  self._illustration(node)
-        elif node.tag=='blockTable':
-            return  self._table(node)
-        elif node.tag=='title':
-            styles = reportlab.lib.styles.getSampleStyleSheet()
-            style = styles['Title']
-            return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'})))
-        elif re.match('^h([1-9]+[0-9]*)$', (node.tag or '')):
-            styles = reportlab.lib.styles.getSampleStyleSheet()
-            style = styles['Heading'+str(node.tag[1:])]
-            return platypus.Paragraph(self._textual(node), style, **(utils.attr_get(node, [], {'bulletText':'str'})))
-        elif node.tag=='image':
-            image_data = False
-            if not node.get('file'):
-                if node.get('name'):
-                    if node.get('name') in self.doc.images:
-                        _logger.debug("Image %s read ", node.get('name'))
-                        image_data = self.doc.images[node.get('name')].read()
-                    else:
-                        _logger.warning("Image %s not defined", node.get('name'))
-                        return False
-                else:
-                    import base64
-                    newtext = node.text
-                    if self.localcontext:
-                        newtext = utils._process_text(self, node.text or '')
-                    image_data = base64.decodestring(newtext)
-                if not image_data:
-                    _logger.debug("No inline image data")
-                    return False
-                image = StringIO(image_data)
-            else:
-                _logger.debug("Image get from file %s", node.get('file'))
-                image = _open_image(node.get('file'), path=self.doc.path)
-            return platypus.Image(image, mask=(250,255,250,255,250,255), **(utils.attr_get(node, ['width','height'])))
-        elif node.tag=='spacer':
-            if node.get('width'):
-                width = utils.unit_get(node.get('width'))
-            else:
-                width = utils.unit_get('1cm')
-            length = utils.unit_get(node.get('length'))
-            return platypus.Spacer(width=width, height=length)
-        elif node.tag=='section':
-            return self.render(node)
-        elif node.tag == 'pageNumberReset':
-            return PageReset()
-        elif node.tag in ('pageBreak', 'nextPage'):
-            return platypus.PageBreak()
-        elif node.tag=='condPageBreak':
-            return platypus.CondPageBreak(**(utils.attr_get(node, ['height'])))
-        elif node.tag=='setNextTemplate':
-            return platypus.NextPageTemplate(str(node.get('name')))
-        elif node.tag=='nextFrame':
-            return platypus.CondPageBreak(1000)           # TODO: change the 1000 !
-        elif node.tag == 'setNextFrame':
-            from reportlab.platypus.doctemplate import NextFrameFlowable
-            return NextFrameFlowable(str(node.get('name')))
-        elif node.tag == 'currentFrame':
-            from reportlab.platypus.doctemplate import CurrentFrameFlowable
-            return CurrentFrameFlowable(str(node.get('name')))
-        elif node.tag == 'frameEnd':
-            return EndFrameFlowable()
-        elif node.tag == 'hr':
-            width_hr=node.get('width') or '100%'
-            color_hr=node.get('color')  or 'black'
-            thickness_hr=node.get('thickness') or 1
-            lineCap_hr=node.get('lineCap') or 'round'
-            return platypus.flowables.HRFlowable(width=width_hr,color=color.get(color_hr),thickness=float(thickness_hr),lineCap=str(lineCap_hr))
-        else:
-            sys.stderr.write('Warning: flowable not yet implemented: %s !\n' % (node.tag,))
-            return None
-
-    def render(self, node_story):
-        def process_story(node_story):
-            sub_story = []
-            for node in utils._child_get(node_story, self):
-                if node.tag == etree.Comment:
-                    node.text = ''
-                    continue
-                flow = self._flowable(node)
-                if flow:
-                    if isinstance(flow,list):
-                        sub_story = sub_story + flow
-                    else:
-                        sub_story.append(flow)
-            return sub_story
-        return process_story(node_story)
-
-
-class EndFrameFlowable(ActionFlowable):
-    def __init__(self,resume=0):
-        ActionFlowable.__init__(self,('frameEnd',resume))
-
-class TinyDocTemplate(platypus.BaseDocTemplate):
-
-    def beforeDocument(self):
-        # Store some useful value directly inside canvas, so it's available
-        # on flowable drawing (needed for proper PageCount handling)
-        self.canv._doPageReset = False
-        self.canv._storyCount = 0
-
-    def ___handle_pageBegin(self):
-        self.page += 1
-        self.pageTemplate.beforeDrawPage(self.canv,self)
-        self.pageTemplate.checkPageSize(self.canv,self)
-        self.pageTemplate.onPage(self.canv,self)
-        for f in self.pageTemplate.frames: f._reset()
-        self.beforePage()
-        self._curPageFlowableCount = 0
-        if hasattr(self,'_nextFrameIndex'):
-            del self._nextFrameIndex
-        for f in self.pageTemplate.frames:
-            if f.id == 'first':
-                self.frame = f
-                break
-        self.handle_frameBegin()
-
-    def afterPage(self):
-        if isinstance(self.canv, NumberedCanvas):
-            # save current page states before eventual reset
-            self.canv._saved_page_states.append(dict(self.canv.__dict__))
-        if self.canv._doPageReset:
-            # Following a <pageReset/> tag:
-            # - we reset page number to 0
-            # - we add  an new PageCount flowable (relative to the current
-            #   story number), but not for NumeredCanvas at is handle page
-            #   count itself)
-            # NOTE: _rml_template render() method add a PageReset flowable at end
-            #   of each story, so we're sure to pass here at least once per story.
-            if not isinstance(self.canv, NumberedCanvas):
-                self.handle_flowable([ PageCount(story_count=self.canv._storyCount) ])
-            self.canv._pageCount = self.page
-            self.page = 0
-            self.canv._flag = True
-            self.canv._pageNumber = 0
-            self.canv._doPageReset = False
-            self.canv._storyCount += 1
-
-class _rml_template(object):
-    def __init__(self, localcontext, out, node, doc, images=None, path='.', title=None):
-        if images is None:
-            images = {}
-        if not localcontext:
-            localcontext={'internal_header':True}
-        self.localcontext = localcontext
-        self.images= images
-        self.path = path
-        self.title = title
-
-        pagesize_map = {'a4': A4,
-                    'us_letter': letter
-                    }
-        pageSize = A4
-        if self.localcontext.get('company'):
-            pageSize = pagesize_map.get(self.localcontext.get('company').rml_paper_format, A4)
-        if node.get('pageSize'):
-            ps = map(lambda x:x.strip(), node.get('pageSize').replace(')', '').replace('(', '').split(','))
-            pageSize = ( utils.unit_get(ps[0]),utils.unit_get(ps[1]) )
-
-        self.doc_tmpl = TinyDocTemplate(out, pagesize=pageSize, **utils.attr_get(node, ['leftMargin','rightMargin','topMargin','bottomMargin'], {'allowSplitting':'int','showBoundary':'bool','rotation':'int','title':'str','author':'str'}))
-        self.page_templates = []
-        self.styles = doc.styles
-        self.doc = doc
-        self.image=[]
-        pts = node.findall('pageTemplate')
-        for pt in pts:
-            frames = []
-            for frame_el in pt.findall('frame'):
-                frame = platypus.Frame( **(utils.attr_get(frame_el, ['x1','y1', 'width','height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding'], {'id':'str', 'showBoundary':'bool'})) )
-                if utils.attr_get(frame_el, ['last']):
-                    frame.lastFrame = True
-                frames.append( frame )
-            try :
-                gr = pt.findall('pageGraphics')\
-                    or pt[1].findall('pageGraphics')
-            except Exception: # FIXME: be even more specific, perhaps?
-                gr=''
-            if len(gr):
-#                self.image=[ n for n in utils._child_get(gr[0], self) if n.tag=='image' or not self.localcontext]
-                drw = _rml_draw(self.localcontext,gr[0], self.doc, images=images, path=self.path, title=self.title)
-                self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) ))
-            else:
-                drw = _rml_draw(self.localcontext,node,self.doc,title=self.title)
-                self.page_templates.append( platypus.PageTemplate(frames=frames,onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) ))
-        self.doc_tmpl.addPageTemplates(self.page_templates)
-
-    def render(self, node_stories):
-        if self.localcontext and not self.localcontext.get('internal_header',False):
-            del self.localcontext['internal_header']
-        fis = []
-        r = _rml_flowable(self.doc,self.localcontext, images=self.images, path=self.path, title=self.title, canvas=None)
-        story_cnt = 0
-        for node_story in node_stories:
-            if story_cnt > 0:
-                fis.append(platypus.PageBreak())
-            fis += r.render(node_story)
-            # end of story numbering computation
-            fis.append(PageReset())
-            story_cnt += 1
-        try:
-            if self.localcontext and self.localcontext.get('internal_header',False):
-                self.doc_tmpl.afterFlowable(fis)
-                self.doc_tmpl.build(fis,canvasmaker=NumberedCanvas)
-            else:
-                self.doc_tmpl.build(fis)
-        except platypus.doctemplate.LayoutError as e:
-            e.name = 'Print Error'
-            e.value = 'The document you are trying to print contains a table row that does not fit on one page. Please try to split it in smaller rows or contact your administrator.'
-            raise
-
-def parseNode(rml, localcontext=None, fout=None, images=None, path='.', title=None):
-    node = etree.XML(rml)
-    r = _rml_doc(node, localcontext, images, path, title=title)
-    #try to override some font mappings
-    try:
-        SetCustomFonts(r)
-    except Exception as exc:
-        _logger.info('Cannot set font mapping: %s', "".join(traceback.format_exception_only(type(exc),exc)))
-    fp = StringIO()
-    r.render(fp)
-    return fp.getvalue()
-
-def parseString(rml, localcontext=None, fout=None, images=None, path='.', title=None):
-    node = etree.XML(rml)
-    r = _rml_doc(node, localcontext, images, path, title=title)
-
-    #try to override some font mappings
-    try:
-        SetCustomFonts(r)
-    except Exception:
-        pass
-
-    if fout:
-        fp = file(fout,'wb')
-        r.render(fp)
-        fp.close()
-        return fout
-    else:
-        fp = StringIO()
-        r.render(fp)
-        return fp.getvalue()
-
-def trml2pdf_help():
-    print 'Usage: trml2pdf input.rml >output.pdf'
-    print 'Render the standard input (RML) and output a PDF file'
-    sys.exit(0)
-
-if __name__=="__main__":
-    if len(sys.argv)>1:
-        if sys.argv[1]=='--help':
-            trml2pdf_help()
-        print parseString(file(sys.argv[1], 'r').read()),
-    else:
-        print 'Usage: trml2pdf input.rml >output.pdf'
-        print 'Try \'trml2pdf --help\' for more information.'
diff --git a/odoo/report/render/rml2pdf/utils.py b/odoo/report/render/rml2pdf/utils.py
deleted file mode 100644
index 785e12fdc41f58eb7ef9d38f0e1de4cece1061fe..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2pdf/utils.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import copy
-import locale
-import logging
-import re
-
-import reportlab
-
-import odoo.tools as tools
-from odoo.tools.safe_eval import safe_eval
-from odoo.tools.misc import ustr
-
-_logger = logging.getLogger(__name__)
-
-_regex = re.compile('\[\[(.+?)\]\]')
-
-def str2xml(s):
-    return (s or '').replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
-
-def xml2str(s):
-    return (s or '').replace('&amp;','&').replace('&lt;','<').replace('&gt;','>')
-
-def _child_get(node, self=None, tagname=None):
-    for n in node:
-        if self and self.localcontext and n.get('rml_loop'):
-
-            for ctx in safe_eval(n.get('rml_loop'),{}, self.localcontext):
-                self.localcontext.update(ctx)
-                if (tagname is None) or (n.tag==tagname):
-                    if n.get('rml_except', False):
-                        try:
-                            safe_eval(n.get('rml_except'), {}, self.localcontext)
-                        except GeneratorExit:
-                            continue
-                        except Exception as e:
-                            _logger.info('rml_except: "%s"', n.get('rml_except',''), exc_info=True)
-                            continue
-                    if n.get('rml_tag'):
-                        try:
-                            (tag,attr) = safe_eval(n.get('rml_tag'),{}, self.localcontext)
-                            n2 = copy.deepcopy(n)
-                            n2.tag = tag
-                            n2.attrib.update(attr)
-                            yield n2
-                        except GeneratorExit:
-                            yield n
-                        except Exception as e:
-                            _logger.info('rml_tag: "%s"', n.get('rml_tag',''), exc_info=True)
-                            yield n
-                    else:
-                        yield n
-            continue
-        if self and self.localcontext and n.get('rml_except'):
-            try:
-                safe_eval(n.get('rml_except'), {}, self.localcontext)
-            except GeneratorExit:
-                continue
-            except Exception as e:
-                _logger.info('rml_except: "%s"', n.get('rml_except',''), exc_info=True)
-                continue
-        if self and self.localcontext and n.get('rml_tag'):
-            try:
-                (tag,attr) = safe_eval(n.get('rml_tag'),{}, self.localcontext)
-                n2 = copy.deepcopy(n)
-                n2.tag = tag
-                n2.attrib.update(attr or {})
-                yield n2
-                tagname = ''
-            except GeneratorExit:
-                pass
-            except Exception as e:
-                _logger.info('rml_tag: "%s"', n.get('rml_tag',''), exc_info=True)
-                pass
-        if (tagname is None) or (n.tag==tagname):
-            yield n
-
-def _process_text(self, txt):
-        """Translate ``txt`` according to the language in the local context,
-           replace dynamic ``[[expr]]`` with their real value, then escape
-           the result for XML.
-
-           :param str txt: original text to translate (must NOT be XML-escaped)
-           :return: translated text, with dynamic expressions evaluated and
-                    with special XML characters escaped (``&,<,>``).
-        """
-        if not self.localcontext:
-            return str2xml(txt)
-        if not txt:
-            return ''
-        result = ''
-        sps = _regex.split(txt)
-        while sps:
-            # This is a simple text to translate
-            to_translate = tools.ustr(sps.pop(0))
-            result += tools.ustr(self.localcontext.get('translate', lambda x:x)(to_translate))
-            if sps:
-                txt = None
-                try:
-                    expr = sps.pop(0)
-                    txt = safe_eval(expr, self.localcontext)
-                    if txt and isinstance(txt, basestring):
-                        txt = tools.ustr(txt)
-                except Exception:
-                    _logger.info("Failed to evaluate expression [[ %s ]] with context %r while rendering report, ignored.", expr, self.localcontext)
-                if isinstance(txt, basestring):
-                    result += txt
-                elif txt and (txt is not None) and (txt is not False):
-                    result += ustr(txt)
-        return str2xml(result)
-
-def text_get(node):
-    return ''.join([ustr(n.text) for n in node])
-
-units = [
-    (re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
-    (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
-    (re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
-    (re.compile('^(-?[0-9\.]+)\s*$'), 1)
-]
-
-def unit_get(size):
-    global units
-    if size:
-        if size.find('.') == -1:
-            decimal_point = '.'
-            try:
-                decimal_point = locale.nl_langinfo(locale.RADIXCHAR)
-            except Exception:
-                decimal_point = locale.localeconv()['decimal_point']
-
-            size = size.replace(decimal_point, '.')
-
-        for unit in units:
-            res = unit[0].search(size, 0)
-            if res:
-                return unit[1]*float(res.group(1))
-    return False
-
-def tuple_int_get(node, attr_name, default=None):
-    if not node.get(attr_name):
-        return default
-    return map(int, node.get(attr_name).split(','))
-
-def bool_get(value):
-    return (str(value)=="1") or (value.lower()=='yes')
-
-def attr_get(node, attrs, dict=None):
-    if dict is None:
-        dict = {}
-    res = {}
-    for name in attrs:
-        if node.get(name):
-            res[name] = unit_get(node.get(name))
-    for key in dict:
-        if node.get(key):
-            if dict[key]=='str':
-                res[key] = tools.ustr(node.get(key))
-            elif dict[key]=='bool':
-                res[key] = bool_get(node.get(key))
-            elif dict[key]=='int':
-                res[key] = int(node.get(key))
-            elif dict[key]=='unit':
-                res[key] = unit_get(node.get(key))
-            elif dict[key] == 'float' :
-                res[key] = float(node.get(key))
-    return res
diff --git a/odoo/report/render/rml2txt/__init__.py b/odoo/report/render/rml2txt/__init__.py
deleted file mode 100644
index 0eccc05611119d169a79b42fd1a25bfb15354c90..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2txt/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from .rml2txt import parseString, parseNode
-
-
-""" This engine is the minimalistic renderer of RML documents into text files,
-    using spaces and newlines to format.
-
-    It was needed in some special applications, where legal reports need to be
-    printed in special (dot-matrix) printers.
-"""
diff --git a/odoo/report/render/rml2txt/rml2txt.py b/odoo/report/render/rml2txt/rml2txt.py
deleted file mode 100755
index 3a401918ea37014201de5c5db54d6574c9ddd172..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2txt/rml2txt.py
+++ /dev/null
@@ -1,484 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import sys
-import StringIO
-
-from lxml import etree
-
-from . import utils
-
-Font_size= 10.0
-
-def verbose(text):
-    sys.stderr.write(text+"\n")
-
-
-class textbox(object):
-    """A box containing plain text.
-    It can have an offset, in chars.
-    Lines can be either text strings, or textbox'es, recursively.
-    """
-    def __init__(self,x=0, y=0):
-        self.posx = x
-        self.posy = y
-        self.lines = []
-        self.curline = ''
-        self.endspace = False
-     
-    def newline(self):
-        if isinstance(self.curline, textbox):
-            self.lines.extend(self.curline.renderlines())
-        else:
-            self.lines.append(self.curline)
-        self.curline = ''
-    
-    def fline(self):
-        if isinstance(self.curline, textbox):
-            self.lines.extend(self.curline.renderlines())
-        elif len(self.curline):
-            self.lines.append(self.curline)
-        self.curline = ''
-    
-    def appendtxt(self,txt):
-        """Append some text to the current line.
-           Mimic the HTML behaviour, where all whitespace evaluates to
-           a single space """
-        if not txt:
-            return
-        bs = es = False
-        if txt[0].isspace():
-            bs = True
-        if txt[len(txt)-1].isspace():
-            es = True
-        if bs and not self.endspace:
-            self.curline += " "
-        self.curline += txt.strip().replace("\n"," ").replace("\t"," ")
-        if es:
-            self.curline += " "
-        self.endspace = es
-
-    def rendertxt(self,xoffset=0):
-        result = ''
-        lineoff = ""
-        for i in range(self.posy):
-            result +="\n"
-        for i in range(self.posx+xoffset):
-            lineoff+=" "
-        for l in self.lines:
-            result+= lineoff+ l +"\n"
-        return result
-    
-    def renderlines(self,pad=0):
-        """Returns a list of lines, from the current object
-        pad: all lines must be at least pad characters.
-        """
-        result = []
-        lineoff = ""
-        for i in range(self.posx):
-            lineoff+=" "
-        for l in self.lines:
-            lpad = ""
-            if pad and len(l) < pad :
-                for i in range(pad - len(l)):
-                    lpad += " "
-                #elif pad and len(l) > pad ?
-                result.append(lineoff+ l+lpad)
-        return result
-            
-            
-    def haplines(self,arr,offset,cc= ''):
-        """ Horizontaly append lines 
-        """
-        while len(self.lines) < len(arr):
-            self.lines.append("")
-        
-        for i in range(len(self.lines)):
-            while len(self.lines[i]) < offset:
-                self.lines[i] += " "
-        for i in range(len(arr)):
-            self.lines[i] += cc +arr[i] 
-        
-
-class _flowable(object):
-    def __init__(self, template, doc,localcontext):
-        self._tags = {
-            '1title': self._tag_title,
-            '1spacer': self._tag_spacer,
-            'para': self._tag_para,
-            'font': self._tag_font,
-            'section': self._tag_section,
-            '1nextFrame': self._tag_next_frame,
-            'blockTable': self._tag_table,
-            '1pageBreak': self._tag_page_break,
-            '1setNextTemplate': self._tag_next_template,
-        }
-        self.template = template
-        self.doc = doc
-        self.localcontext = localcontext
-        self.nitags = []
-        self.tbox = None
-
-    def warn_nitag(self,tag):
-        if tag not in self.nitags:
-            verbose("Unknown tag \"%s\", please implement it." % tag)
-            self.nitags.append(tag)
-    
-    def _tag_page_break(self, node):
-        return "\f"
-
-    def _tag_next_template(self, node):
-        return ''
-
-    def _tag_next_frame(self, node):
-        result=self.template.frame_stop()
-        result+='\n'
-        result+=self.template.frame_start()
-        return result
-
-    def _tag_title(self, node):
-        node.tagName='h1'
-        return node.toxml()
-
-    def _tag_spacer(self, node):
-        length = 1+int(utils.unit_get(node.get('length')))/35
-        return "\n"*length
-
-    def _tag_table(self, node):
-        self.tb.fline()
-        saved_tb = self.tb
-        self.tb = None
-        sizes = None
-        if node.get('colWidths'):
-            sizes = map(lambda x: utils.unit_get(x), node.get('colWidths').split(','))
-        trs = []
-        for n in utils._child_get(node,self):
-            if n.tag == 'tr':
-                tds = []
-                for m in utils._child_get(n,self):
-                    if m.tag == 'td':
-                        self.tb = textbox()
-                        self.rec_render_cnodes(m)
-                        tds.append(self.tb)
-                        self.tb = None
-                if len(tds):
-                    trs.append(tds)
-        
-        if not sizes:
-            verbose("computing table sizes..")
-        for tds in trs:
-            trt = textbox()
-            off=0
-            for i in range(len(tds)):
-                p = int(sizes[i]/Font_size)
-                trl = tds[i].renderlines(pad=p)
-                trt.haplines(trl,off)
-                off += sizes[i]/Font_size
-            saved_tb.curline = trt
-            saved_tb.fline()
-        
-        self.tb = saved_tb
-        return
-
-    def _tag_para(self, node):
-        #TODO: styles
-        self.rec_render_cnodes(node)
-        self.tb.newline()
-
-    def _tag_section(self, node):
-        #TODO: styles
-        self.rec_render_cnodes(node)
-        self.tb.newline()
-
-    def _tag_font(self, node):
-        """We do ignore fonts.."""
-        self.rec_render_cnodes(node)
-
-    def rec_render_cnodes(self,node):
-        self.tb.appendtxt(utils._process_text(self, node.text or ''))
-        for n in utils._child_get(node,self):
-            self.rec_render(n)
-        self.tb.appendtxt(utils._process_text(self, node.tail or ''))
-
-    def rec_render(self,node):
-        """ Recursive render: fill outarr with text of current node
-        """
-        if node.tag is not None:
-            if node.tag in self._tags:
-                self._tags[node.tag](node)
-            else:
-                self.warn_nitag(node.tag)
-
-    def render(self, node):
-        self.tb= textbox()
-        #result = self.template.start()
-        #result += self.template.frame_start()
-        self.rec_render_cnodes(node)
-        #result += self.template.frame_stop()
-        #result += self.template.end()
-        result = self.tb.rendertxt()
-        del self.tb
-        return result
-
-class _rml_tmpl_tag(object):
-    def __init__(self, *args):
-        pass
-    def tag_start(self):
-        return ''
-    def tag_end(self):
-        return False
-    def tag_stop(self):
-        return ''
-    def tag_mergeable(self):
-        return True
-
-class _rml_tmpl_frame(_rml_tmpl_tag):
-    def __init__(self, posx, width):
-        self.width = width
-        self.posx = posx
-    def tag_start(self):
-        return "frame start"
-    def tag_end(self):
-        return True
-    def tag_stop(self):
-        return "frame stop"
-    def tag_mergeable(self):
-        return False
-
-    # An awfull workaround since I don't really understand the semantic behind merge.
-    def merge(self, frame):
-        pass
-
-class _rml_tmpl_draw_string(_rml_tmpl_tag):
-    def __init__(self, node, style):
-        self.posx = utils.unit_get(node.get('x'))
-        self.posy =  utils.unit_get(node.get('y'))
-        aligns = {
-            'drawString': 'left',
-            'drawRightString': 'right',
-            'drawCentredString': 'center'
-        }
-        align = aligns[node.localName]
-        self.pos = [(self.posx, self.posy, align, utils.text_get(node), style.get('td'), style.font_size_get('td'))]
-
-    def tag_start(self):
-        return "draw string \"%s\" @(%d,%d)..\n" %("txt",self.posx,self.posy)
-
-    def merge(self, ds):
-        self.pos+=ds.pos
-
-class _rml_tmpl_draw_lines(_rml_tmpl_tag):
-    def __init__(self, node, style):
-        coord = [utils.unit_get(x) for x in utils.text_get(node).split(' ')]
-        self.ok = False
-        self.posx = coord[0]
-        self.posy = coord[1]
-        self.width = coord[2]-coord[0]
-        self.ok = coord[1]==coord[3]
-        self.style = style
-        self.style = style.get('hr')
-
-    def tag_start(self):
-        return "draw lines..\n"
-
-class _rml_stylesheet(object):
-    def __init__(self, stylesheet, doc):
-        self.doc = doc
-        self.attrs = {}
-        self._tags = {
-            'fontSize': lambda x: ('font-size',str(utils.unit_get(x))+'px'),
-            'alignment': lambda x: ('text-align',str(x))
-        }
-        result = ''
-        for ps in stylesheet.findall('paraStyle'):
-            attr = {}
-            attrs = ps.attributes
-            for i in range(attrs.length):
-                name = attrs.item(i).localName
-                attr[name] = ps.get(name)
-            attrs = []
-            for a in attr:
-                if a in self._tags:
-                    attrs.append("%s:%s" % self._tags[a](attr[a]))
-            if len(attrs):
-                result += "p."+attr['name']+" {"+'; '.join(attrs)+"}\n"
-        self.result = result
-
-    def render(self):
-        return ''
-
-class _rml_draw_style(object):
-    def __init__(self):
-        self.style = {}
-        self._styles = {
-            'fill': lambda x: {'td': {'color':x.get('color')}},
-            'setFont': lambda x: {'td': {'font-size':x.get('size')+'px'}},
-            'stroke': lambda x: {'hr': {'color':x.get('color')}},
-        }
-    def update(self, node):
-        if node.localName in self._styles:
-            result = self._styles[node.localName](node)
-            for key in result:
-                if key in self.style:
-                    self.style[key].update(result[key])
-                else:
-                    self.style[key] = result[key]
-    def font_size_get(self,tag):
-        size  = utils.unit_get(self.style.get('td', {}).get('font-size','16'))
-        return size
-
-    def get(self,tag):
-        if not tag in self.style:
-            return ""
-        return ';'.join(['%s:%s' % (x[0],x[1]) for x in self.style[tag].items()])
-
-class _rml_template(object):
-    def __init__(self, localcontext, out, node, doc, images=None, path='.', title=None):
-        self.localcontext = localcontext
-        self.frame_pos = -1
-        self.frames = []
-        self.template_order = []
-        self.page_template = {}
-        self.loop = 0
-        self._tags = {
-            'drawString': _rml_tmpl_draw_string,
-            'drawRightString': _rml_tmpl_draw_string,
-            'drawCentredString': _rml_tmpl_draw_string,
-            'lines': _rml_tmpl_draw_lines
-        }
-        self.style = _rml_draw_style()
-        for pt in node.findall('pageTemplate'):
-            frames = {}
-            id = pt.get('id')
-            self.template_order.append(id)
-            for tmpl in pt.findall('frame'):
-                posy = int(utils.unit_get(tmpl.get('y1'))) #+utils.unit_get(tmpl.get('height')))
-                posx = int(utils.unit_get(tmpl.get('x1')))
-                frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width')))
-            for tmpl in node.findall('pageGraphics'):
-                for n in tmpl.getchildren():
-                    if n.nodeType==n.ELEMENT_NODE:
-                        if n.localName in self._tags:
-                            t = self._tags[n.localName](n, self.style)
-                            frames[(t.posy,t.posx,n.localName)] = t
-                        else:
-                            self.style.update(n)
-            keys = frames.keys()
-            keys.sort()
-            keys.reverse()
-            self.page_template[id] = []
-            for key in range(len(keys)):
-                if key>0 and keys[key-1][0] == keys[key][0]:
-                    if type(self.page_template[id][-1]) == type(frames[keys[key]]):
-                        if self.page_template[id][-1].tag_mergeable():
-                            self.page_template[id][-1].merge(frames[keys[key]])
-                        continue
-                self.page_template[id].append(frames[keys[key]])
-        self.template = self.template_order[0]
-
-    def _get_style(self):
-        return self.style
-
-    def set_next_template(self):
-        self.template = self.template_order[(self.template_order.index(name)+1) % self.template_order]
-        self.frame_pos = -1
-
-    def set_template(self, name):
-        self.template = name
-        self.frame_pos = -1
-
-    def frame_start(self):
-        result = ''
-        frames = self.page_template[self.template]
-        ok = True
-        while ok:
-            self.frame_pos += 1
-            if self.frame_pos>=len(frames):
-                self.frame_pos=0
-                self.loop=1
-                ok = False
-                continue
-            f = frames[self.frame_pos]
-            result+=f.tag_start()
-            ok = not f.tag_end()
-            if ok:
-                result+=f.tag_stop()
-        return result
-
-    def frame_stop(self):
-        frames = self.page_template[self.template]
-        f = frames[self.frame_pos]
-        result=f.tag_stop()
-        return result
-
-    def start(self):
-        return ''
-    
-    def end(self):
-        return "template end\n"
-
-class _rml_doc(object):
-    def __init__(self, node, localcontext=None, images=None, path='.', title=None):
-        self.localcontext = {} if localcontext is None else localcontext
-        self.etree = node
-        self.filename = self.etree.get('filename')
-        self.result = ''
-
-    def render(self, out):
-        #el = self.etree.findall('docinit')
-        #if el:
-            #self.docinit(el)
-
-        #el = self.etree.findall('stylesheet')
-        #self.styles = _rml_styles(el,self.localcontext)
-
-        el = self.etree.findall('template')
-        self.result =""
-        if len(el):
-            pt_obj = _rml_template(self.localcontext, out, el[0], self)
-            stories = utils._child_get(self.etree, self, 'story')
-            for story in stories:
-                if self.result:
-                    self.result += '\f'
-                f = _flowable(pt_obj,story,self.localcontext)
-                self.result += f.render(story)
-                del f
-        else:
-            self.result = "<cannot render w/o template>"
-        self.result += '\n'
-        out.write( self.result)
-
-def parseNode(rml, localcontext=None,fout=None, images=None, path='.',title=None):
-    node = etree.XML(rml)
-    r = _rml_doc(node, localcontext, images, path, title=title)
-    fp = StringIO.StringIO()
-    r.render(fp)
-    return fp.getvalue()
-
-def parseString(rml, localcontext=None,fout=None, images=None, path='.',title=None):
-    node = etree.XML(rml)
-    r = _rml_doc(node, localcontext, images, path, title=title)
-    if fout:
-        fp = file(fout,'wb')
-        r.render(fp)
-        fp.close()
-        return fout
-    else:
-        fp = StringIO.StringIO()
-        r.render(fp)
-        return fp.getvalue()
-
-def trml2pdf_help():
-    print 'Usage: rml2txt input.rml >output.html'
-    print 'Render the standard input (RML) and output an TXT file'
-    sys.exit(0)
-
-if __name__=="__main__":
-    if len(sys.argv)>1:
-        if sys.argv[1]=='--help':
-            trml2pdf_help()
-        print parseString(file(sys.argv[1], 'r').read()).encode('iso8859-7')
-    else:
-        print 'Usage: trml2txt input.rml >output.pdf'
-        print 'Try \'trml2txt --help\' for more information.'
diff --git a/odoo/report/render/rml2txt/utils.py b/odoo/report/render/rml2txt/utils.py
deleted file mode 100644
index d86380ccfbb0d18198a37cedbe3378a224335fd8..0000000000000000000000000000000000000000
--- a/odoo/report/render/rml2txt/utils.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import copy
-import re
-
-import reportlab
-import reportlab.lib.units
-
-from odoo.tools.safe_eval import safe_eval
-
-_regex = re.compile('\[\[(.+?)\]\]')
-
-def _child_get(node, self=None, tagname=None):
-    for n in node:
-        if self and self.localcontext and n.get('rml_loop', False):
-            oldctx = self.localcontext
-            for ctx in safe_eval(n.get('rml_loop'),{}, self.localcontext):
-                self.localcontext.update(ctx)
-                if (tagname is None) or (n.tag==tagname):
-                    if n.get('rml_except', False):
-                        try:
-                            safe_eval(n.get('rml_except'), {}, self.localcontext)
-                        except Exception:
-                            continue
-                    if n.get('rml_tag'):
-                        try:
-                            (tag,attr) = safe_eval(n.get('rml_tag'),{}, self.localcontext)
-                            n2 = copy.copy(n)
-                            n2.tag = tag
-                            n2.attrib.update(attr)
-                            yield n2
-                        except Exception:
-                            yield n
-                    else:
-                        yield n
-            self.localcontext = oldctx
-            continue
-        if self and self.localcontext and n.get('rml_except', False):
-            try:
-                safe_eval(n.get('rml_except'), {}, self.localcontext)
-            except Exception:
-                continue
-        if (tagname is None) or (n.tag==tagname):
-            yield n
-
-def _process_text(self, txt):
-        if not self.localcontext:
-            return txt
-        if not txt:
-            return ''
-        result = ''
-        sps = _regex.split(txt)
-        while sps:
-            # This is a simple text to translate
-            result += self.localcontext.get('translate', lambda x:x)(sps.pop(0))
-            if sps:
-                try:
-                    txt2 = safe_eval(sps.pop(0),self.localcontext)
-                except Exception:
-                    txt2 = ''
-                if isinstance(txt2, (int, float)):
-                    txt2 = str(txt2)
-                if isinstance(txt2, basestring):
-                    result += txt2
-        return result
-
-def text_get(node):
-    rc = ''
-    for node in node.getchildren():
-            rc = rc + node.text
-    return rc
-
-units = [
-    (re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
-    (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
-    (re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
-    (re.compile('^(-?[0-9\.]+)\s*$'), 1)
-]
-
-def unit_get(size):
-    global units
-    if size:
-        for unit in units:
-            res = unit[0].search(size, 0)
-            if res:
-                return unit[1]*float(res.group(1))
-    return False
-
-def tuple_int_get(node, attr_name, default=None):
-    if not node.get(attr_name):
-        return default
-    res = [int(x) for x in node.get(attr_name).split(',')]
-    return res
-
-def bool_get(value):
-    return (str(value)=="1") or (value.lower()=='yes')
-
-def attr_get(node, attrs, dict=None):
-    if dict is None:
-        dict = {}
-    res = {}
-    for name in attrs:
-        if node.get(name):
-            res[name] = unit_get(node.get(name))
-    for key in dict:
-        if node.get(key):
-            if dict[key]=='str':
-                res[key] = str(node.get(key))
-            elif dict[key]=='bool':
-                res[key] = bool_get(node.get(key))
-            elif dict[key]=='int':
-                res[key] = int(node.get(key))
-            elif dict[key]=='unit':
-                res[key] = unit_get(node.get(key))
-    return res
diff --git a/odoo/report/render/simple.py b/odoo/report/render/simple.py
deleted file mode 100644
index 07584f11914f356361d1081d3a0ef9dfdd16186a..0000000000000000000000000000000000000000
--- a/odoo/report/render/simple.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import copy
-import xml.dom.minidom
-from cStringIO import StringIO
-
-import reportlab.lib
-from reportlab.platypus import SimpleDocTemplate, Paragraph
-from reportlab.lib.units import mm
-from reportlab.lib.pagesizes import A4
-
-from . import render
-
-
-class simple(render.render):
-    def _render(self):
-        self.result = StringIO()
-        parser = xml.dom.minidom.parseString(self.xml)
-
-        title = parser.documentElement.tagName
-        doc = SimpleDocTemplate(self.result, pagesize=A4, title=title,
-          author='Odoo, Fabien Pinckaers', leftmargin=10*mm, rightmargin=10*mm)
-
-        styles = reportlab.lib.styles.getSampleStyleSheet()
-        title_style = copy.deepcopy(styles["Heading1"])
-        title_style.alignment = reportlab.lib.enums.TA_CENTER
-        story = [ Paragraph(title, title_style) ]
-        style_level = {}
-        nodes = [ (parser.documentElement,0) ]
-        while len(nodes):
-            node = nodes.pop(0)
-            value = ''
-            n=len(node[0].childNodes)-1
-            while n>=0:
-                if node[0].childNodes[n].nodeType==3:
-                    value += node[0].childNodes[n].nodeValue
-                else:
-                    nodes.insert( 0, (node[0].childNodes[n], node[1]+1) )
-                n-=1
-            if not node[1] in style_level:
-                style = copy.deepcopy(styles["Normal"])
-                style.leftIndent=node[1]*6*mm
-                style.firstLineIndent=-3*mm
-                style_level[node[1]] = style
-            story.append( Paragraph('<b>%s</b>: %s' % (node[0].tagName, value), style_level[node[1]]))
-        doc.build(story)
-        return self.result.getvalue()
-
-if __name__=='__main__':
-    s = simple()
-    s.xml = '''<test>
-        <author-list>
-            <author>
-                <name>Fabien Pinckaers</name>
-                <age>23</age>
-            </author>
-            <author>
-                <name>Michel Pinckaers</name>
-                <age>53</age>
-            </author>
-            No other
-        </author-list>
-    </test>'''
-    if s.render():
-        print s.get()
diff --git a/odoo/report/report_sxw.py b/odoo/report/report_sxw.py
deleted file mode 100644
index e54ecad953ed45d785d5bfb75d3c78260b971ce9..0000000000000000000000000000000000000000
--- a/odoo/report/report_sxw.py
+++ /dev/null
@@ -1,611 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-import base64
-import cStringIO
-import logging
-import os
-import re
-import StringIO
-import time
-import zipfile
-from datetime import datetime
-
-from lxml import etree
-
-import odoo
-import odoo.tools as tools
-from . import common
-from . import preprocess
-from .interface import report_rml
-from odoo import fields
-from odoo.exceptions import AccessError
-from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
-from odoo.tools.safe_eval import safe_eval
-from odoo.tools.translate import _
-
-
-_logger = logging.getLogger(__name__)
-
-rml_parents = {
-    'tr':1,
-    'li':1,
-    'story': 0,
-    'section': 0
-}
-
-rml_tag="para"
-
-sxw_parents = {
-    'table-row': 1,
-    'list-item': 1,
-    'body': 0,
-    'section': 0,
-}
-
-html_parents = {
-    'tr' : 1,
-    'body' : 0,
-    'div' : 0
-    }
-sxw_tag = "p"
-
-rml2sxw = {
-    'para': 'p',
-}
-
-def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
-    return len((datetime.now()).strftime(date_format))
-
-
-class rml_parse(object):
-    def __init__(self, cr, uid, name, parents=rml_parents, tag=rml_tag, context=None):
-        if not context:
-            context = {}
-        self.cr = cr
-        self.uid = uid
-        env = odoo.api.Environment(cr, uid, context)
-        user = env['res.users'].browse(uid)
-        self.localcontext = {
-            'user': user,
-            'setCompany': self.setCompany,
-            'repeatIn': self.repeatIn,
-            'setLang': self.setLang,
-            'setTag': self.setTag,
-            'removeParentNode': self.removeParentNode,
-            'format': self.format,
-            'formatLang': self.formatLang,
-            'lang' : user.company_id.partner_id.lang,
-            'translate' : self._translate,
-            'setHtmlImage' : self.set_html_image,
-            'strip_name' : self._strip_name,
-            'time' : time,
-            'display_address': self.display_address,
-            # more context members are setup in setCompany() below:
-            #  - company_id
-            #  - logo
-        }
-        self.setCompany(user.company_id)
-        self.localcontext.update(context)
-        self.name = name
-        self._node = None
-        self.parents = parents
-        self.tag = tag
-        self._lang_cache = {}
-        self.lang_dict = {}
-        self.default_lang = {}
-        self.lang_dict_called = False
-        self._transl_regex = re.compile(r'(\[\[.+?\]\])')
-
-    def setTag(self, oldtag, newtag, attrs=None):
-        return newtag, attrs
-
-    def _ellipsis(self, char, size=100, truncation_str='...'):
-        if not char:
-            return ''
-        if len(char) <= size:
-            return char
-        return char[:size-len(truncation_str)] + truncation_str
-
-    def setCompany(self, company_id):
-        if company_id:
-            self.localcontext['company'] = company_id
-            self.localcontext['logo'] = company_id.logo
-            self.rml_header = company_id.rml_header
-            self.rml_header2 = company_id.rml_header2
-            self.rml_header3 = company_id.rml_header3
-            self.logo = company_id.logo
-
-    def _strip_name(self, name, maxlen=50):
-        return self._ellipsis(name, maxlen)
-
-    def format(self, text, oldtag=None):
-        return text.strip()
-
-    def removeParentNode(self, tag=None):
-        raise GeneratorExit('Skip')
-
-    def set_html_image(self, id, model=None, field=None, context=None):
-        if not id:
-            return ''
-        if not model:
-            model = 'ir.attachment'
-        try:
-            env = odoo.api.Environment(self.cr, self.uid, {})
-            res = env[model].browse(int(id)).read()[0]
-            if field:
-                return res[field]
-            elif model =='ir.attachment':
-                return res['datas']
-            else:
-                return ''
-        except Exception:
-            return ''
-
-    def setLang(self, lang):
-        self.localcontext['lang'] = lang
-        self.lang_dict_called = False
-        # re-evaluate self.objects in a different environment
-        env = self.objects.env(self.cr, self.uid, self.localcontext)
-        self.objects = self.objects.with_env(env)
-
-    def _get_lang_dict(self):
-        env = odoo.api.Environment(self.cr, self.uid, {})
-        Lang = env['res.lang']
-        lang = self.localcontext.get('lang', 'en_US') or 'en_US'
-        lang_obj = Lang.search([('code', '=', lang)], limit=1) or \
-                   Lang.search([('code', '=', 'en_US')])
-        self.lang_dict.update({'lang_obj': lang_obj,
-                               'date_format': lang_obj.date_format,
-                               'time_format':lang_obj.time_format})
-        self.default_lang[lang] = self.lang_dict.copy()
-        return True
-
-    def digits_fmt(self, obj=None, f=None, dp=None):
-        digits = self.get_digits(obj, f, dp)
-        return "%%.%df" % (digits, )
-
-    def get_digits(self, obj=None, f=None, dp=None):
-        d = DEFAULT_DIGITS = 2
-        if dp:
-            env = odoo.api.Environment(self.cr, self.uid, {})
-            d = env['decimal.precision'].precision_get(dp)
-        elif obj and f:
-            res_digits = getattr(obj._fields[f], 'digits', lambda x: ((16, DEFAULT_DIGITS)))
-            if isinstance(res_digits, tuple):
-                d = res_digits[1]
-            else:
-                d = res_digits(self.cr)[1]
-        elif (hasattr(obj, '_field') and\
-                obj._field.type == 'float' and\
-                obj._field.digits):
-                d = obj._field.digits[1]
-                if not d and d is not 0:
-                    d = DEFAULT_DIGITS
-        return d
-
-    def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False, currency_obj=False):
-        if digits is None:
-            if dp:
-                digits = self.get_digits(dp=dp)
-            elif currency_obj:
-                digits = currency_obj.decimal_places
-            else:
-                digits = self.get_digits(value)
-
-        if isinstance(value, (str, unicode)) and not value:
-            return ''
-
-        if not self.lang_dict_called:
-            self._get_lang_dict()
-            self.lang_dict_called = True
-
-        if date or date_time:
-            if not value:
-                return ''
-
-            date_format = self.lang_dict['date_format']
-            parse_format = DEFAULT_SERVER_DATE_FORMAT
-            if date_time:
-                value = value.split('.')[0]
-                date_format = date_format + " " + self.lang_dict['time_format']
-                parse_format = DEFAULT_SERVER_DATETIME_FORMAT
-            if isinstance(value, basestring):
-                # FIXME: the trimming is probably unreliable if format includes day/month names
-                #        and those would need to be translated anyway.
-                date = datetime.strptime(value[:get_date_length(parse_format)], parse_format)
-            elif isinstance(value, time.struct_time):
-                date = datetime(*value[:6])
-            else:
-                date = datetime(*value.timetuple()[:6])
-            if date_time:
-                # Convert datetime values to the expected client/context timezone
-                record = self.env['base'].with_context(self.localcontext)
-                date = fields.Datetime.context_timestamp(record, date)
-            return date.strftime(date_format.encode('utf-8'))
-
-        res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
-        if currency_obj and currency_obj.symbol:
-            if currency_obj.position == 'after':
-                res = u'%s\N{NO-BREAK SPACE}%s' % (res, currency_obj.symbol)
-            elif currency_obj and currency_obj.position == 'before':
-                res = u'%s\N{NO-BREAK SPACE}%s' % (currency_obj.symbol, res)
-        return res
-
-    def display_address(self, address_record, without_company=False):
-        # FIXME handle `without_company`
-        return address_record.contact_address
-
-    def repeatIn(self, lst, name,nodes_parent=False):
-        ret_lst = []
-        for id in lst:
-            ret_lst.append({name:id})
-        return ret_lst
-
-    def _translate(self,text):
-        lang = self.localcontext['lang']
-        if lang and text and not text.isspace():
-            env = odoo.api.Environment(self.cr, self.uid, {})
-            Translation = env['ir.translation']
-            piece_list = self._transl_regex.split(text)
-            for pn in range(len(piece_list)):
-                if not self._transl_regex.match(piece_list[pn]):
-                    source_string = piece_list[pn].replace('\n', ' ').strip()
-                    if len(source_string):
-                        translated_string = Translation._get_source(self.name, ('report', 'rml'), lang, source_string)
-                        if translated_string:
-                            piece_list[pn] = piece_list[pn].replace(source_string, translated_string)
-            text = ''.join(piece_list)
-        return text
-
-    def _add_header(self, rml_dom, header='external'):
-        if header=='internal':
-            rml_head =  self.rml_header2
-        elif header=='internal landscape':
-            rml_head =  self.rml_header3
-        else:
-            rml_head =  self.rml_header
-
-        head_dom = etree.XML(rml_head)
-        for tag in head_dom:
-            found = rml_dom.find('.//'+tag.tag)
-            if found is not None and len(found):
-                if tag.get('position'):
-                    found.append(tag)
-                else :
-                    found.getparent().replace(found,tag)
-        return True
-
-    def set_context(self, objects, data, ids, report_type=None):
-        self.localcontext['data'] = data
-        self.localcontext['objects'] = objects
-        self.localcontext['digits_fmt'] = self.digits_fmt
-        self.localcontext['get_digits'] = self.get_digits
-        self.datas = data
-        self.ids = ids
-        self.objects = objects
-        if report_type:
-            if report_type=='odt' :
-                self.localcontext.update({'name_space' :common.odt_namespace})
-            else:
-                self.localcontext.update({'name_space' :common.sxw_namespace})
-
-        # WARNING: the object[0].exists() call below is slow but necessary because
-        # some broken reporting wizards pass incorrect IDs (e.g. ir.ui.menu ids)
-        if objects and len(objects) == 1 and \
-            objects[0].exists() and 'company_id' in objects[0] and objects[0].company_id:
-            # When we print only one record, we can auto-set the correct
-            # company in the localcontext. For other cases the report
-            # will have to call setCompany() inside the main repeatIn loop.
-            self.setCompany(objects[0].company_id)
-
-
-class report_sxw(report_rml, preprocess.report):
-    """
-    The register=True kwarg has been added to help remove the
-    odoo.netsvc.LocalService() indirection and the related
-    odoo.report.interface.report_int._reports dictionary:
-    report_sxw registered in XML with auto=False are also registered in Python.
-    In that case, they are registered in the above dictionary. Since
-    registration is automatically done upon instanciation, and that
-    instanciation is needed before rendering, a way was needed to
-    instanciate-without-register a report. In the future, no report
-    should be registered in the above dictionary and it will be dropped.
-    """
-    def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True):
-        report_rml.__init__(self, name, table, rml, '', register=register)
-        self.name = name
-        self.parser = parser
-        self.header = header
-        self.store = store
-        self.internal_header=False
-        if header=='internal' or header=='internal landscape':
-            self.internal_header=True
-
-    def getObjects(self, cr, uid, ids, context):
-        env = odoo.api.Environment(cr, uid, context or {})
-        return env[self.table].browse(ids)
-
-    def create(self, cr, uid, ids, data, context=None):
-        context = dict(context or {})
-        if self.internal_header:
-            context.update(internal_header=self.internal_header)
-
-        context.update(bin_raw=True)
-        env = odoo.api.Environment(cr, uid, context)
-        env['res.font'].sudo().font_scan(lazy=True)
-        ir_obj = env['ir.actions.report.xml']
-
-        report_xml = ir_obj.search([('report_name', '=', self.name[7:])], limit=1)
-        if not report_xml:
-            title = ''
-            report_file = tools.file_open(self.tmpl, subdir=None)
-            try:
-                rml = report_file.read()
-                report_type= data.get('report_type', 'pdf')
-                class a(object):
-                    def __init__(self, *args, **argv):
-                        for key,arg in argv.items():
-                            setattr(self, key, arg)
-                report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header)
-            finally:
-                report_file.close()
-
-        # We add an attribute on the ir.actions.report.xml instance.
-        # This attribute 'use_global_header' will be used by
-        # the create_single_XXX function of the report engine.
-        # This change has been done to avoid a big change of the API.
-        setattr(report_xml, 'use_global_header', self.header if report_xml.header else False)
-
-        report_type = report_xml.report_type
-        if report_type in ['sxw','odt']:
-            fnct = self.create_source_odt
-        elif report_type in ['pdf','raw','txt','html']:
-            fnct = self.create_source_pdf
-        elif report_type=='html2html':
-            fnct = self.create_source_html2html
-        elif report_type=='mako2html':
-            fnct = self.create_source_mako2html
-        else:
-            raise NotImplementedError(_('Unknown report type: %s') % report_type)
-        fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
-        if not fnct_ret:
-            return False, False
-        return fnct_ret
-
-    def create_source_odt(self, cr, uid, ids, data, report_xml, context=None):
-        return self.create_single_odt(cr, uid, ids, data, report_xml, context or {})
-
-    def create_source_html2html(self, cr, uid, ids, data, report_xml, context=None):
-        return self.create_single_html2html(cr, uid, ids, data, report_xml, context or {})
-
-    def create_source_mako2html(self, cr, uid, ids, data, report_xml, context=None):
-        return self.create_single_mako2html(cr, uid, ids, data, report_xml, context or {})
-
-    def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None):
-        if not context:
-            context = {}
-        env = odoo.api.Environment(cr, uid, context)
-        attach = report_xml.attachment
-        if attach:
-            objs = self.getObjects(cr, uid, ids, context)
-            results = []
-            for obj in objs:
-                aname = safe_eval(attach, {'object':obj, 'time':time})
-                result = False
-                if report_xml.attachment_use and aname and context.get('attachment_use', True):
-                    att = env['ir.attachment'].search([('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)], limit=1)
-                    if att:
-                        if not att.datas:
-                            continue
-                        d = base64.decodestring(att.datas)
-                        results.append((d,'pdf'))
-                        continue
-                result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context)
-                if not result:
-                    return False
-                if aname:
-                    try:
-                        name = aname+'.'+result[1]
-                        # Remove the default_type entry from the context: this
-                        # is for instance used on the account.account_invoices
-                        # and is thus not intended for the ir.attachment type
-                        # field.
-                        ctx = dict(context)
-                        ctx.pop('default_type', None)
-                        env['ir.attachment'].with_context(ctx).create({
-                            'name': aname,
-                            'datas': base64.encodestring(result[0]),
-                            'datas_fname': name,
-                            'res_model': self.table,
-                            'res_id': obj.id,
-                        })
-                    except AccessError:
-                        #TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632
-                        _logger.info('Could not create saved report attachment', exc_info=True)
-                results.append(result)
-            if results:
-                if results[0][1]=='pdf':
-                    from pyPdf import PdfFileWriter, PdfFileReader
-                    output = PdfFileWriter()
-                    for r in results:
-                        reader = PdfFileReader(cStringIO.StringIO(r[0]))
-                        for page in range(reader.getNumPages()):
-                            output.addPage(reader.getPage(page))
-                    s = cStringIO.StringIO()
-                    output.write(s)
-                    return s.getvalue(), results[0][1]
-        return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
-
-    def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
-        if not context:
-            context={}
-        logo = None
-        context = context.copy()
-        title = report_xml.name
-        rml = report_xml.report_rml_content
-        # if no rml file is found
-        if not rml:
-            return False
-        rml_parser = self.parser(cr, uid, self.name2, context=context)
-        objs = self.getObjects(cr, uid, ids, context)
-        rml_parser.set_context(objs, data, ids, report_xml.report_type)
-        processed_rml = etree.XML(rml)
-        if report_xml.use_global_header:
-            rml_parser._add_header(processed_rml, self.header)
-        processed_rml = self.preprocess_rml(processed_rml,report_xml.report_type)
-        if rml_parser.logo:
-            logo = base64.decodestring(rml_parser.logo)
-        create_doc = self.generators[report_xml.report_type]
-        pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8'))
-        return pdf, report_xml.report_type
-
-    def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
-        context = dict(context or {})
-        context['parents'] = sxw_parents
-        report_type = report_xml.report_type
-        binary_report_content = report_xml.report_sxw_content
-        if isinstance(report_xml.report_sxw_content, unicode):
-            # if binary content was passed as unicode, we must
-            # re-encode it as a 8-bit string using the pass-through
-            # 'latin1' encoding, to restore the original byte values.
-            binary_report_content = report_xml.report_sxw_content.encode("latin1")
-
-        sxw_io = StringIO.StringIO(binary_report_content)
-        sxw_z = zipfile.ZipFile(sxw_io, mode='r')
-        rml = sxw_z.read('content.xml')
-        meta = sxw_z.read('meta.xml')
-        mime_type = sxw_z.read('mimetype')
-        if mime_type == 'application/vnd.sun.xml.writer':
-            mime_type = 'sxw'
-        else :
-            mime_type = 'odt'
-        sxw_z.close()
-
-        rml_parser = self.parser(cr, uid, self.name2, context=context)
-        rml_parser.parents = sxw_parents
-        rml_parser.tag = sxw_tag
-        objs = self.getObjects(cr, uid, ids, context)
-        rml_parser.set_context(objs, data, ids, mime_type)
-
-        rml_dom_meta = node = etree.XML(meta)
-        elements = node.findall(rml_parser.localcontext['name_space']["meta"]+"user-defined")
-        for pe in elements:
-            if pe.get(rml_parser.localcontext['name_space']["meta"]+"name"):
-                if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 3":
-                    pe[0].text=data['id']
-                if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 4":
-                    pe[0].text=data['model']
-        meta = etree.tostring(rml_dom_meta, encoding='utf-8',
-                              xml_declaration=True)
-
-        rml_dom =  etree.XML(rml)
-        elements = []
-        key1 = rml_parser.localcontext['name_space']["text"]+"p"
-        key2 = rml_parser.localcontext['name_space']["text"]+"drop-down"
-        for n in rml_dom.iterdescendants():
-            if n.tag == key1:
-                elements.append(n)
-        if mime_type == 'odt':
-            for pe in elements:
-                e = pe.findall(key2)
-                for de in e:
-                    pp=de.getparent()
-                    if de.text or de.tail:
-                        pe.text = de.text or de.tail
-                    for cnd in de:
-                        if cnd.text or cnd.tail:
-                            if pe.text:
-                                pe.text +=  cnd.text or cnd.tail
-                            else:
-                                pe.text =  cnd.text or cnd.tail
-                            pp.remove(de)
-        else:
-            for pe in elements:
-                e = pe.findall(key2)
-                for de in e:
-                    pp = de.getparent()
-                    if de.text or de.tail:
-                        pe.text = de.text or de.tail
-                    for cnd in de:
-                        text = cnd.get("{http://openoffice.org/2000/text}value",False)
-                        if text:
-                            if pe.text and text.startswith('[['):
-                                pe.text +=  text
-                            elif text.startswith('[['):
-                                pe.text =  text
-                            if de.getparent():
-                                pp.remove(de)
-
-        rml_dom = self.preprocess_rml(rml_dom, mime_type)
-        create_doc = self.generators[mime_type]
-        odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext),
-                             encoding='utf-8', xml_declaration=True)
-        sxw_contents = {'content.xml':odt, 'meta.xml':meta}
-
-        if report_xml.use_global_header:
-            #Add corporate header/footer
-            rml_file = tools.file_open(os.path.join('base', 'report', 'corporate_%s_header.xml' % report_type))
-            try:
-                rml = rml_file.read()
-                rml_parser = self.parser(cr, uid, self.name2, context=context)
-                rml_parser.parents = sxw_parents
-                rml_parser.tag = sxw_tag
-                objs = self.getObjects(cr, uid, ids, context)
-                rml_parser.set_context(objs, data, ids, report_xml.report_type)
-                rml_dom = self.preprocess_rml(etree.XML(rml),report_type)
-                create_doc = self.generators[report_type]
-                odt = create_doc(rml_dom,rml_parser.localcontext)
-                if report_xml.use_global_header:
-                    rml_parser._add_header(odt)
-                odt = etree.tostring(odt, encoding='utf-8',
-                                     xml_declaration=True)
-                sxw_contents['styles.xml'] = odt
-            finally:
-                rml_file.close()
-
-        #created empty zip writing sxw contents to avoid duplication
-        sxw_out = StringIO.StringIO()
-        sxw_out_zip = zipfile.ZipFile(sxw_out, mode='w')
-        sxw_template_zip = zipfile.ZipFile (sxw_io, 'r')
-        for item in sxw_template_zip.infolist():
-            if item.filename not in sxw_contents:
-                buffer = sxw_template_zip.read(item.filename)
-                sxw_out_zip.writestr(item.filename, buffer)
-        for item_filename, buffer in sxw_contents.iteritems():
-            sxw_out_zip.writestr(item_filename, buffer)
-        sxw_template_zip.close()
-        sxw_out_zip.close()
-        final_op = sxw_out.getvalue()
-        sxw_io.close()
-        sxw_out.close()
-        return final_op, mime_type
-
-    def create_single_html2html(self, cr, uid, ids, data, report_xml, context=None):
-        context = dict(context or {})
-        context['parents'] = html_parents
-        report_type = 'html'
-
-        html = report_xml.report_rml_content
-        html_parser = self.parser(cr, uid, self.name2, context=context)
-        html_parser.parents = html_parents
-        html_parser.tag = sxw_tag
-        objs = self.getObjects(cr, uid, ids, context)
-        html_parser.set_context(objs, data, ids, report_type)
-
-        html_dom =  etree.HTML(html)
-        html_dom = self.preprocess_rml(html_dom,'html2html')
-
-        create_doc = self.generators['html2html']
-        html = etree.tostring(create_doc(html_dom, html_parser.localcontext))
-
-        return html.replace('&amp;','&').replace('&lt;', '<').replace('&gt;', '>').replace('</br>',''), report_type
-
-    def create_single_mako2html(self, cr, uid, ids, data, report_xml, context=None):
-        mako_html = report_xml.report_rml_content
-        html_parser = self.parser(cr, uid, self.name2, context)
-        objs = self.getObjects(cr, uid, ids, context)
-        html_parser.set_context(objs, data, ids, 'html')
-        create_doc = self.generators['makohtml2html']
-        html = create_doc(mako_html,html_parser.localcontext)
-        return html,'html'
diff --git a/odoo/service/__init__.py b/odoo/service/__init__.py
index 5d61b35f0e4801b55d01d8e57bf92ab7c2c75339..3b9f417e273b922e88d150107339766971aff9e7 100644
--- a/odoo/service/__init__.py
+++ b/odoo/service/__init__.py
@@ -4,7 +4,6 @@
 from . import common
 from . import db
 from . import model
-from . import report
 from . import wsgi_server
 from . import server
 
diff --git a/odoo/service/report.py b/odoo/service/report.py
deleted file mode 100644
index 8229a2396e4bf260fbd50dcd429771b1de3bf1c2..0000000000000000000000000000000000000000
--- a/odoo/service/report.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import base64
-import logging
-import sys
-import threading
-
-import odoo
-import odoo.report
-from odoo import tools
-from odoo.exceptions import UserError
-
-from . import security
-
-_logger = logging.getLogger(__name__)
-
-# TODO: set a maximum report number per user to avoid DOS attacks
-#
-# Report state:
-#     False -> True
-
-self_reports = {}
-self_id = 0
-self_id_protect = threading.Semaphore()
-
-def dispatch(method, params):
-    (db, uid, passwd ) = params[0:3]
-    threading.current_thread().uid = uid
-    params = params[3:]
-    if method not in ['report', 'report_get', 'render_report']:
-        raise KeyError("Method not supported %s" % method)
-    security.check(db,uid,passwd)
-    registry = odoo.registry(db).check_signaling()
-    fn = globals()['exp_' + method]
-    with registry.manage_changes():
-        res = fn(db, uid, *params)
-    return res
-
-def exp_render_report(db, uid, object, ids, datas=None, context=None):
-    if not datas:
-        datas={}
-    if not context:
-        context={}
-
-    self_id_protect.acquire()
-    global self_id
-    self_id += 1
-    id = self_id
-    self_id_protect.release()
-
-    self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
-
-    cr = odoo.registry(db).cursor()
-    try:
-        result, format = odoo.report.render_report(cr, uid, ids, object, datas, context)
-        if not result:
-            tb = sys.exc_info()
-            self_reports[id]['exception'] = odoo.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
-        self_reports[id]['result'] = result
-        self_reports[id]['format'] = format
-        self_reports[id]['state'] = True
-    except Exception as exception:
-
-        _logger.exception('Exception: %s\n', exception)
-        if hasattr(exception, 'name') and hasattr(exception, 'value'):
-            self_reports[id]['exception'] = odoo.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
-        else:
-            tb = sys.exc_info()
-            self_reports[id]['exception'] = odoo.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
-        self_reports[id]['state'] = True
-    cr.commit()
-    cr.close()
-
-    return _check_report(id)
-
-def exp_report(db, uid, object, ids, datas=None, context=None):
-    if not datas:
-        datas={}
-    if not context:
-        context={}
-
-    self_id_protect.acquire()
-    global self_id
-    self_id += 1
-    id = self_id
-    self_id_protect.release()
-
-    self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
-
-    def go(id, uid, ids, datas, context):
-        with odoo.api.Environment.manage():
-            cr = odoo.registry(db).cursor()
-            try:
-                result, format = odoo.report.render_report(cr, uid, ids, object, datas, context)
-                if not result:
-                    tb = sys.exc_info()
-                    self_reports[id]['exception'] = odoo.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
-                self_reports[id]['result'] = result
-                self_reports[id]['format'] = format
-                self_reports[id]['state'] = True
-            except Exception as exception:
-                _logger.exception('Exception: %s\n', exception)
-                if hasattr(exception, 'name') and hasattr(exception, 'value'):
-                    self_reports[id]['exception'] = odoo.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
-                else:
-                    tb = sys.exc_info()
-                    self_reports[id]['exception'] = odoo.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
-                self_reports[id]['state'] = True
-            cr.commit()
-            cr.close()
-        return True
-
-    threading.Thread(target=go, args=(id, uid, ids, datas, context)).start()
-    return id
-
-def _check_report(report_id):
-    result = self_reports[report_id]
-    exc = result['exception']
-    if exc:
-        raise UserError('%s: %s' % (exc.message, exc.traceback))
-    res = {'state': result['state']}
-    if res['state']:
-        if tools.config['reportgz']:
-            import zlib
-            res2 = zlib.compress(result['result'])
-            res['code'] = 'zlib'
-        else:
-            #CHECKME: why is this needed???
-            if isinstance(result['result'], unicode):
-                res2 = result['result'].encode('latin1', 'replace')
-            else:
-                res2 = result['result']
-        if res2:
-            res['result'] = base64.encodestring(res2)
-        res['format'] = result['format']
-        del self_reports[report_id]
-    return res
-
-def exp_report_get(db, uid, report_id):
-    if report_id in self_reports:
-        if self_reports[report_id]['uid'] == uid:
-            return _check_report(report_id)
-        else:
-            raise Exception('AccessDenied')
-    else:
-        raise Exception('ReportNotFound')
diff --git a/odoo/tools/amount_to_text_en.py b/odoo/tools/amount_to_text_en.py
index 7a7fb5c2ef3f087877b1021864c284337ad83d38..6a8e7020b4a81e8b2bca56e36f33fa562d0c8145 100644
--- a/odoo/tools/amount_to_text_en.py
+++ b/odoo/tools/amount_to_text_en.py
@@ -89,11 +89,6 @@ def amount_to_text(nbr, lang='en', currency='euro'):
         
             1654: thousands six cent cinquante-quatre.
     """
-    import odoo.loglevels as loglevels
-#    if nbr > 10000000:
-#        _logger.warning(_("Number too large '%d', can not translate it"))
-#        return str(nbr)
-    
     if lang not in _translate_funcs:
         _logger.warning(_("no translation function found for lang: '%s'"), lang)
         #TODO: (default should be en) same as above
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index 2dd45699edbeef1233b7a94089a78e476738d19a..815ee9a64f1b60c8f187ece8c40090e9c9e65d6f 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -285,16 +285,12 @@ form: module.record_id""" % (xml_id,)
         for dest,f in (('name','string'),('model','model'),('report_name','name')):
             res[dest] = rec.get(f,'').encode('utf8')
             assert res[dest], "Attribute %s of report is empty !" % (f,)
-        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),
-                           ('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'),
-                           ('report_type', 'report_type'), ('parser', 'parser')):
+        for field,dest in (('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'),
+                           ('file', 'report_file'), ('report_type', 'report_type'), ('parser', 'parser')):
             if rec.get(field):
                 res[dest] = rec.get(field).encode('utf8')
         if rec.get('auto'):
             res['auto'] = safe_eval(rec.get('auto','False'))
-        if rec.get('sxw'):
-            sxw_content = file_open(rec.get('sxw')).read()
-            res['report_sxw_content'] = sxw_content
         if rec.get('header'):
             res['header'] = safe_eval(rec.get('header','False'))
 
@@ -319,19 +315,19 @@ form: module.record_id""" % (xml_id,)
             pf_id = self.id_get(pf_name)
             res['paperformat_id'] = pf_id
 
-        id = self.env['ir.model.data']._update("ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
+        id = self.env['ir.model.data']._update("ir.actions.report", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
         self.idref[xml_id] = int(id)
 
         if not rec.get('menu') or safe_eval(rec.get('menu','False')):
             keyword = str(rec.get('keyword', 'client_print_multi'))
-            value = 'ir.actions.report.xml,'+str(id)
+            value = 'ir.actions.report,'+str(id)
             action = self.env['ir.values'].set_action(res['name'], keyword, res['model'], value)
-            self.env['ir.actions.report.xml'].browse(id).write({'ir_values_id': action.id})
+            self.env['ir.actions.report'].browse(id).write({'ir_values_id': action.id})
         elif self.mode=='update' and safe_eval(rec.get('menu','False'))==False:
             # Special check for report having attribute menu=False on update
-            value = 'ir.actions.report.xml,'+str(id)
+            value = 'ir.actions.report,'+str(id)
             self._remove_ir_values(res['name'], value, res['model'])
-            self.env['ir.actions.report.xml'].browse(id).write({'ir_values_id': False})
+            self.env['ir.actions.report'].browse(id).write({'ir_values_id': False})
         return id
 
     def _tag_function(self, rec, data_node=None, mode=None):
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py
index 4c570e7cc87bfc3c2c4b853d08da8164d9249068..492be9951e429effc16c5a01c95375dbb8eef379 100644
--- a/odoo/tools/misc.py
+++ b/odoo/tools/misc.py
@@ -154,7 +154,6 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
     
     >>> file_open('hr/report/timesheer.xsl')
     >>> file_open('addons/hr/report/timesheet.xsl')
-    >>> file_open('../../base/report/rml_template.xsl', subdir='addons/hr/report', pathinfo=True)
 
     @param name name of the file
     @param mode file open mode
diff --git a/odoo/tools/test_reports.py b/odoo/tools/test_reports.py
index c1f9af8bb550e6bb07fdfd25befc59489c70c1b3..17065848129b77ef964ecb862cc478c9b72e9c80 100644
--- a/odoo/tools/test_reports.py
+++ b/odoo/tools/test_reports.py
@@ -8,7 +8,6 @@
 """
 
 import odoo
-import odoo.report
 import odoo.tools as tools
 import logging
 
@@ -24,24 +23,20 @@ _test_logger = logging.getLogger('odoo.tests')
 
 def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, report_type=None):
     """ Try to render a report <rname> with contents of ids
-    
+
         This function should also check for common pitfalls of reports.
     """
-    if data is None:
-        data = {}
     if context is None:
         context = {}
-    if rname.startswith('report.'):
-        rname_s = rname[7:]
-    else:
-        rname_s = rname
     _test_logger.info("  - Trying %s.create(%r)", rname, ids)
 
-    res = odoo.report.render_report(cr, uid, ids, rname_s, data, context=context)
-    if not isinstance(res, tuple):
-        raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
-                                (rname, type(res)))
-    (res_data, res_format) = res
+    env = odoo.api.Environment(cr, uid, context)
+
+    report_id = env['ir.actions.report'].search([('report_name', '=', rname)], limit=1)
+    if not report_id:
+        raise Exception("Required report does not exist: %s" % rname)
+
+    res_data, res_format = report_id.render(ids, data=data)
 
     if not res_data:
         raise ValueError("Report %s produced an empty result!" % rname)
@@ -53,7 +48,6 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, re
     if res_format == 'pdf':
         if res_data[:5] != '%PDF-':
             raise ValueError("Report %s produced a non-pdf header, %r" % (rname, res_data[:10]))
-
         res_text = False
         try:
             fd, rfname = tempfile.mkstemp(suffix=res_format)
@@ -256,7 +250,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
                         action_name, b['string'], b['type'])
             return res
 
-        elif action['type']=='ir.actions.report.xml':
+        elif action['type']=='ir.actions.report':
             if 'window' in datas:
                 del datas['window']
             if not datas:
@@ -267,7 +261,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
             ids = datas.get('ids')
             if 'ids' in datas:
                 del datas['ids']
-            res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
+            res = try_report(cr, uid, action['report_name'], ids, datas, context, our_module=our_module)
             return res
         else:
             raise Exception("Cannot handle action of type %s" % act_model)
diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py
index 32299d6db14af47b0ceaa668414d6cd8768b225a..dcdb95d09554c66f68d39e8e6c89bf72e59dca57 100644
--- a/odoo/tools/translate.py
+++ b/odoo/tools/translate.py
@@ -860,24 +860,6 @@ def trans_generate(lang, modules, cr):
                 for dummy, val in field.selection:
                     push_translation(module, 'selection', name, 0, encode(val))
 
-        elif model=='ir.actions.report.xml':
-            name = encode(record.report_name)
-            fname = ""
-            if record.report_rml:
-                fname = record.report_rml
-                parse_func = trans_parse_rml
-                report_type = "report"
-            elif record.report_xsl:
-                continue
-            if fname and record.report_type in ('pdf', 'xsl'):
-                try:
-                    with file_open(fname) as report_file:
-                        d = etree.parse(report_file)
-                        for t in parse_func(d.iter()):
-                            push_translation(module, report_type, name, 0, t)
-                except (IOError, etree.XMLSyntaxError):
-                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
-
         for field_name, field in record._fields.iteritems():
             if field.translate:
                 name = model + "," + field_name
diff --git a/odoo/tools/yaml_import.py b/odoo/tools/yaml_import.py
index ad9a48e8a84a85d79114deeaa9ce921556b4f509..58e9a154a54af066a16668db3a7747b0df881d8f 100644
--- a/odoo/tools/yaml_import.py
+++ b/odoo/tools/yaml_import.py
@@ -793,18 +793,11 @@ class YamlInterpreter(object):
         for dest, f in (('name','string'), ('model','model'), ('report_name','name')):
             values[dest] = getattr(node, f)
             assert values[dest], "Attribute %s of report is empty !" % (f,)
-        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')):
+        for field,dest in (('file', 'report_file'), ('attachment','attachment'),('attachment_use','attachment_use')):
             if getattr(node, field):
                 values[dest] = getattr(node, field)
         if node.auto:
             values['auto'] = safe_eval(node.auto)
-        if node.sxw:
-            sxw_file = file_open(node.sxw)
-            try:
-                sxw_content = sxw_file.read()
-                values['report_sxw_content'] = sxw_content
-            finally:
-                sxw_file.close()
         if node.header:
             values['header'] = safe_eval(node.header)
         values['multi'] = node.multi and safe_eval(node.multi)
@@ -813,13 +806,13 @@ class YamlInterpreter(object):
 
         self._set_group_values(node, values)
 
-        id = self.sudo_env['ir.model.data']._update("ir.actions.report.xml", \
+        id = self.sudo_env['ir.model.data']._update("ir.actions.report", \
                 self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode)
         self.id_map[xml_id] = int(id)
 
         if not node.menu or safe_eval(node.menu):
             keyword = node.keyword or 'client_print_multi'
-            value = 'ir.actions.report.xml,%s' % id
+            value = 'ir.actions.report,%s' % id
             ir_values = self.env['ir.values']
             res_id = False
             model = values['model']
diff --git a/requirements.txt b/requirements.txt
index 05b1e1bf0e0ed1926a3479d7ff9e680ba42df5d4..23abdb04f1904c5ef7bc8243d9ea0dbd929c3611 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -23,7 +23,6 @@ pyldap==2.4.28
 pyparsing==2.1.10
 pyPdf==1.13
 pyserial==3.1.1
-Python-Chart==1.39
 python-dateutil==2.5.3
 python-openid==2.2.5
 pytz==2016.7
diff --git a/setup.py b/setup.py
index 5fd18a9995155a3518190e6c218c7194186068d3..2fce5faa39d7141b3d21961252612a5e165fd242 100644
--- a/setup.py
+++ b/setup.py
@@ -150,7 +150,6 @@ setup(
         'psutil',  # windows binary code.google.com/p/psutil/downloads/list
         'psycogreen',
         'psycopg2 >= 2.2',
-        'python-chart',
         'pydot',
         'pyldap',  # optional
         'pyparsing',