/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 *
 */
 
package org.eclipse.osbp.xtext.reportdsl.jvmmodel

import com.google.inject.Inject
import com.ibm.icu.util.ULocale
import com.vaadin.data.Container.Filter
import com.vaadin.server.Sizeable.Unit
import com.vaadin.server.StreamResource
import com.vaadin.ui.AbstractComponent
import com.vaadin.ui.BrowserFrame
import com.vaadin.ui.Button
import com.vaadin.ui.HorizontalLayout
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.util.ArrayList
import java.util.Locale
import java.util.UUID
import org.eclipse.birt.report.model.api.IDesignEngine
import org.eclipse.birt.report.model.api.OdaDataSetHandle
import org.eclipse.birt.report.model.api.StructureFactory
import org.eclipse.birt.report.model.api.command.ContentException
import org.eclipse.birt.report.model.api.command.CustomMsgException
import org.eclipse.birt.report.model.api.core.IModuleModel
import org.eclipse.birt.report.model.api.elements.structures.CachedMetaData
import org.eclipse.birt.report.model.api.elements.structures.ComputedColumn
import org.eclipse.birt.report.model.api.elements.structures.OdaResultSetColumn
import org.eclipse.birt.report.model.api.metadata.DimensionValue
import org.eclipse.birt.report.model.elements.interfaces.IDataSetModel
import org.eclipse.e4.core.di.extensions.EventUtils
import org.eclipse.e4.core.services.events.IEventBroker
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.osbp.dsl.entity.xtext.extensions.NamingExtensions
import org.eclipse.osbp.dsl.semantic.common.types.LPackage
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.eventbroker.EventBrokerMsg
import org.eclipse.osbp.ui.api.report.IReportProvider
import org.eclipse.osbp.utils.entityhelper.DataType
import org.eclipse.osbp.utils.vaadin.ViewLayoutManager
import org.eclipse.osbp.xtext.action.common.IToolbarAction
import org.eclipse.osbp.xtext.basic.generator.BasicDslGeneratorUtils
import org.eclipse.osbp.xtext.datamartdsl.DatamartCube
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity
import org.eclipse.osbp.xtext.datamartdsl.DatamartProperty
import org.eclipse.osbp.xtext.datamartdsl.DatamartRole
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask
import org.eclipse.osbp.xtext.datamartdsl.jvmmodel.DatamartDSLJvmModelInferrer
import org.eclipse.osbp.xtext.i18n.DSLOutputConfigurationProvider
import org.eclipse.osbp.xtext.i18n.I18NKeyGenerator
import org.eclipse.osbp.xtext.i18n.I18NModelGenerator
import org.eclipse.osbp.xtext.reportdsl.AutoText
import org.eclipse.osbp.xtext.reportdsl.DatamartTable
import org.eclipse.osbp.xtext.reportdsl.DatamartTableProperty
import org.eclipse.osbp.xtext.reportdsl.Element
import org.eclipse.osbp.xtext.reportdsl.Grid
import org.eclipse.osbp.xtext.reportdsl.Image
import org.eclipse.osbp.xtext.reportdsl.Label
import org.eclipse.osbp.xtext.reportdsl.PageFooter
import org.eclipse.osbp.xtext.reportdsl.PageHeader
import org.eclipse.osbp.xtext.reportdsl.PageTemplate
import org.eclipse.osbp.xtext.reportdsl.Report
import org.eclipse.osbp.xtext.reportdsl.ReportDesignTemplate
import org.eclipse.osbp.xtext.reportdsl.ReportModel
import org.eclipse.osbp.xtext.reportdsl.ReportPackage
import org.eclipse.osbp.xtext.reportdsl.Style
import org.eclipse.osbp.xtext.reportdsl.SubSubTitle
import org.eclipse.osbp.xtext.reportdsl.SubTitle
import org.eclipse.osbp.xtext.reportdsl.Text
import org.eclipse.osbp.xtext.reportdsl.Title
import org.eclipse.osbp.xtext.reportdsl.common.BaseReport
import org.eclipse.osbp.xtext.reportdsl.common.BirtEngine
import org.eclipse.osbp.xtext.reportdsl.common.DataTypes
import org.eclipse.osbp.xtext.reportdsl.common.OdaConnProperties
import org.eclipse.osbp.xtext.reportdsl.common.attribute.Attribute
import org.eclipse.osbp.xtext.reportdsl.common.attribute.Width
import org.eclipse.osbp.xtext.reportdsl.common.item.BodyItem
import org.eclipse.osbp.xtext.reportdsl.common.item.ContainerItem
import org.eclipse.osbp.xtext.reportdsl.common.item.GridItem
import org.eclipse.osbp.xtext.reportdsl.common.item.ImageItem
import org.eclipse.osbp.xtext.reportdsl.common.item.PageFooterItem
import org.eclipse.osbp.xtext.reportdsl.common.item.PageHeaderItem
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.compiler.GeneratorConfig
import org.eclipse.xtext.xbase.compiler.ImportManager
import org.osgi.service.event.Event
import org.osgi.service.event.EventHandler

class ReportModelGenerator extends I18NModelGenerator {
	@Inject extension IQualifiedNameProvider
	@Inject extension DatamartDSLJvmModelInferrer datamartInferrer
	@Inject extension NamingExtensions
	@Inject extension BasicDslGeneratorUtils
    
	@Inject
	@Extension
	private DataType dtType;
	
	static var designEngine = null
	
	override void doGenerate(Resource input, IFileSystemAccess fsa) {
		addTranslatables('''«BaseReport.CAPTION_I18NKEY_SAVE_PDF»,«BaseReport.CAPTION_I18NKEY_PRINT_PDF»''')
		super.doGenerate(input, fsa)
	}
	
	def dispatch void internalDoGenerate(ReportModel orgModel, IFileSystemAccess fsa) {
		designEngine = BirtEngine.createDesignEngine()
		for (pkg:orgModel.pckg) {
			for	(report : pkg.reports) {
				try {
					generateReportFile(pkg, report, fsa)
				}
				catch (Exception e) {
					e.printStackTrace
				}
			}
		}
   	}
   	
   	private def void generateReportFile(ReportPackage pckg, Report report, IFileSystemAccess fsa) {
   		if	(report.design instanceof ReportDesignTemplate) {
			generateReportRoleFile(pckg, report, null, fsa)
			for(role : report.datamartRef.roles) {
   				generateReportRoleFile(pckg, report, role, fsa)
			}
		}
	}
		
   	private def void generateReportRoleFile(ReportPackage pckg, Report report, DatamartRole role, IFileSystemAccess fsa) {
		var workSet = new ReportGeneratorWorkSet()
		workSet.generator = this
		workSet.report = report
		workSet.role = role
		// --- generate full path name to the report design file to be generated ---
		var template = report.design as ReportDesignTemplate
		var pckgName = pckg.fullyQualifiedName.toString
		var pckgNamePath = pckgName.replaceAll("\\.","/")
		var filename = '''«report.name»«IF role!=null»«role.assignedRole.name»«ENDIF».rptdesign'''
		var fullpath = '''«pckgNamePath»/«filename»'''

		// --- get managing BIRT instances ---
		var session = (designEngine as IDesignEngine).newSessionHandle(ULocale.forLocale(Locale.getDefault()))
		// --- Create a new report design ---
		workSet.design = session.createDesign()
		// --- The element factory creates instances of the various BIRT elements ---
		workSet.factory = workSet.design.getElementFactory()
		// set the i18n property resources
		workSet.design.setIncludeResource("i18n/I18N")
		// set the requested media for this report
		workSet.requestedMedia = report.media

		// --- generate a master page ---
		generateMasterPage(report.datamartRef, workSet, report.pageTemplate, template.header, template.footer)
		// --- add the master datamart ---
//		if	(report.datamartRef != null) {
		addDatamartSourceAndSet(report.datamartRef, workSet, null, null)
//		}
		
		var body = new BodyItem(workSet)
		generateItems(report.datamartRef, workSet, body, template.detail.elements)
		
		// --- generate an output stream to receive the BIRT generated report design ---			
		var baos = new ByteArrayOutputStream()
		try {
			workSet.design.getModule().prepareToSave();
			workSet.design.getModule().getWriter().write(baos);
			workSet.design.getModule().onSave();
		}
		catch (Exception e) {
			baos = new ByteArrayOutputStream()
			e.printStackTrace(new PrintStream(baos))
		}
		
		// --- generated output stream to the file --- 
		fsa.generateFile(fullpath, DSLOutputConfigurationProvider.DEFAULT_REPORT_OUTPUT, baos.toString())
   	}
	
//	def SessionHandle newSessionHandle(IDesignEngine engine, ULocale locale) {
//		return engine.newSessionHandle(locale)
//	}
	
	private def generateMasterPage(DatamartDefinition datamart, ReportGeneratorWorkSet workSet, PageTemplate pageTemplate, PageHeader pageHeader, PageFooter pageFooter) {
		// Note: The report will fail to load in the BIRT designer unless you create a master page.
		var header = pageHeader
		var footer = pageFooter
		if	(header == null) {
			header = pageTemplate.header
		}
		if	(footer == null) {
			footer = pageTemplate.footer
		}
		var masterPage = workSet.factory.newSimpleMasterPage(pageTemplate.name); //$NON-NLS-1$
		masterPage.setPageType(pageTemplate.size.name().toLowerCase);
		masterPage.setOrientation(pageTemplate.orientation.name().toLowerCase)
		masterPage.topMargin.setValue(new DimensionValue(pageTemplate.topMarginValue, pageTemplate.topMarginUnit.name().toLowerCase))
		masterPage.leftMargin.setValue(new DimensionValue(pageTemplate.leftMarginValue, pageTemplate.leftMarginUnit.name().toLowerCase))
		masterPage.bottomMargin.setValue(new DimensionValue(pageTemplate.bottomMarginValue, pageTemplate.bottomMarginUnit.name().toLowerCase))
		masterPage.rightMargin.setValue(new DimensionValue(pageTemplate.rightMarginValue, pageTemplate.rightMarginUnit.name().toLowerCase))
		if	(header != null) {
			masterPage.setShowHeaderOnFirst(header.showOnFirst)
			masterPage.headerHeight.setValue(new DimensionValue(header.heightValue, header.heightUnit.name().toLowerCase))
			generateItems(datamart, workSet, new PageHeaderItem(workSet, masterPage), header.elements)
		}
		if	(footer != null) {
			masterPage.setShowFooterOnLast(footer.showOnLast)
			masterPage.footerHeight.setValue(new DimensionValue(footer.heightValue, footer.heightUnit.name().toLowerCase))
			generateItems(datamart, workSet, new PageFooterItem(workSet, masterPage), footer.elements)
		}
		workSet.design.getMasterPages().add(masterPage);
	}
	
	private def addDatamartSourceAndSet(DatamartDefinition datamart, ReportGeneratorWorkSet workSet, String alias, DatamartProperty[] hiddens) {
		// --- generate the Data Source ---
		var dataSourceName = Utilities.getDataSourceName(alias, datamart).toString
		var odsourceh = workSet.factory.newOdaDataSource(dataSourceName, BaseReport.DATASOURCE_EXTENSION_ID);
		odsourceh.getElement().setID(workSet.design.getModule().getNextID());
		workSet.design.getModule().addElementID(odsourceh.getElement());
		workSet.design.getModule().add(odsourceh.getElement(), IModuleModel.DATA_SOURCE_SLOT);
		
		// --- generate the Data Set connected to the Data Source ---
		var dataSetName = Utilities.getDataSetName(alias, datamart).toString
		var odseth = workSet.factory.newOdaDataSet(dataSetName, BaseReport.DATASOURCE_EXTENSION_ID.concat(".dataSet"));
		workSet.dataSets.put(dataSetName, odseth)
		odseth.getElement().setID(workSet.design.getModule().getNextID());
		odseth.setProperty(OdaConnProperties.DATAMART_BUNDLENAME, Utilities.getBundleName(datamart));
		odseth.setProperty(OdaConnProperties.DATAMART_CLASSNAME, getDatamartClassName(alias, datamart));
		odseth.setProperty(OdaConnProperties.DATAMART_DATASOURCE, odsourceh.getElement().getName());
		odseth.setProperty(OdaConnProperties.DATAMART_DATASOURCENAME, dataSourceName);
		odseth.setProperty(OdaConnProperties.DATAMART_DATASETNAME, dataSetName);
		// --- add additional informations to the Data Set ---
		switch (datamart.source) {
			DatamartCube:
				addDatamartCubeResultSet(workSet, odseth, dataSetName, datamart)
			DatamartEntity:
				addDatamartEntityResultSet(workSet, odseth, dataSetName, datamart)
			DatamartTask:
				System.err.println("DatamartTask ... todo")
		}
		workSet.design.getModule().addElementID(odseth.getElement());
		workSet.design.getModule().add(odseth.getElement(), IModuleModel.DATA_SET_SLOT);
	}
	
	private def addDatamartCubeResultSet(ReportGeneratorWorkSet workSet, OdaDataSetHandle odseth, String dataSetName, DatamartDefinition datamart) {
		System.err.println("DatamartCube ... todo")
		
		var cube = datamart.source as DatamartCube;
		var selectColumns = ""
		var cmd = new CachedMetaData()
		var sd = new ArrayList<OdaResultSetColumn>()
		var cc = new ArrayList<ComputedColumn>()

//		var position = 0
//		// --- at first all navigations ---
//		for (navigation : entity.navigations) {
//			for	(property : navigation.datamartEntity.properties) {
//				if	((hiddens == null) || !hiddens.contains(property)) {
//					position = position+1
//					addDatamartProperty(sd, cc, property, position)
//				}				
//			}
//		}
//		// --- at last the "pure" data properties ---
//		for	(property : entity.properties) {
//			if	((hiddens == null) || !hiddens.contains(property)) {
//				position = position+1
//				addDatamartProperty(sd, cc, property, position)
//			}				
//		}
//		workSet.putResultSetColumns(dataSetName, sd)
//		workSet.putComputedColumns(dataSetName, cc)
//		for	(cc1 : cc) {
//			if	(selectColumns.empty) {
//				selectColumns = cc1.getName();
//			}
//			else {
//				selectColumns = selectColumns+","+cc1.getName();
//			}
//		}

		odseth.setProperty("queryText", ('''select «selectColumns» from «datamart.name»''').toString())
		cmd.setProperty(IDataSetModel.RESULT_SET_PROP, sd)
		odseth.setProperty(IDataSetModel.CACHED_METADATA_PROP, cmd)
		odseth.getElement().setProperty(IDataSetModel.RESULT_SET_PROP, sd)
	}	
	
	private def addAllDatamartProperties(ReportGeneratorWorkSet workSet, ArrayList<OdaResultSetColumn> sd, ArrayList<ComputedColumn> cc, EObject container) {
		switch container {
			DatamartEntity: {
				// --- at first all navigations ---
				for (navigation : container.navigations) {
					navigation.eAllContents.forEach[element |
						addAllDatamartProperties(workSet, sd, cc, element)
					]
				}
				// --- if no explicit properties are set ---
				if	(container.properties.isEmpty) {
					for	(attribute : container.entityRef.allAttributes) {
						if	(!attribute.isId && !attribute.isUuid) {
							if (datamartInferrer.isAuthorized(workSet.role, container.entityRef, attribute.name)) {
								addDatamartProperty(workSet, sd, cc, attribute)
							}
						}
					}
				}
				// --- at last the "pure" data properties ---
				else {
					for	(property : container.properties) {
						if (datamartInferrer.isAuthorized(workSet.role, container.entityRef, property.propertyRef.name)) {
							addDatamartProperty(workSet, sd, cc, property)
						}
					}
				}
			}
		}
	}
	
	private def addDatamartEntityResultSet(ReportGeneratorWorkSet workSet, OdaDataSetHandle odseth, String dataSetName, DatamartDefinition datamart) {
		var selectColumns = ""
		var cmd = new CachedMetaData()
		var sd = new ArrayList<OdaResultSetColumn>()
		var cc = new ArrayList<ComputedColumn>()

		workSet.fPosition = 0
		addAllDatamartProperties(workSet, sd, cc, datamart.source)
		workSet.putResultSetColumns(dataSetName, sd)
		workSet.putComputedColumns(dataSetName, cc)
		for	(cc1 : cc) {
			if	(selectColumns.empty) {
				selectColumns = cc1.getName();
			}
			else {
				selectColumns = selectColumns.concat(",").concat(cc1.getName());
			}
		}
		odseth.setProperty("queryText", ('''select «selectColumns» from «datamart.name»''').toString())
		cmd.setProperty(IDataSetModel.RESULT_SET_PROP, sd)
		odseth.setProperty(IDataSetModel.CACHED_METADATA_PROP, cmd)
		odseth.getElement().setProperty(IDataSetModel.RESULT_SET_PROP, sd)
	}	

	private def addDatamartProperty(ReportGeneratorWorkSet workSet, ArrayList<OdaResultSetColumn> sd, ArrayList<ComputedColumn> cc, DatamartProperty property) {
		addDatamartProperty(workSet, sd, cc, property.propertyRef)
	}
		
	private def addDatamartProperty(ReportGeneratorWorkSet workSet, ArrayList<OdaResultSetColumn> sd, ArrayList<ComputedColumn> cc, LEntityAttribute attribute) {
		// --- general information about the column ---
		var etype = dtType.getBasicType(attribute)
		var dataType = DataTypes.typeFor(etype)
		if	(dataType == DataTypes.ANY) {
			dataType = DataTypes.typeFor(attribute.type) // ??? warum ANY ???
		}
		// see also DatamartDSLJvmInferrer
		var name = attribute.toColumnName.toLowerCase
		// --- check for already found column ---
		for	(column : sd) {
			if	(column.columnName.equalsIgnoreCase(name)) {
				return
			}
		}
		// --- information needed to access via oda ---
		var st = new OdaResultSetColumn()
		st.setColumnName(name)
		st.setProperty("name", name)
		st.setNativeDataType(dataType.getNativeOdaDataTypeId())
		st.setNativeName(name)
		workSet.fPosition = workSet.fPosition+1
		st.setPosition(workSet.fPosition)
		st.setDataType(dataType.getNativeOdaDataTypeName())
		sd.add(st)
		// --- information needed to access via table ---
		var cs1 = StructureFactory.createComputedColumn()
		cs1.setName(name)
		cs1.setDisplayName(name);
		cs1.setExpression("dataSetRow[\"".concat(name).concat("\"]"))
		cs1.setDataType(dataType.getNativeOdaDataTypeName())
		cc.add(cs1)
	}
	
	private def getDatamartClassName(String alias, DatamartDefinition datamart) {
		'''«(datamart.eContainer as LPackage).fullyQualifiedName».«datamart.name»Class'''
	}
	
	public def generateItems(DatamartDefinition datamart, ReportGeneratorWorkSet workSet, ContainerItem container, Element[] elements) {
		if	(elements != null) {
			for	(element : elements) {
				try {
					switch (element) {
						Title:
							container.addHeader(1, I18NKeyGenerator.key(element.text), element.text.replace("\"",""), element.style)
						SubTitle:
							container.addHeader(2, I18NKeyGenerator.key(element.text), element.text.replace("\"",""), element.style)
						SubSubTitle:
							container.addHeader(3, I18NKeyGenerator.key(element.text), element.text.replace("\"",""), element.style) 
						Label:
							container.addLabel(I18NKeyGenerator.key(element.text), element.text.replace("\"",""), element.style)
						Text:
							container.addText (I18NKeyGenerator.key(element.text), element.text.replace("\"",""), element.style)
						AutoText:
							container.addAutoText (element.type.toString, element.style)
						DatamartTableProperty:
							container.addData (element, element.style)
						Image:
							addImage(
								workSet, container, element, null
							)
						DatamartTable:
							addDatamartTable(datamart, 
								workSet, container, element,
								new Width("100%")
							)
						Grid:
							addGrid(datamart, 
								workSet, container, element, null,
								new Width("100%")
							)
//						TableDsl:
//							addTable(
//								workSet, container, element,
//								new Width("100%")
//							)
//						ChartDsl:
//							System.err.println("ChartDsl ... todo")
					}
				}
				catch (ContentException ce) {
					System.err.println('''«ce.class.simpleName»: «ce.localizedMessage»''')
				}
				catch (Exception e) {
					e.printStackTrace
				}
			}
		}
	}
	
	private def addDatamartTable(DatamartDefinition datamart, ReportGeneratorWorkSet workSet, ContainerItem container, DatamartTable datamartTable, Attribute... attributes) {
//		var datamart = datamartTable.datamartRef
		var hiddens = new ArrayList<DatamartProperty>
		for	(columnFormatter : datamartTable.detail.columnFormatters) {
//			if	(columnFormatter.hiddens) {
//				var column = columnFormatter.column 
//				switch	(column) {
//					TableProperty: hiddens.add(column.valueRef)
//				}
//			}
		}
		var alias = datamartTable.name
		var dataSetName = Utilities.getDataSetName(alias, datamart).toString
		var dataSet = workSet.dataSets.get(dataSetName)
		if	(dataSet == null) {
			addDatamartSourceAndSet(datamart, workSet, alias, hiddens)
			dataSet = workSet.dataSets.get(dataSetName)
		}
		container.addTable(dataSet, datamartTable, workSet.getComputedColumns(dataSetName), datamartTable.groups, datamartTable.detail.style, datamartTable.detail.columnFormatters, datamartTable.style, attributes)
	}
	
//	def addTable(ReportGeneratorWorkSet workSet, Container container, TableDsl tableDsl, Attribute... attributes) {
//		var datamart = tableDsl.tableRef.source.datamartRef
//		var hiddens = null as DatamartProperty[]//tableItem.hiddens
//		var alias = tableDsl.name
//		var dataSetName = Utilities.getDataSetName(alias, datamart).toString
//		var dataSet = workSet.dataSets.get(dataSetName)
//		if	(dataSet == null) {
//			addDatamart(workSet, alias, datamart, hiddens)
//			dataSet = workSet.dataSets.get(dataSetName)
//		}
//		var propertyLookups = new PropertyLookups
//		var tableInferrer = new TableDSLJvmModelInferrer
//		tableInferrer.extractPropertyLookups(tableDsl.tableRef, propertyLookups)
//		container.addTable(dataSet, workSet.getComputedColumns(dataSetName), propertyLookups, attributes)
//	}
	
	private def addImage(ReportGeneratorWorkSet workSet, ContainerItem container, Image imageData, Style style, Attribute... attributes) {
		var image = new ImageItem(
			workSet,
			null,
			imageData.size.literal, 
			imageData.scale, 
			imageData.sourceType.literal, 
			imageData.filename
		)
		container.add(image, style, attributes)
	}
	
	private def addGrid(DatamartDefinition datamart, ReportGeneratorWorkSet workSet, ContainerItem container, Grid grid, Style style, Attribute... attributes) {
		var rowCount = grid.rows.length
		var columnCount = 0
		for	(row : grid.rows) {
			columnCount = Math.max(columnCount, row.cells.length)
		}
		var gridItem = new GridItem(
			workSet, 
			columnCount,
			rowCount
		);
		var rowNo = 0
		for	(row : grid.rows) {
			var columnNo = 0
			for	(cell : row.cells) {
				generateItems(datamart, workSet, gridItem.getCell(columnNo, rowNo).setColumnSpan(cell.columnspan), cell.elements)
				columnNo = columnNo+1
			}
			if	(row.style != null) {
				gridItem.applyStyle(rowNo, row.style)
			}
			rowNo = rowNo+1
		}
		container.add(gridItem, style, attributes)
	}

	override createAppendable(EObject context, ImportManager importManager, GeneratorConfig config) {
  		// required to initialize the needed builder to avoid deprecated methods
		builder = context.eResource
		// ---------
       addImportFor(importManager, _typeReferenceBuilder
	        , ReportGeneratorWorkSet
			, HorizontalLayout
			, ViewLayoutManager
			, BrowserFrame
			, StreamResource
			, Unit
			, Button
			, com.vaadin.ui.Label
			, IEventBroker
			, EventHandler
			, Event
			, EventUtils
			, EventBrokerMsg
			, CustomMsgException
			, IReportProvider.Rendering
			, AbstractComponent
			, UUID
			, Filter
			, IToolbarAction)
    	super.createAppendable(context, importManager, config)
	}
}
