<#--
   ******************************************************
   *
   *                       NOTICE
   *
   *  THIS SOFTWARE IS THE PROPERTY OF AND CONTAINS
   *  CONFIDENTIAL INFORMATION OF INFOR, AND SHALL NOT BE
   *  COPIED, USED, NOR DISCLOSED WITHOUT EXPRESS WRITTEN
   *  AUTHORIZATION.  ALTHOUGH PUBLICATION IS NOT
   *  INTENDED, IN THE EVENT OF PUBLICATION, THE
   *  FOLLOWING NOTICE IS APPLICABLE:
   *
   *  Copyright © 2009 Infor. All rights reserved.
   *  The word and design marks set forth herein are
   *  trademarks and/or registered trademarks of Infor
   *  and/or related affiliates and subsidiaries.
   *  All rights reserved. All other trademarks listed
   *  herein are the property of their respective owners.
   *  www.infor.com.
   *
   ******************************************************
  -->
<#import "common.defs.ftl" as common/>

<#function searchattrimpl iCi iCIT icolumn iOneLevel=false iLogError=true iSearchOtherDirection=false>
	<#assign attrImplList = []>
	<#-- Read attributeImplementation-->
	<#list iCi.attributeImplementation as ai>
		<#if ai.type == "column" && ai.componentImplementationTable.value == iCIT.name &&
				 ai.column.value == icolumn>
			<#assign attrImplList = attrImplList+[{"attributeName":ai.name}]>
		</#if>
	</#list>
	<#if !iOneLevel>
		<#-- Read ComponentImplementationTableDetails -->
		<#if !iSearchOtherDirection>
			<#list iCIT.componentImplementationTableDetail as citd>
				<#if citd.column.value == icolumn>
					<#assign attrImplList = attrImplList+searchattrimpl(iCi, citd.toComponentImplementationTable.idref, citd.toColumn.value, false, false, false)>
				</#if>
			</#list>
		</#if>
		<#-- Search other way around -->
		<#list iCi.componentImplementationTable as ct>
			<#list ct.componentImplementationTableDetail as citd>
				<#if citd.toColumn.value == icolumn && citd.toComponentImplementationTable.value == iCIT.name &&
					iCIT.position == citd.toComponentImplementationTable.idref.position>
					<#assign attrImplList = attrImplList+searchattrimpl(iCi, ct, citd.column.value, false, false, true)>
				</#if>
			</#list>
		</#list>
	</#if>
	<#if iLogError && !attrImplList?has_content>
		${logger.error(object," Field:${iCIT.name}.${icolumn}(${iCIT.position}) is not mapping to an attribute.")}
	</#if>
	<#return attrImplList>
</#function>

<#--#perf.sn-->
<#macro initHasMethodAlternativeImplementation>
	<#global hasMethodAlternativeImplementationStruc=[]>
</#macro>
<#--#perf.en-->

<#function hasMethodAlternativeImplementation iMethodName>
<#--#perf.sn-->
	<#list hasMethodAlternativeImplementationStruc as l>
		<#if l.methodName == iMethodName>
			<#return l.altBDE>
		</#if>
	</#list>
<#--#perf.en-->
	<#assign alt_BDE="">
	<#list protected.listProtectedComponents() as c>
		<#if c.componentName == names.businessInterfaceName>
			<#list c.componentImplementation.methodImplementation as cm>
				<#if cm.name==iMethodName &&
				     cm.alternativeBusinessInterfaceImplementation?exists>
						<#assign alt_BDE=cm.alternativeBusinessInterfaceImplementation.idref.name>
						<#break>
				</#if>
			</#list>
			<#break>
		</#if>
	</#list>	
<#--#perf.sn-->
	<#assign hasMethodAlternativeImplementationStruc = hasMethodAlternativeImplementationStruc + [{
			"methodName":iMethodName,
			"altBDE":alt_BDE
		}]>
<#--#perf.en-->
	<#return alt_BDE>
</#function>

<#function containedIn iValue iList>
	<#list iList as value>
		<#if value==iValue>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function listDependenciesFromGraph iValue iGraph>
	<#local dependenciesList=[]>
	<#list iGraph as g>
		<#if g.to.name==iValue.name>
			<#local dependenciesList=dependenciesList+[g.from]>
		</#if>
	</#list>
	<#return dependenciesList>
</#function>

<#function determineDependencyGraphForComponent iComponent>
	<#local dependencyGraph=[]>
	<#list common.listAttributeImplementations(iComponent) as ai>
		<#if ai.attributeImplementation.onSetHookExpression?exists && ai.attributeImplementation.onSetHookExpression?has_content>
			<#local gotListed=false>
			<#list ai.attributeImplementation.attributeImplementationRelationship as air>
				<#local dependencyGraph = dependencyGraph + [{
					"from":air.attributeImplementation.idref,
					"to":ai.attributeImplementation
				}]>
				<#local gotListed=true>
			</#list>
			<#if !gotListed>
				<#local dependencyGraph = dependencyGraph + [{
					"from":"",
					"to":ai.attributeImplementation
				}]>
			</#if>
		</#if>
	</#list>
	<#return dependencyGraph>
</#function>

<#function determineDependencyGraphForArguments iComponent iArgumentsList>
	<#local dependencyGraph=[]>
	<#local dependencyGraphComponent=determineDependencyGraphForComponent(iComponent)>
	<#list dependencyGraphComponent as dg>
		<#if dg.from?exists && dg.from!="">
			<#if dg.from.attribute?exists>
				<#if containedIn(dg.from.name, iArgumentsList)>
					<#local dependencyGraph=dependencyGraph+[dg]>
				</#if>
			<#else>
				<#local dependencyGraph=dependencyGraph+[dg]>
			</#if>
		<#else>
			<#local dependencyGraph=dependencyGraph+[dg]>
		</#if>
	</#list>
	<#return dependencyGraph>
</#function>

<#function determineAttributeImplementationsSequence iKnownArguments iDependencyGraph iSequenceSoFar>
	<#local newMembersFound=false>
	<#local knownArguments=iKnownArguments>
	<#local newKnownArguments=[]>
	<#local candidatesList=[]>
	<#local candidatesNameList=[]>
	<#local sequenceOrder=iSequenceSoFar>
	<#list iDependencyGraph as dg>
		<#if !containedIn(dg.to.name, candidatesNameList)>
			<#local candidatesNameList=candidatesNameList+[dg.to.name]>
			<#local candidatesList=candidatesList+[dg.to]>
		</#if>
	</#list>
	<#list candidatesList as candidate>
		<#local canBeAdded=true>
		<#list iDependencyGraph as dg>
			<#if canBeAdded && dg.to.name==candidate.name && dg.from!="">
				<#if !containedIn(dg.from.name, knownArguments)>
					<#local canBeAdded=false>
				</#if>
			</#if>
		</#list>
		<#if canBeAdded>
			<#local sequenceOrder=sequenceOrder+[candidate]>
			<#local knownArguments=knownArguments+[candidate.name]>
			<#local newKnownArguments=newKnownArguments+[candidate.name]>
			<#local newMembersFound=true>
		</#if>
	</#list>
	<#if newMembersFound>
		<#local dependencyGraph=[]>
		<#list iDependencyGraph as dg>
			<#if !containedIn(dg.to.name, newKnownArguments)>
				<#local dependencyGraph = dependencyGraph + [dg]>
			</#if>
		</#list>
		<#local sequenceOrder=determineAttributeImplementationsSequence(knownArguments, dependencyGraph, sequenceOrder)>
	</#if>
	<#return sequenceOrder>	
</#function>

<#function listAttributeImplementationsWithDependencies iComponent iMethod>
	<#local argumentList=[]>
	<#local sequenceOrderWithDependencies=[]>
	<#list listProtectedAttributes(iMethod, iComponent) as a>
		<#if a.scope=="in" || a.scope=="inout">
			<#local argumentList = argumentList+[a.attributeName]>
		</#if>
	</#list>
	<#local dependencyGraph=determineDependencyGraphForArguments(iComponent, argumentList)>
	<#local sequenceOrder=[]>
	<#local sequenceOrder=determineAttributeImplementationsSequence(argumentList, dependencyGraph, sequenceOrder)>
	<#list sequenceOrder as attr>
		<#local sequenceOrderWithDependencies=sequenceOrderWithDependencies+[{
			"attributeImplementation":attr,
			"dependentFrom":listDependenciesFromGraph(attr, dependencyGraph)
		}]>
	</#list>
	<#return sequenceOrderWithDependencies>
</#function>

<#--#perf.sn-->
<#macro initListProtectedComponents>
	<#global componentsListProtStruct=[]>
</#macro>
<#--#perf.en-->

<#function listProtectedComponents iParentComponentName="" iobject=object>
	<@common.checkCancel/>
	<#local protectedComponentsList=[]>
	<#if iParentComponentName=="">
<#--#perf.so--
		<#local protectedComponent={
			"parentComponentName":"", 
			"parentQueryID":0, 
			"componentName":names.businessInterfaceName,
			"componentPublicName":names.businessInterfaceName,
			"queryID":getFirstCounter(),
			"componentImplementation":iobject,
			"relationshipImplementation":""
		}>	
		<#local protectedComponentsList=listProtectedComponentsAA([protectedComponent], protectedComponent)> 
<#--#perf.eo-->
<#--#perf.sn-->
		<#if componentsListProtStruct?size == 0>
			<#local protectedComponent={
				"parentComponentName":"", 
				"componentName":names.businessInterfaceName,
				"componentPublicName":names.businessInterfaceName,
				"componentImplementation":iobject,
				"relationshipImplementation":""
			}>
			<#local componentsListProtStruct=listProtectedComponentsAA([protectedComponent], protectedComponent)>
		</#if> 
		<#local protectedComponentsList=componentsListProtStruct>
<#--#perf.en-->
	<#else>
		<#list listProtectedComponents() as c>
			<#if c.parentComponentName==iParentComponentName>
				<#local protectedComponentsList=protectedComponentsList+[c]>
			</#if>
		</#list>
	</#if>
	<#return protectedComponentsList>
</#function>

<#function listProtectedComponentsAA iProtectedComponentsList iParent>
	<#list iParent.componentImplementation.relationshipImplementation as relationshipImplementation>
		<#if relationshipImplementation.relationship?has_content && relationshipImplementation.relationship.idref.type=="aggregation">
<#--#perf.so--
			<#local protectedComponent={
				"parentComponentName":iParent.componentName, 
				"parentQueryID":iParent.queryID, 
				"parentComponentImplementation":iParent.componentImplementation,
				"componentName":common.getComponentName(relationshipImplementation.componentImplementation), 
				"componentPublicName":common.getComponentPublicName(relationshipImplementation.componentImplementation),
				"queryID":getNextCounter(),
				"componentImplementation":relationshipImplementation.componentImplementation,
				"relationshipImplementation":relationshipImplementation
			}>	
<#--#perf.eo-->
<#--#perf.sn-->
			<#local protectedComponent={
				"parentComponentName":iParent.componentName, 
				"parentComponentImplementation":iParent.componentImplementation,
				"componentName":common.getComponentName(relationshipImplementation.componentImplementation), 
				"componentPublicName":common.getComponentPublicName(relationshipImplementation.componentImplementation),
				"componentImplementation":relationshipImplementation.componentImplementation,
				"relationshipImplementation":relationshipImplementation
			}>	
<#--#perf.en-->
			<#local iProtectedComponentsList=iProtectedComponentsList+[protectedComponent]>
			<#local iProtectedComponentsList=listProtectedComponentsAA(iProtectedComponentsList, protectedComponent)>
		</#if>
	</#list>
	<#return iProtectedComponentsList>
</#function>

<#function getFirstCounter>
	<#assign myCounter = 1>
	<#return myCounter>
</#function>
<#function getNextCounter>
	<#assign myCounter = myCounter + 1>
	<#return myCounter>
</#function>

<#function listJOINTables iComponentImplementationTable>
	<#local container=[]>
	<#list iComponentImplementationTable.componentImplementationTableDetail as citd>
		<#local toTableName=citd.toComponentImplementationTable.idref.table.idref.name>
		<#if !container?seq_contains(toTableName)>
			<#local container=container+[toTableName]>
		</#if>
	</#list>
	<#return container>
</#function>

<#function listJOINTableDetails iComponentImplementationTable itoTableName="">
	<#local container=[]>
	<#list iComponentImplementationTable.componentImplementationTableDetail as citd>
		<#if (itoTableName=="" || citd.toComponentImplementationTable.idref.table.idref.name==itoTableName)>
			<#local container=container+[{
				"fromComponentImplementationTable":iComponentImplementationTable,
				"fromTableName":iComponentImplementationTable.table.idref.name, 
				"fromColumnName":citd.column.idref.name,
				"fromTablePosition":iComponentImplementationTable.position,
				"toComponentImplementationTable":citd.toComponentImplementationTable.idref,
				"toTableName":itoTableName, 
				"toColumnName":citd.toColumn.idref.name,
				"toTablePosition":citd.toComponentImplementationTable.idref.position,
				"componentImplementationTableDetail":citd
			}]>
		</#if>
	</#list>
	<#return container>
</#function>

<#--#perf.sn-->
<#macro initListProtectedAssociatedAttributes>
	<#global attributesListProtAssocStruct=[]>
</#macro>

<#function buildListProtectedAssociatedAttributes>
	<#local theList=[]>
	<#local components=listProtectedComponents()>
	<#list components as c>
		<#local container=[]>
		<#list c.componentImplementation.attributeImplementation as ai>
			<#if ai.type=="association">
				<#local relationshipImplementation=ai.association.idref>
				<#local toComponentImplementation=relationshipImplementation.toBusinessInterfaceImplementation.idref>
				<#if relationshipImplementation.toComponentImplementation?exists &&
					 common.getComponentName(relationshipImplementation.toComponentImplementation.idref, relationshipImplementation.toBusinessInterfaceImplementation.idref) != "">
					<#local toComponentImplementation=relationshipImplementation.toComponentImplementation.idref>
				</#if>
				<#local container=container+[{
					"fromBusinessInterfaceImplementation":object,
					"fromBusinessInterfaceName":names.businessInterfaceName,
					"fromComponentImplementation":c.componentImplementation,
					"fromComponentName":common.getComponentName(c.componentImplementation),
					"fromAttributeImplementation":ai,
					"fromAttributeName":common.getAttributeName(ai),
					"toBusinessInterfaceImplementation":relationshipImplementation.toBusinessInterfaceImplementation.idref,
					"toBusinessInterfaceName":common.getComponentName(relationshipImplementation.toBusinessInterfaceImplementation.idref, relationshipImplementation.toBusinessInterfaceImplementation.idref),
					"toComponentImplementation":toComponentImplementation,
					"toComponentName":common.getComponentName(toComponentImplementation, relationshipImplementation.toBusinessInterfaceImplementation.idref),
					"toAttributeImplementation":common.getAttributeImplementation(toComponentImplementation, ai.attributeFromAssociation.idref.name),
					"toAttributeName":ai.attributeFromAssociation.idref.name,
					"relationshipImplementation":relationshipImplementation
				}]>			
			</#if>
		</#list>
		<#local theList=theList+[{
			"componentImplementation":c.componentImplementation,
			"container":container
		}]>
	</#list>	
	<#return theList>
</#function>

<#function listProtectedAssociatedAttributes iComponentImplementation>
	<#if attributesListProtAssocStruct?size=0>
		<#assign attributesListProtAssocStruct=buildListProtectedAssociatedAttributes()>
	</#if>

	<#list attributesListProtAssocStruct as c>
		<#if c.componentImplementation==iComponentImplementation>
			<#return c.container>
		</#if>
	</#list>
	<#return []>
</#function>
<#--#perf.en-->
<#--#perf.so--
<#function listProtectedAssociatedAttributes iComponentImplementation>
	<#local container=[]>
	<#local components=listProtectedComponents()>
	<#local queryID=components?last.queryID>
	<#list components as c>
		<#list c.componentImplementation.attributeImplementation as ai>
			<#if ai.type=="association">
				<#local queryID=queryID+1>
				<#if c.componentImplementation==iComponentImplementation>
					<#local relationshipImplementation=ai.association.idref>
					<#local toComponentImplementation=relationshipImplementation.toBusinessInterfaceImplementation.idref>
					<#if relationshipImplementation.toComponentImplementation?exists &&
						 common.getComponentName(relationshipImplementation.toComponentImplementation.idref, relationshipImplementation.toBusinessInterfaceImplementation.idref) != "">
						<#local toComponentImplementation=relationshipImplementation.toComponentImplementation.idref>
					</#if>
					<#local container=container+[{
						"fromBusinessInterfaceImplementation":object,
						"fromBusinessInterfaceName":names.businessInterfaceName,
						"fromComponentImplementation":iComponentImplementation,
						"fromComponentName":common.getComponentName(iComponentImplementation),
						"fromAttributeImplementation":ai,
						"fromAttributeName":common.getAttributeName(ai),
						"toBusinessInterfaceImplementation":relationshipImplementation.toBusinessInterfaceImplementation.idref,
						"toBusinessInterfaceName":common.getComponentName(relationshipImplementation.toBusinessInterfaceImplementation.idref, relationshipImplementation.toBusinessInterfaceImplementation.idref),
						"toComponentImplementation":toComponentImplementation,
						"toComponentName":common.getComponentName(toComponentImplementation, relationshipImplementation.toBusinessInterfaceImplementation.idref),
						"toAttributeImplementation":common.getAttributeImplementation(toComponentImplementation, ai.attributeFromAssociation.idref.name),
						"toAttributeName":ai.attributeFromAssociation.idref.name,
						"relationshipImplementation":relationshipImplementation,
						"queryID":queryID
					}]>			
				</#if>
			</#if>
		</#list>
	</#list>	
	<#return container>
</#function>
<#--#perf.eo-->

<#--#perf.sn-->
<#macro initListInternalIdentifiers>
	<#global internalIdentifiersListStruct=[]>
</#macro>
<#--#perf.en-->

<#function listInternalIdentifiers iComponentName="" iMapToTable=true>
	<#-- Provides the attribute implementations at the inside that are identifiers -->
	<#-- Each entry contains same elemens as protected.listProtectedAttributes --> 
<#--#perf.sn-->
	<#list internalIdentifiersListStruct as l>
		<#if l.componentName==iComponentName && l.mapToTable==iMapToTable>
			<#return l.internalIdentifiers>
		</#if>
	</#list>
<#--#perf.en-->
	<#local internalIdentifierList=[]/>
	<#local found=false/>
	<#list listProtectedAttributes("", iComponentName) as pa>
		<#if common.getIsIdentifier(pa.attributeImplementation) && pa.attributeImplementation.type=="column">
			<#local internalIdentifierList=internalIdentifierList+[pa]>
			<#local found=true/>
		</#if>
	</#list>
	<#if !iMapToTable && !found>
		<#-- take the attributes that are identifier and are not calculated -->
		<#list listProtectedAttributes("", iComponentName) as pa>
			<#if common.getIsIdentifier(pa.attributeImplementation) && pa.attributeImplementation.type!="calculated">
				<#local internalIdentifierList=internalIdentifierList+[pa]>
			</#if>
		</#list>
	</#if>
<#--#perf.sn-->
	<#assign internalIdentifiersListStruct = internalIdentifiersListStruct + [{
			"componentName":iComponentName,
			"mapToTable":iMapToTable,
			"internalIdentifiers":internalIdentifierList
		}]>
<#--#perf.en-->
	<#return internalIdentifierList>
</#function>

<#function isTableIdentifier iTable iAttribute>
	<#-- Checks if iAttribute occurs in iTable AND that it is an identifier -->
	<#list iTable.column as column>
		<#if column.isPrimaryKey && column.name==iAttribute>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function listRootTableIdentifiers iComponentName>
	<#-- Provides the attribute implementations at the inside that are identifiers -->
	<#-- and map to table columns -->
	<#-- Each entry contains same elemens as protected.listProtectedAttributes --> 
	<#local internalIdentifierList=[]/>
	<#list listProtectedComponents() as c>
		<#if c.componentName==iComponentName>
			<#list c.componentImplementation.componentImplementationTable as componentImplementationTable>
				<#if componentImplementationTable.isRootTable>
					<#local table=componentImplementationTable.table.idref>
					<#list listProtectedAttributes("", iComponentName) as pa>
						<#if pa.attributeImplementation.type=="column" && isTableIdentifier(table, pa.attributeImplementation.column.idref.name)>
							<#local internalIdentifierList=internalIdentifierList+[pa]>
						</#if><#--if pa.attributeImplementation.type=="column" && isTableIdentifier(table, pa.attributeImplementation.column.idref.name)-->
					</#list><#--list listProtectedAttributes("", iComponentName) as pa-->
					<#break>
				</#if></#--if componentImplementationTable.isRootTable-->
			</#list><#--list c.componentImplementation.componentImplementationTable as componentImplementationTable-->
			<#break>
		</#if><#--if c.componentName==iComponentName-->
	</#list><#--list listProtectedComponents() as c-->
	<#return internalIdentifierList>
</#function>

<#function listNonRootTables iComponentName>
	<#local tableList=[]>
	<#list listProtectedComponents() as c>
		<#if c.componentName==iComponentName>
			<#list c.componentImplementation.componentImplementationTable as componentImplementationTable>
				<#local table=componentImplementationTable.table.idref>
				<#if !componentImplementationTable.isRootTable && !containedIn(table, tableList)>
					<#local tableList = tableList + [table]>
				</#if><#--if !containedIn(table, tableList)-->
			</#list><#--list c.componentImplementation.componentImplementationTable as componentImplementationTable-->
			<#break>
		</#if><#--if c.componentName==iComponentName)-->
	</#list><#--list listProtectedComponents() as c-->
	<#return tableList>
</#function>

<#function isMappedToTable iComponentImplementation iAttributeImplementation iTableName>
	<#if iAttributeImplementation.type=="column">
		<#local tableName=iAttributeImplementation.componentImplementationTable.idref.table.idref.name>		
		<#local columnName=iAttributeImplementation.column.idref.name>		
		<#if tableName==iTableName>
			<#return true>
		</#if>
		
		<#list iComponentImplementation.componentImplementationTable as cit>
			<#list cit.componentImplementationTableDetail as citd>
				<#if ((cit.table.idref.name==iTableName) && 
					  (citd.toColumn.idref.name==columnName))>
					<#return true>
				</#if>
			</#list>
		</#list>
	</#if>
	<#return false>
</#function>

<#function isMappedToTableByCit iComponentImplementation iAttributeImplementation iComponentImplementationTable>
	<#if iAttributeImplementation.type=="column">	
		<#local columnName=iAttributeImplementation.column.idref.name>		
		<#if iAttributeImplementation.componentImplementationTable==iComponentImplementationTable>
			<#return true>
		</#if>
		
		<#list iComponentImplementation.componentImplementationTable as cit>
			<#list cit.componentImplementationTableDetail as citd>
				<#if ((cit==iComponentImplementationTable) && 
					  (citd.toColumn.idref.name==columnName))>
					<#return true>
				</#if>
			</#list>
		</#list>
	</#if>
	<#return false>
</#function>

<#-- function used by the generation of setting fields for create/change (protected.st.methods) -->
<#function getAttributeImplementationLinkedToTableColumn iComponent iTableName iColumnName iSwitchedToOtherDirection=false>
	<#-- search on attribute implementations directly -->
	<#list listProtectedAttributes("", iComponent.componentName) as a>
		<#if a.attributeImplementation.componentImplementationTable?exists && a.attributeImplementation.componentImplementationTable?has_content>
			<#if iTableName == a.attributeImplementation.componentImplementationTable.idref.table.idref.name &&
					iColumnName == a.attributeImplementation.column.idref.name>
				<#return a>
			</#if>
		</#if>
	</#list>
	<#if !iSwitchedToOtherDirection>
		<#-- search on table links -->
		<#list iComponent.componentImplementation.componentImplementationTable as cit>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.toComponentImplementationTable.idref.table.idref.name == iTableName &&
						citd.toColumn.idref.name == iColumnName>
					<#return getAttributeImplementationLinkedToTableColumn(iComponent, cit.table.idref.name, citd.column.idref.name)>
				</#if>
			</#list>
		</#list>
	</#if>
	<#-- search on table links, other way around -->
	<#list iComponent.componentImplementation.componentImplementationTable as cit>
		<#if cit.table.idref.name == iTableName>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.column.idref.name == iColumnName>
					<#return getAttributeImplementationLinkedToTableColumn(iComponent, citd.toComponentImplementationTable.idref.table.idref.name, citd.toColumn.idref.name, true)>
				</#if>
			</#list>
		</#if>
	</#list>
	<#-- not found -->
	<#return "">
</#function>

<#-- function used by the generation of setting fields for create/change (protected.st.methods) -->
<#function getAttributeImplementationLinkedToTableColumnByCit iComponent iComponentImplementationTable iColumnName iSwitchedToOtherDirection=false>
	<#-- search on attribute implementations directly -->
	<#list listProtectedAttributes("", iComponent.componentName) as a>
		<#if a.attributeImplementation.componentImplementationTable?exists && 
		     a.attributeImplementation.componentImplementationTable?has_content>
			<#if iComponentImplementationTable == a.attributeImplementation.componentImplementationTable.idref && 
			     iColumnName == a.attributeImplementation.column.idref.name>
				<#return a>
			</#if>
		</#if>
	</#list>
	<#if !iSwitchedToOtherDirection>
		<#-- search on table links -->
		<#list iComponent.componentImplementation.componentImplementationTable as cit>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.toComponentImplementationTable.idref == iComponentImplementationTable && 
				     citd.toColumn.idref.name == iColumnName>
					<#return getAttributeImplementationLinkedToTableColumnByCit(iComponent, cit, citd.column.idref.name)>
				</#if>
			</#list>
		</#list>
	</#if>
	<#-- search on table links, other way around -->
	<#list iComponent.componentImplementation.componentImplementationTable as cit>
		<#if cit == iComponentImplementationTable>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.column.idref.name == iColumnName>
					<#return getAttributeImplementationLinkedToTableColumnByCit(iComponent, citd.toComponentImplementationTable.idref, citd.toColumn.idref.name, true)>
				</#if>
			</#list>
		</#if>
	</#list>
	<#-- not found -->
	<#return "">
</#function>

<#--TECH5785.sn-->
<#function containsAttributeImplementation iList iAttributeImplementation>
	<#list iList as ai>
		<#if ai.attributeImplementation == iAttributeImplementation>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>
<#--TECH5785.en-->

<#-- #VERS.sn -->
<#-- Same as getAttributeImplementationLinkedToTableColumnByCit, but returns a list of all related attribute implementations -->
<#function getMultipleAttributeImplementationsLinkedToTableColumnByCit iComponent iComponentImplementationTable iColumnName iSwitchedToOtherDirection=false>
	<#local container=[]>
	<#-- search on attribute implementations directly -->
	<#list listProtectedAttributes("", iComponent.componentName) as a>
		<#local attrImpl = a.attributeImplementation>
		<#if attrImpl.componentImplementationTable?exists && 
		     attrImpl.componentImplementationTable?has_content>
			<#if iComponentImplementationTable == attrImpl.componentImplementationTable.idref && 
			     iColumnName == attrImpl.column.idref.name>
<#--TECH5785.so--
		     	<#if !container?seq_contains(attrImpl)>
					<#local container=container+[{"attributeImplementation":attrImpl}]>
<#--TECH5785.eo-->
<#--TECH5785.sn-->
		     	<#if !containsAttributeImplementation(container, attrImpl)>
					<#local container=container+[{
						"componentName":a.componentName,
						"attributeName":a.attributeName,
						"attributeImplementation":attrImpl}]>
<#--TECH5785.en-->
		     	</#if>
			</#if>
		</#if>
	</#list>
	<#if !iSwitchedToOtherDirection>
		<#-- search on table links -->
		<#list iComponent.componentImplementation.componentImplementationTable as cit>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.toComponentImplementationTable.idref == iComponentImplementationTable && 
				     citd.toColumn.idref.name == iColumnName>
				     <#list getMultipleAttributeImplementationsLinkedToTableColumnByCit(iComponent, cit, citd.column.idref.name) as a>
<#--TECH5785.so--
				     	<#if !container?seq_contains(a.attributeImplementation)>
							<#local container=container+[{"attributeImplementation":a.attributeImplementation}]>
<#--TECH5785.eo-->
<#--TECH5785.sn-->
				     	<#if !containsAttributeImplementation(container, a.attributeImplementation)>
							<#local container=container+[a]>
<#--TECH5785.en-->
				     	</#if>
				     </#list>
				</#if>
			</#list>
		</#list>
	</#if>
	<#-- search on table links, other way around -->
	<#list iComponent.componentImplementation.componentImplementationTable as cit>
		<#if cit == iComponentImplementationTable>
			<#list cit.componentImplementationTableDetail as citd>
				<#if citd.column.idref.name == iColumnName>
				     <#list getMultipleAttributeImplementationsLinkedToTableColumnByCit(iComponent, citd.toComponentImplementationTable.idref, citd.toColumn.idref.name, true) as a>
<#--TECH5785.so--
				     	<#if !container?seq_contains(a.attributeImplementation)>
							<#local container=container+[{"attributeImplementation":a.attributeImplementation}]>
<#--TECH5785.eo-->
<#--TECH5785.sn-->
				     	<#if !containsAttributeImplementation(container, a.attributeImplementation)>
							<#local container=container+[a]>
<<#--TECH5785.en-->
				     	</#if>
				     </#list>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return container>
</#function>
<#-- #VERS.en -->

<#function listProtectedParentComponents iComponentName>
	<#local container=[]>
	<#list listProtectedComponents() as c>
		<#if c.componentName==iComponentName>
			<#if c.parentComponentName!="">
				<#local container=container+[{
					"componentName":c.parentComponentName, 
					"componentImplementation":c.parentComponentImplementation,
					"relationshipImplementation":c.relationshipImplementation
				}]>
				<#list listProtectedParentComponents(c.parentComponentName) as pc>
					<#local container=container+[{
						"componentName":pc.componentName, 
						"componentImplementation":pc.componentImplementation,
						"relationshipImplementation":pc.relationshipImplementation
					}]>
				</#list>
			</#if>
			<#break>
		</#if>
	</#list>
	<#return container>
</#function>

<#function hasProtectedChildComponents iComponentName>
	<#local found=false>
	<#list listProtectedChildComponents(iComponentName) as pcc>
		<#local found=true>
		<#break>
	</#list>
	<#return found>
</#function>

<#function hasProtectedParentComponents iComponentName>
	<#local found=false>
	<#list listProtectedParentComponents(iComponentName) as ppc>
		<#local found=true>
		<#break>
	</#list>
	<#return found>
</#function>

<#function hasNonRootTable iComponentImplementation>
	<#local found=false>
	<#list iComponentImplementation.componentImplementationTable as cit>
		<#if !cit.isRootTable>
			<#local found=true>
			<#break>
		</#if>
	</#list>
	<#return found>
</#function>

<#function listProtectedChildComponents iComponentName>
	<#local container=[]>
	<#list listProtectedComponents() as c>
		<#if c.parentComponentName!="">
			<#if c.parentComponentName==iComponentName>
				<#local container=container+[{
					"componentName":c.componentName, 
					"componentImplementation":c.componentImplementation
				}]>
				<#list listProtectedChildComponents(c.componentName) as pc>
					<#local container=container+[{
						"componentName":pc.componentName, 
						"componentImplementation":pc.componentImplementation
					}]>
				</#list>
			</#if>
		</#if>
	</#list>
	<#return container>
</#function>

<#function listNonRootTablesOrder iComponentImplementation iTableName nonRootTablesList=[]>
	<#-- call this function with roottable as iTableName argument -->
	<#list iComponentImplementation.componentImplementationTable as cit>
		<#list listJOINTables(cit) as joinTableName>
			<#list listJOINTableDetails(cit, joinTableName) as jtd>
				<#local cont=true>
				<#-- 1. relations from another table to this table -->
				<#if "${jtd.toTableName}_${jtd.toTablePosition}"=iTableName>
					<#local toTableName="${jtd.fromTableName}_${jtd.fromTablePosition}">
				<#else>
					<#-- 2. relations from this table to another table -->
					<#if "${jtd.fromTableName}_${jtd.fromTablePosition}"=iTableName>
						<#local toTableName="${jtd.toTableName}_${jtd.toTablePosition}">
					<#else>
						<#local cont=false>
					</#if>					
				</#if>
				<#if cont>
					<#local skip=false>
					<#list nonRootTablesList as rtl>
						<#if rtl.fromTable=toTableName>
							<#local skip=true>
						<#else>
							<#if rtl.toTable=toTableName>						
								<#local skip=true>
							</#if>
						</#if>
					</#list>
					<#if skip=false>
						<#local nonRootTablesList=nonRootTablesList+[{
							"fromTable":iTableName, 
							"toTable":toTableName}]>
						<#list listNonRootTablesOrder(iComponentImplementation, toTableName, nonRootTablesList) as nrto>
							<#if nrto.toTable!=toTableName && nrto.fromTable!=iTableName>
								<#local nonRootTablesList=nonRootTablesList+[nrto]>
							</#if>
						</#list>
					</#if>
				</#if>
			</#list>
		</#list>
	</#list>
	<#return nonRootTablesList>
</#function>

<#function listNonRootChildren iComponentImplementation iTable>
	<#local nonRootChildrenList=[]>
	<#list iComponentImplementation.componentImplementationTable as cit>
		<#if cit.isRootTable>
			<#assign table=cit.table.idref>
			<#assign tableName=table.name>
			<#list listNonRootTablesOrder(iComponentImplementation, "${tableName}_${cit.position}") as nrc>
				<#if nrc.fromTable=iTable>
					<#if !containedIn(nrc.toTable, nonRootChildrenList)>
						<#local nonRootChildrenList=nonRootChildrenList+[nrc.toTable]>
					</#if>
				</#if>
			</#list>
			<#break>
		</#if>
	</#list>
	<#return nonRootChildrenList>
</#function>

<#function listSiblingComponents iRootComponent iComponentName>
	<#-- returns direct siblings of component in relation to a root(parent) component -->
	<#local siblingComponentsList=[]>
	<#list listProtectedComponents() as pc>
		<#if pc.parentComponentName == iRootComponent && pc.componentName != iComponentName>
			<#list listProtectedParentComponents(iComponentName) as ppc>
				<#if ppc.componentName == pc.componentName>
					<#-- only include siblings, no components from parent path to root -->
					<#break>
				</#if>
				<#if !ppc_has_next>
					<#local siblingComponentsList=siblingComponentsList+[{
										"componentName":pc.componentName}]>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return siblingComponentsList>
</#function>

<#function hasSiblingComponents iRootComponent iComponentName>
	<#local found=false>
	<#list listSiblingComponents(iRootComponent, iComponentName) as sc>
		<#local found=true>
		<#break>
	</#list>
	<#return found>
</#function>

<#function listProtectedAttributes0 iMethodName="" iComponentName="">
<#-- lists all protected attributes from a certain component used in a certain method -->
	<#local attributesList=[]>
	<#list listProtectedComponents() as c>
		<#if (iComponentName=="" || c.componentName==iComponentName)>
			<#list c.componentImplementation.attributeImplementation as attributeImplementation>
				<#assign attributeName=common.getAttributeName(attributeImplementation)>
				<#if iMethodName != "">
					<#list common.listMethodArgumentImplementationsAA(c.componentImplementation, iMethodName) as methodArgumentImplementation>
						<#if methodArgumentImplementation.methodArgument?exists>
							<#assign methodArgument=methodArgumentImplementation.methodArgument.idref>
							<#if methodArgument.type=="attribute">
								<#if ((common.getComponentNameFromMethodArgument(methodArgument)==c.componentName) && (methodArgument.attribute.idref.name==attributeName))>
									<#local attributesList=attributesList+[{
										"componentName":c.componentName, 
										"attributeName":attributeName,
										"scope":methodArgumentImplementation.scope,
										"position": methodArgumentImplementation.position,
										"attributeImplementation":attributeImplementation, 
										"methodArgumentImplementation":methodArgumentImplementation}]>
									<#break>
								</#if>					
							</#if>
						<#elseif methodArgumentImplementation.attributeImplementation?exists>
							<#if methodArgumentImplementation.attributeImplementation.idref==attributeImplementation>
								<#local attributesList=attributesList+[{
									"componentName":c.componentName, 
									"attributeName":attributeName, 
									"scope":methodArgumentImplementation.scope,
									"position": methodArgumentImplementation.position,
									"attributeImplementation":attributeImplementation, 
									"methodArgumentImplementation":methodArgumentImplementation}]>
								<#break>
							</#if>
						<#else>	
							${logger.warn(object, "No Protected Attributes found for Component ${iComponentName}, Attribute ${attributeName} and Method ${iMethodName}")}
						</#if>
					</#list>
				<#else>
						<#local attributesList=attributesList+[{
							"componentName":c.componentName, 
							"attributeName":attributeName, 
							"attributeImplementation":attributeImplementation, 
							"methodArgumentImplementation":""}]>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return attributesList>
</#function>

<#macro initListProtectedAttributes>
	<#global attributesListProtStruct=[]>
</#macro>

<#function listProtectedAttributes iMethodName iComponentName="">
<#-- lists all protected attributes from a certain component used in a certain method -->
	<#list attributesListProtStruct as a>
		<#if iMethodName=a.methodName && iComponentName==a.componentName>
			<#return a.content>
		</#if>
	</#list>
	<#local attributesList=listProtectedAttributes0(iMethodName,iComponentName)>
	<#assign attributesListProtStruct=attributesListProtStruct+[{
			"methodName":iMethodName,
			"componentName":iComponentName,
			"content":attributesList}]>
	<#return attributesList>
</#function>

<#function listAllProtectedAttributes iComponentName="">
<#-- this function replaces the calls to listPublicOutputAttributes("List") -->
	<#if common.protectedMethodPresent("List")>
		<#-- retrieve from List method -->
		<#return listProtectedAttributes("List", iComponentName)>
	<#else>
		<#if common.protectedMethodPresent("Show")>
			<#-- retrieve from Show method -->
			<#return listProtectedAttributes("Show", iComponentName)>
		<#else>
			<#-- no List and Show methods present: return empty list -->
			<#return []>
		</#if>
	</#if>
</#function>

<#function listattrRelShipColumn iai iHandled iLevel iRootAttr>
	<#local iLevel = iLevel +1>
	<#local atlist=[]>
	<#list iai.attributeImplementation.attributeImplementationRelationship as ar>
		<#assign ai=ar.attributeImplementation.idref>
		<#assign attributeName=common.getAttributeName(ai)>
		<#-- check for loop-->
		<#local skip=false>
		<#local tmp="">
		<#list iHandled as ih>
			<#local tmp=tmp + "," + ih.attributeName>
			<#if ih.attributeName == attributeName>
				<#local skip=true>
			</#if>
		</#list>
		<#list atlist as al>
				<#local tmp=tmp + ",(" + al.attributeName +")">
			<#if al.attributeName == attributeName>
				<#local skip=true>
			</#if>
		</#list>
		<#if !skip>
			<#local iHandled=iHandled+[{
				"attributeName":attributeName}]>
			<#if ai.type == "column">
				<#local atlist=atlist+[{
					"attributeName":attributeName,
					"attributeImplementation":ai}]>
			</#if>
			<#if ai.type == "calculated">
				<#local al={			"attributeName":attributeName,
										"attributeImplementation":ai}>
				<#list listattrRelShipColumn(al, iHandled, iLevel, iRootAttr) as arc>
					<#local atlist=atlist+[{
						"attributeName":arc.attributeName,
						"attributeImplementation":arc.attributeImplementation}]>
					<#local iHandled=iHandled+[{
						"attributeName":arc.attributeName}]>
				</#list>
			</#if>
		</#if>
	</#list>
	<#local iLevel = iLevel -1>
	<#return atlist>
</#function>

<#function listColumnsBlowAttributes iComponentName iAttributeName="">

	<#local attributesList=[]>
	<#local level=0>
	<#list listAllProtectedAttributes(iComponentName) as a>
		<#if (iAttributeName=="" || iAttributeName==a.attributeName)> 
			<#local handledAttr=[]>
			<#list listattrRelShipColumn(a, handledAttr, level, a.attributeName) as arc>
				<#local attributesList=attributesList+[{
					"componentName":a.componentName, 
					"attributeName":arc.attributeName,
					"attributeImplementation":arc.attributeImplementation}]>
			</#list>
		</#if>
	</#list>

	<#return attributesList>
</#function>


<#function listUsedPersistentAttributes iMethodName iComponentName iAttributeName="">

	<#local attributesList=[]>	
	
	<#list listProtectedAttributes(iMethodName, iComponentName) as a>
		<#if (iAttributeName=="" || iAttributeName==a.attributeName)>
			<#list a.attributeImplementation.attributeImplementationRelationship as ar>
				<#assign ai=ar.attributeImplementation.idref>
				<#assign attributeName=common.getAttributeName(ai)>
				<#list common.listMethodArgumentImplementations(iMethodName) as mai>
					<#if mai.methodArgument?exists>
						<#assign ma=mai.methodArgument.idref>
						<#if ma.type=="attribute">
							<#if ((common.getComponentNameFromMethodArgument(ma)==a.componentName) && (ma.attribute.idref.name==iAttributeName))>
								<#local attributesList=attributesList+[{
									"componentName":a.componentName, 
									"attributeName":attributeName, 
									"attributeImplementation":ai, 
									"methodArgumentImplementation":mai}]>
								<#break>
							</#if>					
						</#if>
					<#elseif mai.attributeImplementation?exists>
						<#if mai.attributeImplementation.idref==ai>
							<#local attributesList=attributesList+[{
								"componentName":a.componentName, 
								"attributeName":attributeName, 
								"attributeImplementation":ai, 
								"methodArgumentImplementation":mai}]>
							<#break>
						</#if>
					<#else>
						${logger.warn(object, "Failed to list UsedPersistentAttributes for Method ${iMethodName}, Component ${iComponentName} and Attibute ${iAttributeName}")}
					</#if>
				</#list>
			</#list>		
		</#if>
	</#list>

	<#return attributesList>
</#function>

<#function listProtectedMethods>
	<#local container=[{
		"methodName":"Read"
	}]>		
	<#list object.methodImplementation as m>
		<#if !common.isQueryMethod(m)>
			<#local container=container+[{
				"methodName":common.getNameFromMethodImplementation(m),
				"methodImplementation":m
			}]>
		</#if>
	</#list>
	<#return container>
</#function>

<#function listTables>
	<#local container=[]>
	<#list listProtectedComponents() as c>
		<#list c.componentImplementation.componentImplementationTable as ct>
			<#local table={
				"tableName":ct.table.idref.name,
				"table":ct.table.idref,
				"isRootTable":ct.isRootTable,
				"isReferentialIntegrityTable":ct.isReferentialIntegrityTable
			}>
			<#if !container?seq_contains(table)>
				<#local container=container+[table]>
			</#if>
		</#list>
	</#list>
	<#return container>	
</#function>

<#function calculatedFieldPresent>
	<#list listProtectedComponents() as c>
		<#list c.componentImplementation.attributeImplementation as attributeImplementation>
			<#if attributeImplementation.type == "calculated">
				<#return true>			
			</#if>
		</#list>			
	</#list>
	<#return false>
</#function>

<#function isFunctionServerComponent iComponentImplementation>
	<#list iComponentImplementation.componentImplementationTable as componentImplementationTable>
		<#if componentImplementationTable.table.idref.type == "form">
			<#return true>			
		</#if>
	</#list>
	<#return false>
</#function>

<#function generateFunctionServer>
	<#list listProtectedComponents() as c>
		<#if isFunctionServerComponent(c.componentImplementation) == true>
			<#return true>			
		</#if>
	</#list>
	<#return false>
</#function>
 

<#function getBaanDataInitializers iAttributeImplementation>
	<#assign datatype = common.get_BaanDatatype_from_XMLSchemaDatatype(common.getDatatype(iAttributeImplementation))>
	<#switch datatype>
	  	<#case "DB.LONG">
	  	<#case "DB.DATE">
	  	<#case "DB.TIME">
	  	<#case "DB.TEXT">
			<#return "0">
	  	<#case "DB.DOUBLE">
		<#case "DB.FLOAT">
			<#return "0.0">
	  	<#case "DB.STRING">
			<#return "\"\"">
	  	<#case "DB.ENUM">
			<#return "empty">
		<#case "DB.BOOLEAN">
			<#return "false">	  	
		<#default>
			<#return "">
	</#switch>  
</#function>

<#--#unused.so--
<#function getMAX_QUERY_STRUCT>
<#-- 	
	Max number of queries.Every component results in a seperate 
	query and each individual protected associated attribute 
	results in another query.
-- >
	<#local queryCounter=0>
	<#list listProtectedComponents() as c>
		<#local queryCounter=queryCounter+1>
		<#list listProtectedAssociatedAttributes(c.componentImplementation) as aa>
			<#local queryCounter=queryCounter+1>
		</#list>
	</#list>
	<#return queryCounter>
</#function>

<#function getMAX_QUERY_LEVEL iComponentImplementation="">
<#--
	Max depth of the component hierarchy.
	Every component results in a seperate level and protected 
	associated attribute in the deepest component results in 
	another level.
-- >
	<#if iComponentImplementation!="">
		<#local current=0>
		<#if (listProtectedAssociatedAttributes(iComponentImplementation)?size!=0)>
			<#local current=1>
		</#if>
		
		<#local hierarchy=0>
		<#list iComponentImplementation.relationshipImplementation as relationshipImplementation>
			<#if relationshipImplementation.relationship?has_content && relationshipImplementation.relationship.idref.type=="aggregation">
				<#local level=getMAX_QUERY_LEVEL(relationshipImplementation.componentImplementation)>
				<#if hierarchy < level>
					<#local hierarchy=level>
				</#if>
			</#if>
		</#list>
			
		<#if current < hierarchy>
			<#return hierarchy+1>
		</#if>
		<#return current+1>
	</#if>
	<#return getMAX_QUERY_LEVEL(object)>
</#function>
<#--#unused.eo-->

<#function ReducedExecs>
	<#-- Reduced execs is calculated as follows.
		 Default set to true.
		 except:
		 	- nr.components = 0 (not possible anymore >> skip)
		 	- forced.fetches = true (See below >> skip)
		 	- calc.relation.attr.present (not possible anymore >> skip)
		 	- relation to parent table where column is not part of the index.
	-->
	<#return true>
</#function>

<#--#unused.so--
<#function ForcedFetches>
	<#-- Forced fetches is programmed in templates and tlbctdll1222.
	     But a search for usage of this result in no records. 
	     So is not used in current BOL's, So put to false
	-- >
	<#return false>
</#function>

<#function BDE_ReadPresent>
	<#-- BDE Read present.
		 This means that data should be read from other BDE's.
		 Data will not be read by reference in hte parent query.
		 Special 'private.read' functions will be created.
	-- >
	<#list listProtectedComponents() as c>
		<#list listProtectedAssociatedAttributes(c.componentImplementation) as aa>
			<#return true>
		</#list>
	</#list>
	<#return false>
</#function>

<#function MaxTableBufLength>
	<#--
		Contains the maximum record length of tables. Needed for buffering rcd.records...
		So whem a table contains 3 fields.
			field1 = string van 30 			>> 30
			field2 = enum 					>> 1
			field3 = double 				>> 8
			======================================
			Totale lengte					>> 39
			
	TODO: make dynamic in QueryInit
	-- >
	<#return "1024">
</#function>


<#function MaxNrRel>
	<#--	Contians the maxmimum number of tables in a query.
				queryNR | nr. tables.
					1   |   1
					2   |   3
					3	|   2
				MaxNrRel = 3				
	-- >
	<#local maxNrRel=0>
	<#list listProtectedComponents() as c>
		<#local size=c.componentImplementation.componentImplementationTable?size>
		<#if maxNrRel < size>
			<#local maxNrRel=size>
		</#if>
	</#list>
	<#return maxNrRel>
</#function>

<#function MaxNrColumns>
	<#local maxNrCols=MaxNrCols()>
	<#local maxNrFields=MaxNrFields()>
	<#if maxNrCols < maxNrFields >
		<#local maxNrCols=maxNrFields> 
	</#if>
	<#list listProtectedComponents() as c>
		<#local size=c.componentImplementation.attributeImplementation?size>
		<#if maxNrCols < size>
				<#local maxNrCols=size>
		</#if>
	</#list>
	<#return 3*maxNrCols+10><#-- in case of calculations, maximum nr of columns is insufficient -->
				<#-- because the arrays contain elements for each combination of attribute implementation and column -->
				<#-- Note: this is a workaround!! -- 
</#function>

<#function MaxNrCols>
	<#local maxNrCols=MaxNrRel()>
	<#list listProtectedComponents() as c>
		<#if c.relationshipImplementation!="">
			<#local size=common.listRelationshipDetails(c.componentImplementation,c.relationshipImplementation)?size>
			<#if maxNrCols < size>
				<#local maxNrCols=size>
			</#if>
		</#if>
	</#list>
	<#return maxNrCols>
</#function>

<#function MaxNrFields>
	<#local maxNrFields=0>
	<#list listProtectedComponents() as c>
		<#list c.componentImplementation.componentImplementationTable as cit>
			<#local size=cit.table.idref.column?size>
			<#if maxNrFields < size>
				<#local maxNrFields=size>
			</#if>
		</#list>
	</#list>
	<#return maxNrFields>
</#function>


<#function MaxCondLength>
	<#--	Conditie die aan een relatie kunnen hangen. 
			Dus bijv. op een tabel staat dat de attriubuut 'x' > 0 moet zijn,
			 of 'x' moet een vast waarde hebben.. 
			Dit is 'vrije' tekst. En wordt vertaald naar een conditie die in 
			 de where clause komt. 
			De maximale grootte van de condities is MaxCondLength. dit is niet de som van 
			alle condities, maar de grootste.
	-- >
	<#return 1>
</#function>
<#--#unused.eo-->

<#function handleObject iMethodName iTable>
	<#if (!iTable.isReferentialIntegrityTable &&
		   (iMethodName=="Create" ||
		 	iMethodName== "Change" ||
		 	iMethodName== "Delete")) ||
		 (iTable.isReferentialIntegrityTable &&
		   (iMethodName== "DeleteRef" ||
		 	iMethodName== "CreateRef"))>
		 	<#return true>
	</#if>
	<#return false>
</#function>

<#function fillArrayField iAttributeImplementation>
<#-- #VERS.sn -->
	<#return fillArrayFieldForColumn(iAttributeImplementation, iAttributeImplementation.column.idref)>
</#function>

<#function fillArrayFieldForColumn iAttributeImplementation iColumn>
<#-- #VERS.en -->
	<#assign array=false>
	<#assign arrayFLD=""> <#-- "" or "(3)" or "(1, 3)" for example -->
	<#assign arrayDEF="">
	<#assign arrayDEFLNG="">
	<#assign arrayDEFSTR="">
	<#assign arrayOPT="">
	<#assign arrayPOS=0>
<#-- #VERS.o	<#if iAttributeImplementation.column.idref.datatype.idref.dimensions?exists>  -->
<#-- #VERS.sn -->
	<#if iColumn.datatype.idref.dimensions?exists> 
<#-- #VERS.en -->
		<#assign array=true>
		<#assign arrayDEF=".ARRAY">
		<#assign arrayDEFLNG=".ARRAY.LONG">
		<#assign arrayDEFSTR=".ARRAY.STRING">
		<#assign arrayPOS=1>
		<#if iAttributeImplementation.additionalInstructions?exists>
			<#assign arrayPOS=iAttributeImplementation.additionalInstructions>
		</#if>
		<#assign arrayOPT=", "+arrayPOS>
<#-- #VERS.o	<#if common.get_BaanDatatype_from_XMLSchemaDatatype(iAttributeImplementation.column.idref.datatype.idref)=="DB.STRING"> -->
<#-- #VERS.sn -->
		<#if common.get_BaanDatatype_from_XMLSchemaDatatype(iColumn.datatype.idref)=="DB.STRING">
<#-- #VERS.en -->
			<#assign arrayFLD="(1,"+arrayPOS+")">
		<#else>
			<#assign arrayFLD="("+arrayPOS+")">
		</#if>
		<#if iAttributeImplementation.additionalInstructions?exists>
			<#assign arrayPOS=iAttributeImplementation.additionalInstructions>
		</#if>
<#-- #VERS.o	</#if><#--if iattributeImplementation.column.idref.datatype.idref.dimensions?exists-->
<#-- #VERS.sn -->
	</#if> <#-- iColumn.datatype.idref.dimensions?exists-->
<#-- #VERS.en -->
	<#assign container={
				"array":array,
				"arrayFLD":arrayFLD, 
				"arrayPOS":arrayPOS,
				"arrayDEF":arrayDEF,
				"arrayDEFLNG":arrayDEFLNG,
				"arrayDEFSTR":arrayDEFSTR,	
				"arrayOPT":arrayOPT
			}>
	<#return container>
</#function>

<#function executeMethodHookPresent iType imethodImplementation>
	<#assign meth=imethodImplementation>
	<#assign hookPresent=false>
	<#switch iType>
		<#case "before">
			<#assign hookPresent=meth.beforeExecuteHookExpression?exists && meth.beforeExecuteHookExpression?has_content>
			<#if hookPresent>
				<#assign hook=meth.beforeExecuteHookExpression>
			</#if>
			<#break>
		<#case "after">
			<#assign hookPresent=meth.afterExecuteHookExpression?exists && meth.afterExecuteHookExpression?has_content>
			<#if hookPresent>
				<#assign hook=meth.afterExecuteHookExpression>
			</#if>
			<#break>
		<#case "on">
			<#assign hookPresent=meth.onExecuteHookExpression?exists && meth.onExecuteHookExpression?has_content>
			<#if hookPresent>
				<#assign hook=meth.onExecuteHookExpression>
			</#if>
			<#break>
	</#switch>
	<#if hookPresent>
		<#if !(hook?contains("return"))>
			${logger.warn(object,"${iType}ExecuteHook for method ${common.getNameFromMethodImplementation(meth)} does not contain a return value.")}
		</#if>
		<#return true>
	</#if>
	<#return false>
</#function>

<#function getAttributeHookArguments iAttributeImplementation>
	<#assign hookArguments=[]>
	<#list iAttributeImplementation.attributeImplementationRelationship?sort_by("position") as air>
		<#if air.attributeImplementation.idref.scope?exists>
			<#assign scope=air.attributeImplementation.idref.scope>
		<#else>
			<#assign scope="">
		</#if>
		<#assign hookArguments = hookArguments +[{
			"name":common.getAttributeName(air.attributeImplementation.idref),
			"scope":scope,
			"domain":common.getDatatypeName(common.getDatatype(air.attributeImplementation.idref)),
			"hasDimensions":common.getMandatoryDatatype(air.attributeImplementation.idref).dimensions?exists
			}]>
	</#list>
	<#return hookArguments>
</#function>

<#function updateAttributeList iAttributeList iFullName>
	<#list iAttributeList as a>
		<#if a.fullname==iFullName>
			<#assign found = true>
			<#if a.scope=="out">
				<#assign a = [{"name":a.name,
							"fullname":a.fullname,
							"scope":"inout",
							"domain":a.domain,
							"hasDimensions":a.hasDimensions,
							"attributeImplementation":a.attributeImplementation
							}]>>
			</#if>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function addDerivedAttributes iAttributeList iHookArguments>
	<#assign attributeList = iAttributeList>
	<#assign newDeriveds = []>
	<#assign newDerivedsFound = false>
	<#list iHookArguments as a>
		<#list a.attributeImplementation.attributeImplementationRelationship as air>
			<#assign ai = air.attributeImplementation.idref>
			<#assign ciName = air.componentImplementation.idref.component>
			<#if !updateAttributeList(attributeList, ciName + "." + ai.name)>
				<#assign attributeList = attributeList + [{
							"name":ai.name,
							"fullname":ciName + "." + ai.name,
							"scope":"in",
							"domain":common.getDatatypeName(common.getDatatype(ai)),
							"hasDimensions":common.getMandatoryDatatype(ai).dimensions?exists,
							"attributeImplementation":ai
							}]>
				<#assign newDeriveds = newDeriveds + [{
							"name":ai.name,
							"fullname":ciName + "." + ai.name,
							"scope":"in",
							"domain":common.getDatatypeName(common.getDatatype(ai)),
							"hasDimensions":common.getMandatoryDatatype(ai).dimensions?exists,
							"attributeImplementation":ai
							}]>
				<#assign newDerivedsFound = true>
			</#if>
		</#list>
	</#list>
	<#if newDerivedsFound>
		<#assign attributeList = addDerivedAttributes(attributeList, newDeriveds)>
	</#if>
	<#return attributeList>
</#function>

<#function getMethodHookArguments iHookType iMethodName iComponentName>
	<#assign hookArguments=[]>
	<#list listProtectedAttributes(iMethodName, iComponentName)?sort_by("position") as pa>
		<#if iHookType!="before" || pa.scope!= "out">
			<#assign hookArguments = hookArguments +[{
				"name":pa.attributeName,
				"fullname":pa.componentName+"."+pa.attributeName,
				"scope":pa.scope,
				"domain":common.getDatatypeName(common.getDatatype(pa.attributeImplementation)),
				"hasDimensions":common.getMandatoryDatatype(pa.attributeImplementation).dimensions?exists,
				"attributeImplementation":pa.attributeImplementation
				}]>
		</#if><#--if iHookType!="before" || pa.scope!= "out"-->
	</#list>
	<#assign hookarguments = addDerivedAttributes(hookArguments, hookArguments)>
	<#return hookArguments>
</#function>

<#function generateIoDefaultInOnExecuteHook iMethodName iProcessingOrder>
	<#if iProcessingOrder == "batch">
		<#switch iMethodName>
			<#case "SubscribeList">
			<#case "SubscribeEvent">
			<#case "UnSubscribeEvent">
			<#case "PublishEvent">
			<#case "OnEvent">
			<#case "SupportsReferentialIntegrity">
				<#return true>
		</#switch>
	<#else>
		<#switch iMethodName>
			<#case "Create">
			<#case "Change">
			<#case "Delete">
			<#case "CreateRef">
			<#case "DeleteRef">
				<#return true>
		</#switch>
	</#if>
	<#return false>
</#function>

<#macro RETIFNOKINITFIN_COMPONENT iComponent iMethod iFun iCancel=false iAfter=false iHookType="" iQueryMethod=false iNoDefault=false iRestoreDalContext=false>
	<#local methodName = common.getNameFromMethodImplementation(iMethod)>
	<#local FunArg="">
	<#if iHookType == "">
	bl.result = ${iFun}()
	<#else>
		<#local ExArgs="">
		<#if iHookType == "before">
			<#local ExArgs="io.cancel">
			<#if common.isQueryMethod(methodName)>
				<#local ExArgs="bl.filter, "+ExArgs>		
			</#if>
		</#if><#--if iHookType == "before"-->
		<#if iHookType == "on">
			<#if common.isQueryMethod(methodName)>
				<#local ExArgs="bl.filter, anythingFetched">
			<#else>
				<#if !iNoDefault>
					<#local ExArgs="loc.default">
				</#if>
			</#if>
		</#if><#--if iHookType == "on"-->
		<#if iHookType == "after">
			<#if common.isQueryMethod(methodName)>
				<#local ExArgs="anythingFetched">		
			</#if>
		</#if><#--if iHookType == "after"-->
		<#local args=false>
		<#list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg>
			<#local args=true>
			<#if hookarg_index == 0>
	bl.result = ${iFun}(
			</#if><#--if hookarg_index == 0-->
				bl.${hookarg.fullname},
			<#if hookarg_has_next>
				bl.${hookarg.fullname}.set,
			<#else><#--if hookarg_has_next-->
				<#if ExArgs == "">
				bl.${hookarg.fullname}.set)
				<#else><#--if ExArgs == ""-->
				bl.${hookarg.fullname}.set, ${ExArgs})
				</#if><#--if ExArgs == ""-->
				|*ExArg "${ExArgs}"
			</#if><#--if a_has_next-->
		</#list><#--list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg-->
		<#if !args>
	bl.result = ${iFun}(${ExArgs})
		</#if><#--if !args-->
	</#if>
	if bl.result <> 0 then
		bl.${iComponent.componentName}.initialize = false
		bl.method.result = bl.result
	<#if iAfter && executeMethodHookPresent("after", iMethod)>
		<#if iCancel >
			<#local args=false>
			<#list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg>
				<#local args=true>
				<#if hookarg_index == 0>
			bl.ret = "Hook.AfterExecute."+${hookarg.fullname}(
				</#if><#--if hookarg_index == 0-->
				<#if hookarg_has_next>
				bl.${hookarg.fullname},
				<#else><#--if hookarg_has_next-->
				bl.${hookarg.fullname})
				</#if><#--if hookarg_has_next-->
			</#list><#--list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg-->
			<#if !args>	
			bl.ret = "Hook.AfterExecute."${iComponent.componentName}.${methodName}(
			</#if><#--if !args-->
		<#else><#--if iCancel-->
			<#local args=false>
			<#list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg>
				<#local args=true>
				<#if hookarg_index == 0>
		bl.ret = "Hook.AfterExecute."+${hookarg.fullname}(
				</#if><#--if hookarg_index == 0-->
				<#if hookarg_has_next>
				bl.${hookarg.fullname},
				<#else><#--if hookarg_has_next-->
				bl.${hookarg.fullname})
				</#if><#--if hookarg_has_next-->
			</#list><#--list getMethodHookArguments(iHookType, methodName, iComponent.componentName) as hookarg-->
			<#if !args>
		bl.ret = "Hook.AfterExecute."+${iComponent.componentName}.${methodName}(
			</#if><#--if !args-->		
		</#if><#--if iCancel-->
	</#if><#--f iAfter && executeMethodHookPresent("after", iMethod)-->
		<#if iQueryMethod>
		bl.${iComponent.componentName}.query.status = QUERY.ERROR
		<#else>
		bl.ret = ${names.packageName}${names.moduleName}.bl${names.businessObjectID}st00.finalize.${methodName}(bl.result)
		</#if>
		error.bypass = 0
		<#if iRestoreDalContext>
		dal.set.context(hold.context)
		</#if>
		return(bl.result)
	endif
</#macro>

<#function fillDefaultStruct iDefaultValue iDefaultPresent iWhere iDimensions=0>
	<#if iDefaultValue=="">
			<#assign defaultX={
			"value":"",
			"present":false,
			"where":iWhere,
			"dimensions":iDimensions}>
	<#else>
		<#assign defaultX={
			"value":iDefaultValue,
			"present":iDefaultPresent,
			"where":iWhere,
			"dimensions":iDimensions}>
	</#if>
	<#return defaultX>
</#function>

<#function getDefaultValueFromMethodArgumentImplementation iMethodArgumentImplementation>
	<#assign defaultX=fillDefaultStruct("", false, "Not found")>
	<#assign datatype=common.getDatatypeFromMethodArgumentImplementation(iMethodArgumentImplementation)>
	<#if datatype != "" && datatype.dimensions?exists>
		<#assign dimensions=datatype.dimensions>
	<#else>
		<#assign dimensions=0>
	</#if>

	<#if iMethodArgumentImplementation.defaultValue?exists && iMethodArgumentImplementation.defaultValue!="">
		<#assign defaultX=fillDefaultStruct(iMethodArgumentImplementation.defaultValue, true, 
			"MethodArgumentImplementation.defaultValue", dimensions)>
	<#elseif iMethodArgumentImplementation.attributeImplementation.idref.defaultValue?exists &&
			 iMethodArgumentImplementation.attributeImplementation.idref.defaultValue!="">
			<#assign defaultX=fillDefaultStruct(iMethodArgumentImplementation.attributeImplementation.idref.defaultValue,
			true, "AttributeImplementation.defaultValue", dimensions)>
	</#if>
	<#if defaultX.present && defaultX.value!="">
		<#switch common.get_BaanDatatype_from_XMLSchemaDatatype(common.getDatatypeFromMethodArgumentImplementation(iMethodArgumentImplementation))>
		  	<#case "DB.STRING">
				<#return fillDefaultStruct("\""+defaultX.value+"\"", true, defaultX.where,dimensions)>
		  	<#case "DB.ENUM">
				<#return fillDefaultStruct(datatype.nativeDatatype+"."+defaultX.value, true, defaultX.where,dimensions)>	  	
		</#switch>
	<#else>
		<#return fillDefaultStruct("", false, "Not found")>
	</#if>
	<#return defaultX>
</#function>

<#function getDefaultFromAttributeImplementation iAttributeImplementation>
	<#assign defaultX={ "value":"",
						"present":false,
						"dimensions":0}>
	<#assign dimensions=0>

	<#if iAttributeImplementation.defaultValue?exists>
		<#assign datatype=common.getDatatype(iAttributeImplementation)>
		<#if datatype.dimensions?exists>
			<#assign dimensions=datatype.dimensions>
		</#if>
		<#if iAttributeImplementation.defaultValue !="">
			<#assign defaultX={ "value":iAttributeImplementation.defaultValue,
							 	"present":true,
								"dimensions":dimensions}>
			<#switch common.get_BaanDatatype_from_XMLSchemaDatatype(datatype)>
			<#case "DB.STRING">
		  			<#assign defaultX={"value":"\""+defaultX.value+"\"", "present":true,
								"dimensions":dimensions}>
			  		<#break>
			<#case "DB.ENUM">
					<#assign defaultX={"value":datatype.nativeDatatype+"."+defaultX.value, "present":true,
								"dimensions":dimensions}>
					<#break>
			</#switch>
	 </#if>
	 </#if>
	 <#return defaultX>
</#function>

<#function usesAttribute iAttributeImplementation iUsesAttributeName>
	<#list iAttributeImplementation.attributeImplementationRelationship as air>
		<#if common.getAttributeName(air.attributeImplementation.idref)==iUsesAttributeName>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function listAttributesUsingAttribute iMethodName iComponentImplementation iUsesAttributeName iOnGetHook>
	<#local container=[]>
	<#list listProtectedAttributes(iMethodName, common.getComponentName(iComponentImplementation)) as p>
		<#if ((iOnGetHook && p.attributeImplementation.onGetHookExpression?exists && p.attributeImplementation.onGetHookExpression?has_content) ||
			  (!iOnGetHook && p.attributeImplementation.onSetHookExpression?exists && p.attributeImplementation.onSetHookExpression?has_content))>
			<#if usesAttribute(p.attributeImplementation, iUsesAttributeName)>
				<#local container=container+[p]>
				<#local aap=listAttributesUsingAttribute(iMethodName, iComponentImplementation, p.attributeName, iOnGetHook)>
				<#if aap?size!=0>
					<#local container=container+aap>
				</#if>
			</#if>
		</#if>
	</#list>
	<#return container>
</#function>

<#function listUsedAttributes iAttributeImplementation iOnGetHook>
	<#local usedAttributeImplementationList=[]>	
	<#list listUsedAttributesAA(iAttributeImplementation, iOnGetHook) as ua>
		<#if ua.attributeName!=common.getAttributeName(iAttributeImplementation)>
			<#local found=false>
			<#list usedAttributeImplementationList as dummy>
				<#if dummy.attributeName==ua.attributeName>
					<#local found=true>
					<#break>
				</#if>
			</#list>
			<#if !found>
				<#local usedAttributeImplementationList=usedAttributeImplementationList+[ua]>
			</#if>
		</#if>
	</#list>
	<#return usedAttributeImplementationList>
</#function>

<#function listUsedAttributesAA iAttributeImplementation iOnGetHook>
	<#local usedAttributeImplementationList=[{
		"attributeName":common.getAttributeName(iAttributeImplementation),
		"attributeImplementation":iAttributeImplementation,
		"datatype":common.getDatatypeFromAttributeImplementation(iAttributeImplementation)
	}]>
	<#if ((iOnGetHook && iAttributeImplementation.onGetHookExpression?exists && iAttributeImplementation.onGetHookExpression?has_content) ||
		  (!iOnGetHook && iAttributeImplementation.onSetHookExpression?exists && iAttributeImplementation.onSetHookExpression?has_content))>
		<#list iAttributeImplementation.attributeImplementationRelationship as air>		
			<#local usedAttributeImplementationList=listUsedAttributesAA(air.attributeImplementation.idref,iOnGetHook)+usedAttributeImplementationList>
		</#list>		
	</#if>
	<#return usedAttributeImplementationList>
</#function>

<#-- sorts all tables of a particular component using the table relations -->
<#-- Note: this algorithm works for at most five levels deep, recursion could
     not be implemented -->
<#function addComponentImplementationTableToList iListComponentTables iComponentImplementationTable iBottomUp>
	<#local listComponentTables=iListComponentTables>
	<#if !iBottomUp && !containedIn(iComponentImplementationTable.table.idref.name, listComponentTables)>
		<#local listComponentTables = listComponentTables + [iComponentImplementationTable.table.idref.name]>
	</#if>
	<#list iComponentImplementationTable.componentImplementationTableDetail as citd>
		<#if !iBottomUp && !containedIn(citd.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
			<#local listComponentTables = listComponentTables + [citd.toComponentImplementationTable.idref.table.idref.name]>
		</#if>
		<#list citd.toComponentImplementationTable.idref.componentImplementationTableDetail as citd2>
			<#if !iBottomUp && !containedIn(citd2.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
				<#local listComponentTables = listComponentTables + [citd2.toComponentImplementationTable.idref.table.idref.name]>
			</#if>
			<#list citd2.toComponentImplementationTable.idref.componentImplementationTableDetail as citd3>
				<#if !iBottomUp && !containedIn(citd3.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
					<#local listComponentTables = listComponentTables + [citd3.toComponentImplementationTable.idref.table.idref.name]>
				</#if>
				<#list citd3.toComponentImplementationTable.idref.componentImplementationTableDetail as citd4>
					<#if !iBottomUp && !containedIn(citd4.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
						<#local listComponentTables = listComponentTables + [citd4.toComponentImplementationTable.idref.table.idref.name]>
					</#if>
					<#list citd4.toComponentImplementationTable.idref.componentImplementationTableDetail as citd5>
						<#if !containedIn(citd5.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
							<#local listComponentTables = listComponentTables + [citd5.toComponentImplementationTable.idref.table.idref.name]>
						</#if>
					</#list>
					<#if iBottomUp && !containedIn(citd4.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
						<#local listComponentTables = listComponentTables + [citd4.toComponentImplementationTable.idref.table.idref.name]>
					</#if>
				</#list>
				<#if iBottomUp && !containedIn(citd3.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
					<#local listComponentTables = listComponentTables + [citd3.toComponentImplementationTable.idref.table.idref.name]>
				</#if>
			</#list>
			<#if iBottomUp && !containedIn(citd2.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
				<#local listComponentTables = listComponentTables + [citd2.toComponentImplementationTable.idref.table.idref.name]>
			</#if>
		</#list>
		<#if iBottomUp && !containedIn(citd.toComponentImplementationTable.idref.table.idref.name, listComponentTables)>
			<#local listComponentTables = listComponentTables + [citd.toComponentImplementationTable.idref.table.idref.name]>
		</#if>
	</#list>
	<#if iBottomUp && !containedIn(iComponentImplementationTable.table.idref.name, listComponentTables)>
		<#local listComponentTables = listComponentTables + [iComponentImplementationTable.table.idref.name]>
	</#if>
	<#return listComponentTables>
</#function>

<#function listOfComponentTables iComponent iBottomUp iFromTable="">
<#-- If iFromTable is filled only the iFromTable and the tables that refer to it will be included.
     If in this way the root table is not included, the list is extended so that the root table
     will be included as well.
     Algorithm: depending on the relations the tables of iComponent are sorted in a way, that for
     all tables A and B where a table column of A refers to B, table A is listed earlier than B.
     - If iFromTable is specified, the list is returned until iFromTable
     - If the root table occurs later in the list than iFromTable, the list is returned until root table
     - If iFromTable is not specified or it does not occur in the list, the whole list is returned.
-->
	<#local listComponentTables=[]>
	<#local rootTable="">
	<#list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable>
		<#local listComponentTables=addComponentImplementationTableToList(listComponentTables, componentImplementationTable, iBottomUp)>
		<#if componentImplementationTable.isRootTable>
			<#local rootTable=componentImplementationTable.table.idref.name>
		</#if><#--if componentImplementationTable.isRootTable-->
	</#list><#--list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable-->
	<#if iFromTable!="">
		<#local newListComponentTables=[]>
		<#local rootTableIncluded=false>
		<#local fromTableIncluded=false>
		<#list listComponentTables as table>
			<#local newListComponentTables = newListComponentTables + [table]>
			<#if table==iFromTable>
				<#local fromTableIncluded=true>
			</#if>
			<#if table==rootTable>
				<#local rootTableIncluded=true>
			</#if>
			<#if rootTableIncluded && fromTableIncluded>
				<#return newListComponentTables>
			</#if>
		</#list>
	</#if><#--if iFromTable!=""-->
	<#return listComponentTables>
</#function>

<#function getEmptyValue iPrimitiveDatatype>
	<#switch iPrimitiveDatatype>
	  	<#case "long">
	  	<#case "date">
	  	<#case "time">
	  	<#case "text">
			<#return "0">
	  	<#case "double">
			<#return "0.0">
	  	<#case "string">
			<#return "\"\"">
	  	<#case "enum">
			<#return "empty">
	</#switch>
	<#return "">
</#function>

<#-- function to return all identifying columns of a particular table -->
<#function listIdentifyingColumns iComponent iTableName>
	<#local columnList=[]>
	<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
		<#if attributeImplementation.type="column">
			<#list iComponent.componentImplementation.componentImplementationTable as cit>
				<#list cit.componentImplementationTableDetail as citd>
					<#if citd.toComponentImplementationTable.value==iTableName &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey>
						<#local columnList=columnList+[{
							"name":citd.toColumn.value,
							"emptyValue":getEmptyValue(citd.toColumn.idref.datatype.idref.primitiveDatatype)
							}]>
					</#if><#--if citd.toComponentImplementationTable.value==tableName &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey -->
				</#list><#--list cit.componentImplementationTableDetail as citd -->
			</#list><#--list c.componentImplementation.componentImplementationTable as cit -->
			<#if attributeImplementation.componentImplementationTable.value==iTableName &&
			     attributeImplementation.column.value==attributeImplementation.column.idref.name &&
			     attributeImplementation.column.idref.isPrimaryKey>
				<#local columnList=columnList+[{
					"name":attributeImplementation.column.value,
					"emptyValue":getBaanDataInitializers(attributeImplementation)
					}]>
			</#if><#--if attributeImplementation.componentImplementationTable.value==iTableName &&
			     attributeImplementation.column.value==attributeImplementation.column.idref.name &&
			     attributeImplementation.column.idref.isPrimaryKey -->
		</#if><#--if attributeImplementation.type="column"-->		
	</#list><#--list c.componentImplementation.attributeImplementation as attributeImplementation-->
	<#return columnList>
</#function>

<#-- function to return all identifying columns of a particular table -->
<#function listIdentifyingColumnsByCit iComponent iComponentImplementationTable>
	<#local columnList=[]>
	<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
		<#if attributeImplementation.type="column">
			<#list iComponent.componentImplementation.componentImplementationTable as cit>
				<#list cit.componentImplementationTableDetail as citd>
					<#if citd.toComponentImplementationTable.idref==iComponentImplementationTable &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey>
						<#local columnList=columnList+[{
							"name":citd.toColumn.value,
							"emptyValue":getEmptyValue(citd.toColumn.idref.datatype.idref.primitiveDatatype)
							}]>
					</#if><#--if citd.toComponentImplementationTable.idref==iComponentImplementationTable &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey -->
				</#list><#--list cit.componentImplementationTableDetail as citd -->
			</#list><#--list c.componentImplementation.componentImplementationTable as cit -->
			<#if attributeImplementation.componentImplementationTable.idref==iComponentImplementationTable &&
			     attributeImplementation.column.value==attributeImplementation.column.idref.name &&
			     attributeImplementation.column.idref.isPrimaryKey>
				<#local columnList=columnList+[{
					"name":attributeImplementation.column.value,
					"emptyValue":getBaanDataInitializers(attributeImplementation)
					}]>
			</#if><#--if attributeImplementation.componentImplementationTable.idref==iComponentImplementationTable &&
			     attributeImplementation.column.value==attributeImplementation.column.idref.name &&
			     attributeImplementation.column.idref.isPrimaryKey -->
		</#if><#--if attributeImplementation.type="column"-->		
	</#list><#--list c.componentImplementation.attributeImplementation as attributeImplementation-->
	<#return columnList>
</#function>

<#-- function to return all columns of a particular table that do not map to its parent table -->
<#function listAttributesNotMappedToOther iComponent iTableName>
	<#local attributeList=[]>
	<#local excludeList=[]>
	<#list listIdentifyingColumns(iComponent, iTableName) as column>
		<#local excludeList = excludeList + [column.name]>
	</#list><#--list listIdentifyingColumns(iComponent, iTableName) as column-->
	<#-- excludeList contains all columns that must not be included in the attributeList -->
	<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
		<#if attributeImplementation.type="column">
			<#if attributeImplementation.componentImplementationTable.value==iTableName &&
			     !containedIn(attributeImplementation.column, excludeList)>
				<#local attributeList=attributeList+[{
						"attribute":attributeImplementation.name,
						"attributeImplementation":attributeImplementation,
						"emptyValue":getBaanDataInitializers(attributeImplementation)
						}]>
			</#if><#--if attributeImplemetation.componentImplementationTable==iTableName &&
				!containedIn(attributeImplementation.column, excludeList)-->
		</#if><#--if attributeImplementation.type="column"-->		
	</#list><#--list c.componentImplementation.attributeImplementation as attributeImplementation-->
	<#return attributeList>
</#function>

<#-- function to return all columns of a particular table that do not map to its parent table -->
<#function listAttributesNotMappedToOtherByCit iComponent iComponentImplementationTable>
	<#local attributeList=[]>
	<#local excludeList=[]>
	<#list listIdentifyingColumnsByCit(iComponent, iComponentImplementationTable) as column>
		<#local excludeList = excludeList + [column.name]>
	</#list><#--list listIdentifyingColumnsByCit(iComponent, iComponentImplementationTable) as column-->
	<#-- excludeList contains all columns that must not be included in the attributeList -->
	<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
		<#if attributeImplementation.type="column">
			<#if attributeImplementation.componentImplementationTable.idref==iComponentImplementationTable &&
			     !containedIn(attributeImplementation.column, excludeList)>
				<#local attributeList=attributeList+[{
						"attribute":attributeImplementation.name,
						"attributeImplementation":attributeImplementation,
						"emptyValue":getBaanDataInitializers(attributeImplementation)
						}]>
			</#if><#--if attributeImplementation.componentImplementationTable.idref==iComponentImplementationTable &&
				!containedIn(attributeImplementation.column, excludeList)-->
		</#if><#--if attributeImplementation.type="column"-->		
	</#list><#--list c.componentImplementation.attributeImplementation as attributeImplementation-->
	<#return attributeList>
</#function>

<#function getParentTablesWithColumns iComponent iTableName>
	<#local columnList=[]>
	<#list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable>
		<#list componentImplementationTable.componentImplementationTableDetail as citd>
			<#if citd.toComponentImplementationTable.idref.table.idref.name==iTableName &&
			     componentImplementationTable.table.idref.name!=iTableName>
				<#local columnList=columnList+[{
				"parentTable":componentImplementationTable.table.idref,
				"name":citd.column.idref.name,
				"toName":citd.toColumn.idref.name
				}]>
			</#if><#--if citd.toComponentImplementationTable.idref.table.idref.name==iTableName &&
				     componentImplementationTable.table.idref.name!=iTableName -->
		</#list><#--list iComponentImplementationTable.componentImplementationTableDetail as citd-->
	</#list><#--list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable-->
	<#return columnList>
</#function>

<#function getParentTablesWithColumnsByCit iComponent iComponentImplementationTable>
	<#local columnList=[]>
	<#list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable>
		<#list componentImplementationTable.componentImplementationTableDetail as citd>
			<#if citd.toComponentImplementationTable.idref==iComponentImplementationTable &&
			     componentImplementationTable!=iComponentImplementationTable>
				<#local columnList=columnList+[{
				"parentTable":componentImplementationTable.table.idref,
				"name":citd.column.idref.name,
				"toName":citd.toColumn.idref.name
				}]>
			</#if><#--if citd.toComponentImplementationTable.idref.table.idref.name==iTableName &&
				     componentImplementationTable.table.idref.name!=iTableName -->
		</#list><#--list iComponentImplementationTable.componentImplementationTableDetail as citd-->
	</#list><#--list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable-->
	<#return columnList>
</#function>

<#function getTableRelationIdentifiers iComponent iTableName>
	<#local relationIdentifierList=[]>
	<#list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable>
		<#local table=componentImplementationTable.table.idref>
		<#if iTableName==table.name>
			<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
				<#if attributeImplementation.type="column">
					<#if attributeImplementation.column?exists && attributeImplementation.column.idref.isPrimaryKey>
						<#if protected.isMappedToTable(iComponent.componentImplementation, attributeImplementation, iTableName)>
							<#local relationIdentifierList=relationIdentifierList+[{
								"table": attributeImplementation.componentImplementationTable.idref.table.idref.name,
								"column": attributeImplementation.column.idref.name,
								"attribute":common.getAttributeName(attributeImplementation)
							}]>
						</#if><#--if protected.isMappedToTable(iComponent.componentImplementation, attributeImplementation, iTableName)-->
					</#if><#--if attributeImplementation.column?exists && attributeImplementation.column.idref.isPrimaryKey-->
					<#list iComponent.componentImplementation.componentImplementationTable as cit>
						<#list cit.componentImplementationTableDetail as citd>
							<#if citd.toComponentImplementationTable.idref.name==iTableName &&
							     citd.column.value==attributeImplementation.column.idref.name &&
							     citd.toColumn.idref.isPrimaryKey>
							<#local relationIdentifierList=relationIdentifierList+[{
								"table":citd.toComponentImplementationTable.idref.name,
								"column": citd.toColumn.idref.name,
								"attribute":common.getAttributeName(attributeImplementation)
							}]>
							</#if><#--if citd.toComponentImplementationTable.idref.name==iTableName &&
							     citd.column.value==attributeImplementation.column.idref.name &&
							     citd.toColumn.idref.isPrimaryKey -->
						</#list><#--list cit.componentImplementationTableDetail as citd -->
					</#list><#--list iComponent.componentImplementation.componentImplementationTable as cit -->
				</#if><#--if attributeImplementation.type="column"-->
			</#list><#--list iComponent.componentImplementation.attributeImplementation as attributeImplementation-->
			<#break>
		</#if><#--if iTableName=table.name-->
	</#list><#--list iComponent.componentImplementation.componentImplementationTable as componentImplementationTable-->
	<#return relationIdentifierList>
</#function>

<#function getTableRelationIdentifiersByCit iComponent iComponentImplementationTable>
	<#local relationIdentifierList=[]>
	<#list iComponent.componentImplementation.attributeImplementation as attributeImplementation>
		<#if attributeImplementation.type="column">
			<#if attributeImplementation.column?exists && attributeImplementation.column.idref.isPrimaryKey>
				<#if protected.isMappedToTableByCit(iComponent.componentImplementation, attributeImplementation, iComponentImplementationTable)>
					<#local relationIdentifierList=relationIdentifierList+[{
						"table": attributeImplementation.componentImplementationTable.idref.table.idref.name,
						"componentImplementationTable": attributeImplementation.componentImplementationTable.idref,
						"column": attributeImplementation.column.idref.name,
						"attribute":common.getAttributeName(attributeImplementation)
					}]>
				</#if><#--if protected.isMappedToTableByCit(iComponent.componentImplementation, attributeImplementation, iComponentImplementationTable)-->
			</#if><#--if attributeImplementation.column?exists && attributeImplementation.column.idref.isPrimaryKey-->
			<#list iComponent.componentImplementation.componentImplementationTable as cit>
				<#list cit.componentImplementationTableDetail as citd>
					<#if citd.toComponentImplementationTable==iComponentImplementationTable &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey>
					<#local relationIdentifierList=relationIdentifierList+[{
						"table":citd.toComponentImplementationTable.idref.name,
						"componentImplementationTable": citd.toComponentImplementationTable.idref,
						"column": citd.toColumn.idref.name,
						"attribute":common.getAttributeName(attributeImplementation)
					}]>
					</#if><#--if citd.toComponentImplementationTable==iComponentImplementationTable &&
					     citd.column.value==attributeImplementation.column.idref.name &&
					     citd.toColumn.idref.isPrimaryKey -->
				</#list><#--list cit.componentImplementationTableDetail as citd -->
			</#list><#--list iComponent.componentImplementation.componentImplementationTable as cit -->
		</#if><#--if attributeImplementation.type="column"-->
	</#list><#--list iComponent.componentImplementation.attributeImplementation as attributeImplementation-->
	<#return relationIdentifierList>
</#function>

<#macro declareDefines iUndef>
<#-- This macro declares the defines that are used in the st library. These
defines must be undefined before generating the hook code. This is done by using
declareDefines with iUndef=true. This is necessary because otherwise we will get
name clashes, for example if a hook uses a define like RETIFNOK.
Defines used in only one function need not be delcared here; they can be
undefined and undeffed in that function.
IMPORTANT: when adding defines to this macro, make sure you also add the
corresponding 'undef', and make sure they are not used after the moment they are
undefined (in code generated around hooks). -->
<#if !iUndef>
|******************************* Declare Defines ******************************
<#else>
|************* Undeclare defines (to prevent name clashes in hooks) ***********
</#if>

<#if !iUndef>
#define XmlNode	 long
#define MAX_RECURSION 75
	<#if names.applicationBackendRelease == "BaanERP5.0">
#define	CTX_INTEGRATION	1
#define	CTX_PROCESS	2
	</#if>
<#else>
#undef	XmlNode
#undef	MAX_RECURSION
	<#if names.applicationBackendRelease == "BaanERP5.0">
#undef	CTX_INTEGRATION
#undef	CTX_PROCESS
	</#if>
</#if>

<#if !iUndef>
#define RETIFNOK(...)
^       bl.result = ...
^	if bl.result <> 0 then
^		error.bypass = 0
^		return(bl.result)
^	endif

#define RETIFNOK_SYNC(...)
^       set.permission.for.readonly.attributes(true)
^       bl.result = ...
^       set.permission.for.readonly.attributes(false)
^       if bl.result <> 0 then
^               return(bl.result)
^       endif

#define SET.DAL.FIELD(FIELD, VALUE)
<#-- #VERS.o ^       if bl.##VALUE##.set then -->
<#-- #VERS.sn -->
^		if bl.##VALUE##.set and column.##FIELD##.exists() then
<#-- #VERS.en -->
^               dal.set.field("##FIELD##", bl.##VALUE##)
^       endif

#define SET.DAL.FIELD.ARRAY(FIELD, VALUE, ELEM)
<#-- #VERS.o ^       if bl.##VALUE##.set then -->
<#-- #VERS.sn -->
^		if bl.##VALUE##.set and column.##FIELD##.element.exists(##ELEM##) then
<#-- #VERS.en -->
^               dal.set.field("##FIELD##", bl.##VALUE##, ##ELEM##)
^       endif

#define SET.DAL.FIELD.ARRAY.LONG(FIELD, VALUE, ELEM)
<#-- #VERS.o ^       if bl.##VALUE##.set(##ELEM##) then -->
<#-- #VERS.sn -->
^		if bl.##VALUE##.set(##ELEM##) and column.##FIELD##.element.exists(##ELEM##) then
<#-- #VERS.en -->
^               dal.set.field("##FIELD##", bl.##VALUE##(##ELEM##), ##ELEM##)
^       endif

#define SET.DAL.FIELD.ARRAY.STRING(FIELD, VALUE, ELEM)
<#-- #VERS.o ^       if bl.##VALUE##.set(##ELEM##) then -->
<#-- #VERS.sn -->
^		if bl.##VALUE##.set(##ELEM##) and column.##FIELD##.element.exists(##ELEM##) then
<#-- #VERS.en -->
^               dal.set.field("##FIELD##", bl.##VALUE##(1, ##ELEM##), ##ELEM##)
^       endif

#define CHECK_TOOLS_VERSION_SHOW_AND_PUB(RETVAL)
^	| The Business Studio version used to generate this business object
^	| requires Enterprise Server 8.3 or higher including solution 236710 or 236711.
^	| If an older Enterprise Server version is used, the SubscribeEvent method will
^	| fail. So the ShowAndPublish... methods can immediately return 0
^	| (= OK), to avoid fatal errors when invoking non-existing tl code.
^	if not <@names.ST_DLLCode/>.is.business.studio.supported() then
^		return(RETVAL) | OK
^	endif

#define MESSAGE_EXISTS(MESS.CODE)
^	pos(form.text$(MESS.CODE), MESS.CODE) = 0
<#else>
#undef	RETIFNOK(...)
#undef	RETIFNOK_SYNC(...)
#undef	SET.DAL.FIELD(FIELD, VALUE)
#undef	SET.DAL.FIELD.ARRAY(FIELD, VALUE, ELEM)
#undef	SET.DAL.FIELD.ARRAY.LONG(FIELD, VALUE, ELEM)
#undef	SET.DAL.FIELD.ARRAY.STRING(FIELD, VALUE, ELEM)
#undef	CHECK_TOOLS_VERSION_SHOW_AND_PUB(RETVAL)
#undef	MESSAGE_EXISTS(MESS.CODE)
</#if>

<#if protected.generateFunctionServer()>
<#if !iUndef>
#define	SET.AFS.FIELD(ATTR)
^	if bl.##ATTR##.set then
^		AFS.set.##ATTR##(bl.##ATTR##)
^	endif

#define	SET.AFS.FIELD.ARRAY(ATTR, ELEM)
^	if bl.##ATTR##.set then
^		AFS.set.##ATTR##(bl.##ATTR##, ##ELEM##)
^	endif

#define	GET.AFS.FIELD(ATTR)
^	 bl.##ATTR## = AFS.get.##ATTR##()

#define	GET.AFS.FIELD.ARRAY(ATTR, ELEM)
^	 bl.##ATTR## = AFS.get.##ATTR##(##ELEM##)

#define	SET.AFS.SESSION(SESS)	bl.afs.session = SESS

#define SYNCHRONYZE.SESSION(Component, Method)
^ 	if not isspace(bl.##Component##.sync.session) then
<#if names.applicationBackendRelease != "BaanIV">
^		result = stpapi.synchronize.dialog(
^			bl.##Component##.main.session, "##Method##", bl.afs.err.mess)
^		if result <> 1 then
^			RETIFNOK(handle.result(AFS_ERROR))
^		endif
</#if><#--if names.applicationBackendRelease != "BaanIV"-->
^		SET.AFS.SESSION(bl.##Component##.sync.session)
^	else
^		SET.AFS.SESSION(bl.##Component##.main.session)
^	endif

#define	AFS_ERROR		-1234
<#else>
#undef	SET.AFS.FIELD(ATTR)
#undef	SET.AFS.FIELD.ARRAY(ATTR, ELEM)
#undef	GET.AFS.FIELD(ATTR)
#undef	GET.AFS.FIELD.ARRAY(ATTR, ELEM)
#undef	SET.AFS.SESSION(SESS)
#undef	SYNCHRONYZE.SESSION(Component, Method)
#undef	AFS_ERROR
</#if>
</#if><#--if protected.generateFunctionServer()-->

<#if !iUndef>
|******************************* User Helper Defines ***********************************
| Standard method to be used in hooks when forwarding a request to another BDE
| Return value is 0 (OK) or <> 0 (error value, but no error message set)
#define replaceBdeNameInRequest(oldRequest, newBdeName, newRequest)
^		tlbct.dll1000.replace.bde.name("request", "${names.businessInterfaceName}", oldRequest, newBdeName, newRequest)
#define replaceBdeNameInResponse(oldResponse, oldBdeName, newResponse)
^		tlbct.dll1000.replace.bde.name("response", oldBdeName, oldResponse, "${names.businessInterfaceName}", newResponse)
<#-- Helper define if the BOD delegates logic to a public BDE method and wants to
  use the BDE response XML in the  BOD to be published. For BDEs, 'xsi:nil'
  attributes may be set, but these must not be used in the BOD, because they are
  not defined in the BOD XSDs. The helper function removes these XML attributes. -->
	<#if object.businessInterfaceDefinition.idref.type=="bod">
#define removeNilAttributesInBdeResponse(response)
^		tlbct.dll1000.remove.nillable.attributes(response)
	</#if>

| Assisting method for SubscribeEvent when using multiple BIIs for a BID
#define removeStandardEventsFromRequest(io_request_xml, o_any_event_action_left)
^		tlbct.dll1000.remove.standard.events(io_request_xml, o_any_event_action_left)
|******************************* End of User Helper Defines ****************************
<#-- helper defines are used in hooks, so they must not be undeffed! -->
</#if>

<#if !iUndef>
#define ERR_IF(condition, component)
^	if condition then
^		dal.set.error.message("tlbctstgen", "PublishEvent", component, "${names.businessInterfaceName}")
^		|* Error occurred in Method '%1$s' on component '%2$s' of Object '%3$s'.
^		return(DALHOOKERROR)
^	endif
#define ERR_IF(condition)	ERR_IF(condition, "")
<#else>
#undef	ERR_IF(condition, component)
#undef	ERR_IF(condition)
</#if>
</#macro><#--declareDefines-->
