/*
 * IMPORTANT!!!! XSL Autogenerated class, DO NOT EDIT!!!!!
 * Template: Infrastructure9.0 [oneit.objstore.BusinessObjectTemplate.xsl]
 *   Vendor: Apache Software Foundation (Xalan XSLTC) (Version: 1.0)
 */

    
package performa.orm;

import java.io.*;
import java.util.*;
import oneit.appservices.config.*;
import oneit.logging.*;
import oneit.objstore.*;
import oneit.objstore.assocs.*;
import oneit.objstore.attributes.*;
import oneit.objstore.rdbms.filters.*;
import oneit.objstore.parser.*;
import oneit.objstore.validator.*;
import oneit.objstore.utils.*;
import oneit.utils.*;
import oneit.utils.filter.Filter;
import oneit.utils.transform.*;
import oneit.utils.parsers.FieldException;

import performa.orm.types.*;


public abstract class BaseWorkFlowStage extends BaseBusinessClass
{
    // Reference instance for the object
    public static final WorkFlowStage REFERENCE_WorkFlowStage = new WorkFlowStage ();

    // Reference instance for the object
    public static final WorkFlowStage DUMMY_WorkFlowStage = new DummyWorkFlowStage ();

    // Static constants corresponding to field names
    
    public static final String FIELD_Name = "Name";
    public static final String FIELD_UseMessaging = "UseMessaging";
    public static final String FIELD_StageType = "StageType";
    public static final String FIELD_SortOrder = "SortOrder";
    public static final String FIELD_AutoProgress = "AutoProgress";
    public static final String SINGLEREFERENCE_WithdrawalMessage = "WithdrawalMessage";
    public static final String SINGLEREFERENCE_WorkFlowTemplate = "WorkFlowTemplate";
    public static final String BACKREF_WorkFlowTemplate = "";
    public static final String MULTIPLEREFERENCE_WorkFlowMessages = "WorkFlowMessages";
    public static final String BACKREF_WorkFlowMessages = "";
    public static final String MULTIPLEREFERENCE_Steps = "Steps";
    public static final String BACKREF_Steps = "";

    // Static constants corresponding to searches
    public static final String SEARCH_All = "All";
    

    // Static constants corresponding to attribute helpers
    private static final DefaultAttributeHelper<WorkFlowStage> HELPER_Name = DefaultAttributeHelper.INSTANCE;
    private static final DefaultAttributeHelper<WorkFlowStage> HELPER_UseMessaging = DefaultAttributeHelper.INSTANCE;
    private static final EnumeratedAttributeHelper<WorkFlowStage, StageType> HELPER_StageType =  new EnumeratedAttributeHelper<WorkFlowStage, StageType> (StageType.FACTORY_StageType);
    private static final DefaultAttributeHelper<WorkFlowStage> HELPER_SortOrder = DefaultAttributeHelper.INSTANCE;
    private static final DefaultAttributeHelper<WorkFlowStage> HELPER_AutoProgress = DefaultAttributeHelper.INSTANCE;
    

    // Private attributes corresponding to business object data
    private String _Name;
    private Boolean _UseMessaging;
    private StageType _StageType;
    private Integer _SortOrder;
    private Boolean _AutoProgress;
    

    // Private attributes corresponding to single references
    private SingleAssociation<WorkFlowStage, WorkFlowMessage> _WithdrawalMessage;
    private SingleAssociation<WorkFlowStage, WorkFlowTemplate> _WorkFlowTemplate;
    

    // Private attributes corresponding to multiple references
    private MultipleAssociation<WorkFlowStage, WorkFlowMessage> _WorkFlowMessages;
    private MultipleAssociation<WorkFlowStage, WorkFlowStep> _Steps;
    

    // Map of maps of metadata
    private static final Map ATTRIBUTES_METADATA_WorkFlowStage = new LinkedHashMap ();

    // Arrays of validators for each attribute
    private static final AttributeValidator[] FIELD_Name_Validators;
    private static final AttributeValidator[] FIELD_UseMessaging_Validators;
    private static final AttributeValidator[] FIELD_StageType_Validators;
    private static final AttributeValidator[] FIELD_SortOrder_Validators;
    private static final AttributeValidator[] FIELD_AutoProgress_Validators;
    

    // Arrays of AttributeDecorators for each attribute
    private static final AttributeDecorator<WorkFlowStage, String>[] FIELD_Name_Decorators;
    private static final AttributeDecorator<WorkFlowStage, Boolean>[] FIELD_UseMessaging_Decorators;
    private static final AttributeDecorator<WorkFlowStage, StageType>[] FIELD_StageType_Decorators;
    private static final AttributeDecorator<WorkFlowStage, Integer>[] FIELD_SortOrder_Decorators;
    private static final AttributeDecorator<WorkFlowStage, Boolean>[] FIELD_AutoProgress_Decorators;
    
    
    // Arrays of SingleAssocDecorators for each attribute
    private static final SingleAssocDecorator<WorkFlowStage, WorkFlowMessage>[] SINGLEREFERENCE_WithdrawalMessage_Decorators;
    private static final SingleAssocDecorator<WorkFlowStage, WorkFlowTemplate>[] SINGLEREFERENCE_WorkFlowTemplate_Decorators;
    
    
    // Arrays of MultiAssocDecorators for each attribute
    private static final MultiAssocDecorator<WorkFlowStage, WorkFlowMessage>[] MULTIPLEREFERENCE_WorkFlowMessages_Decorators;
    private static final MultiAssocDecorator<WorkFlowStage, WorkFlowStep>[] MULTIPLEREFERENCE_Steps_Decorators;
    

    // Arrays of behaviour decorators
    private static final WorkFlowStageBehaviourDecorator[] WorkFlowStage_BehaviourDecorators;
    
    static
    {
        try
        {
            
            String tmp_WorkFlowMessages = WorkFlowMessage.BACKREF_WorkFlowStage;
            String tmp_Steps = WorkFlowStep.BACKREF_WorkFlowStage;
            String tmp_WorkFlowTemplate = WorkFlowTemplate.BACKREF_WorkFlowStages;
            
            Map  validatorMapping = ((Map)ConfigMgr.getConfigObject ("CONFIG.ORMVALIDATOR", "ValidatorMapping"));

            setupAssocMetaData_WorkFlowMessages();
            setupAssocMetaData_Steps();
            setupAssocMetaData_WithdrawalMessage();
            setupAssocMetaData_WorkFlowTemplate();
            FIELD_Name_Validators = (AttributeValidator[])setupAttribMetaData_Name(validatorMapping).toArray (new AttributeValidator[0]);
            FIELD_UseMessaging_Validators = (AttributeValidator[])setupAttribMetaData_UseMessaging(validatorMapping).toArray (new AttributeValidator[0]);
            FIELD_StageType_Validators = (AttributeValidator[])setupAttribMetaData_StageType(validatorMapping).toArray (new AttributeValidator[0]);
            FIELD_SortOrder_Validators = (AttributeValidator[])setupAttribMetaData_SortOrder(validatorMapping).toArray (new AttributeValidator[0]);
            FIELD_AutoProgress_Validators = (AttributeValidator[])setupAttribMetaData_AutoProgress(validatorMapping).toArray (new AttributeValidator[0]);
            FIELD_Name_Decorators = (AttributeDecorator[])AttributeDecoratorUtils.getAttributeDecorators(REFERENCE_WorkFlowStage, FIELD_Name).toArray (new AttributeDecorator[0]);
            FIELD_UseMessaging_Decorators = (AttributeDecorator[])AttributeDecoratorUtils.getAttributeDecorators(REFERENCE_WorkFlowStage, FIELD_UseMessaging).toArray (new AttributeDecorator[0]);
            FIELD_StageType_Decorators = (AttributeDecorator[])AttributeDecoratorUtils.getAttributeDecorators(REFERENCE_WorkFlowStage, FIELD_StageType).toArray (new AttributeDecorator[0]);
            FIELD_SortOrder_Decorators = (AttributeDecorator[])AttributeDecoratorUtils.getAttributeDecorators(REFERENCE_WorkFlowStage, FIELD_SortOrder).toArray (new AttributeDecorator[0]);
            FIELD_AutoProgress_Decorators = (AttributeDecorator[])AttributeDecoratorUtils.getAttributeDecorators(REFERENCE_WorkFlowStage, FIELD_AutoProgress).toArray (new AttributeDecorator[0]);
            SINGLEREFERENCE_WithdrawalMessage_Decorators = (SingleAssocDecorator[])AttributeDecoratorUtils.getSingleAssocDecorators(REFERENCE_WorkFlowStage, SINGLEREFERENCE_WithdrawalMessage).toArray (new SingleAssocDecorator[0]);
            SINGLEREFERENCE_WorkFlowTemplate_Decorators = (SingleAssocDecorator[])AttributeDecoratorUtils.getSingleAssocDecorators(REFERENCE_WorkFlowStage, SINGLEREFERENCE_WorkFlowTemplate).toArray (new SingleAssocDecorator[0]);
            MULTIPLEREFERENCE_WorkFlowMessages_Decorators = (MultiAssocDecorator[])AttributeDecoratorUtils.getMultiAssocDecorators(REFERENCE_WorkFlowStage, MULTIPLEREFERENCE_WorkFlowMessages).toArray (new MultiAssocDecorator[0]);
            MULTIPLEREFERENCE_Steps_Decorators = (MultiAssocDecorator[])AttributeDecoratorUtils.getMultiAssocDecorators(REFERENCE_WorkFlowStage, MULTIPLEREFERENCE_Steps).toArray (new MultiAssocDecorator[0]);
            

            REFERENCE_WorkFlowStage.initialiseReference ();
            DUMMY_WorkFlowStage.initialiseReference ();
            WorkFlowStage_BehaviourDecorators = BaseBusinessClass.getBBCBehaviours(WorkFlowStage.class).toArray(new WorkFlowStageBehaviourDecorator[0]);
        }
        catch (RuntimeException e)
        {
            LogMgr.log (BUSINESS_OBJECTS, LogLevel.SYSTEMERROR1, e, "Error initialising");
            throw e;
        }
    }

    
    private static void setupAssocMetaData_WorkFlowMessages()
    {
        Map metaInfo = new HashMap ();

        metaInfo.put ("backreferenceName", "WorkFlowStage");
        metaInfo.put ("name", "WorkFlowMessages");
        metaInfo.put ("type", "WorkFlowMessage");
        
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.WorkFlowMessages:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (MULTIPLEREFERENCE_WorkFlowMessages, Collections.unmodifiableMap (metaInfo));
    }
    
    
    private static void setupAssocMetaData_Steps()
    {
        Map metaInfo = new HashMap ();

        metaInfo.put ("backreferenceName", "WorkFlowStage");
        metaInfo.put ("name", "Steps");
        metaInfo.put ("type", "WorkFlowStep");
        
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.Steps:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (MULTIPLEREFERENCE_Steps, Collections.unmodifiableMap (metaInfo));
    }
    
    
    private static void setupAssocMetaData_WithdrawalMessage()
    {
        Map metaInfo = new HashMap ();

        metaInfo.put ("dbcol", "withdrawal_message_id");
        metaInfo.put ("name", "WithdrawalMessage");
        metaInfo.put ("type", "WorkFlowMessage");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.WithdrawalMessage:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (SINGLEREFERENCE_WithdrawalMessage, Collections.unmodifiableMap (metaInfo));
    }
    
    
    private static void setupAssocMetaData_WorkFlowTemplate()
    {
        Map metaInfo = new HashMap ();

        metaInfo.put ("backreferenceName", "WorkFlowStages");
        metaInfo.put ("dbcol", "work_flow_template_id");
        metaInfo.put ("mandatory", "true");
        metaInfo.put ("name", "WorkFlowTemplate");
        metaInfo.put ("type", "WorkFlowTemplate");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.WorkFlowTemplate:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (SINGLEREFERENCE_WorkFlowTemplate, Collections.unmodifiableMap (metaInfo));
    }
    
    
    private static List setupAttribMetaData_Name(Map validatorMapping)
    {
        Map  metaInfo   = new HashMap ();

        metaInfo.put ("dbcol", "name");
        metaInfo.put ("mandatory", "true");
        metaInfo.put ("name", "Name");
        metaInfo.put ("type", "String");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.Name:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (FIELD_Name, Collections.unmodifiableMap (metaInfo));

        List validators = BaseBusinessClass.getAttribValidators(WorkFlowStage.class, "Name", metaInfo, validatorMapping);
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Validators for WorkFlowStage.Name:", validators);        

        return validators;
    }
    
    private static List setupAttribMetaData_UseMessaging(Map validatorMapping)
    {
        Map  metaInfo   = new HashMap ();

        metaInfo.put ("dbcol", "use_messaging");
        metaInfo.put ("defaultValue", "Boolean.FALSE");
        metaInfo.put ("mandatory", "false");
        metaInfo.put ("name", "UseMessaging");
        metaInfo.put ("type", "Boolean");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.UseMessaging:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (FIELD_UseMessaging, Collections.unmodifiableMap (metaInfo));

        List validators = BaseBusinessClass.getAttribValidators(WorkFlowStage.class, "UseMessaging", metaInfo, validatorMapping);
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Validators for WorkFlowStage.UseMessaging:", validators);        

        return validators;
    }
    
    private static List setupAttribMetaData_StageType(Map validatorMapping)
    {
        Map  metaInfo   = new HashMap ();

        metaInfo.put ("attribHelper", "EnumeratedAttributeHelper");
        metaInfo.put ("dbcol", "stage_type");
        metaInfo.put ("mandatory", "true");
        metaInfo.put ("name", "StageType");
        metaInfo.put ("type", "StageType");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.StageType:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (FIELD_StageType, Collections.unmodifiableMap (metaInfo));

        List validators = BaseBusinessClass.getAttribValidators(WorkFlowStage.class, "StageType", metaInfo, validatorMapping);
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Validators for WorkFlowStage.StageType:", validators);        

        return validators;
    }
    
    private static List setupAttribMetaData_SortOrder(Map validatorMapping)
    {
        Map  metaInfo   = new HashMap ();

        metaInfo.put ("dbcol", "sort_order");
        metaInfo.put ("mandatory", "true");
        metaInfo.put ("name", "SortOrder");
        metaInfo.put ("type", "Integer");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.SortOrder:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (FIELD_SortOrder, Collections.unmodifiableMap (metaInfo));

        List validators = BaseBusinessClass.getAttribValidators(WorkFlowStage.class, "SortOrder", metaInfo, validatorMapping);
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Validators for WorkFlowStage.SortOrder:", validators);        

        return validators;
    }
    
    private static List setupAttribMetaData_AutoProgress(Map validatorMapping)
    {
        Map  metaInfo   = new HashMap ();

        metaInfo.put ("dbcol", "auto_progress");
        metaInfo.put ("defaultValue", "Boolean.FALSE");
        metaInfo.put ("mandatory", "false");
        metaInfo.put ("name", "AutoProgress");
        metaInfo.put ("type", "Boolean");
        metaInfo.put (METADATA_DB_TABLENAME, "tl_work_flow_stage");
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG2, "Metadata for WorkFlowStage.AutoProgress:", metaInfo);
        ATTRIBUTES_METADATA_WorkFlowStage.put (FIELD_AutoProgress, Collections.unmodifiableMap (metaInfo));

        List validators = BaseBusinessClass.getAttribValidators(WorkFlowStage.class, "AutoProgress", metaInfo, validatorMapping);
        LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Validators for WorkFlowStage.AutoProgress:", validators);        

        return validators;
    }
    
    // END OF STATIC METADATA DEFINITION    
    
    
    
    // This constructor should not be called
    protected BaseWorkFlowStage ()
    {
    }


    protected BBCBehaviourDecorator[] getBehaviours()
    {
        return WorkFlowStage_BehaviourDecorators;
    }

    


    protected void _initialiseNewObjAttributes (ObjectTransaction transaction) throws StorageException
    {
        super._initialiseNewObjAttributes (transaction);

        
        _Name = (String)(HELPER_Name.initialise (_Name));
        _UseMessaging = (Boolean)(Boolean.FALSE);
        _StageType = (StageType)(HELPER_StageType.initialise (_StageType));
        _SortOrder = (Integer)(HELPER_SortOrder.initialise (_SortOrder));
        _AutoProgress = (Boolean)(Boolean.FALSE);
    }


    protected void _initialiseAssociations ()
    {
        super._initialiseAssociations ();

        _WithdrawalMessage = new SingleAssociation<WorkFlowStage, WorkFlowMessage> (this, SINGLEREFERENCE_WithdrawalMessage, null, WorkFlowMessage.REFERENCE_WorkFlowMessage, "tl_work_flow_stage");
        _WorkFlowTemplate = new SingleAssociation<WorkFlowStage, WorkFlowTemplate> (this, SINGLEREFERENCE_WorkFlowTemplate, WorkFlowTemplate.MULTIPLEREFERENCE_WorkFlowStages, WorkFlowTemplate.REFERENCE_WorkFlowTemplate, "tl_work_flow_stage");
        _WorkFlowMessages = new MultipleAssociation<WorkFlowStage, WorkFlowMessage> (this, MULTIPLEREFERENCE_WorkFlowMessages, WorkFlowMessage.SINGLEREFERENCE_WorkFlowStage, WorkFlowMessage.REFERENCE_WorkFlowMessage);_Steps = new MultipleAssociation<WorkFlowStage, WorkFlowStep> (this, MULTIPLEREFERENCE_Steps, WorkFlowStep.SINGLEREFERENCE_WorkFlowStage, WorkFlowStep.REFERENCE_WorkFlowStep);
    }


    protected BaseBusinessClass initialiseReference ()
    {
        super.initialiseReference ();
        
        _WithdrawalMessage = new SingleAssociation<WorkFlowStage, WorkFlowMessage> (this, SINGLEREFERENCE_WithdrawalMessage, null, WorkFlowMessage.REFERENCE_WorkFlowMessage, "tl_work_flow_stage");
        _WorkFlowTemplate = new SingleAssociation<WorkFlowStage, WorkFlowTemplate> (this, SINGLEREFERENCE_WorkFlowTemplate, WorkFlowTemplate.MULTIPLEREFERENCE_WorkFlowStages, WorkFlowTemplate.REFERENCE_WorkFlowTemplate, "tl_work_flow_stage");
        _WorkFlowMessages = new MultipleAssociation<WorkFlowStage, WorkFlowMessage> (this, MULTIPLEREFERENCE_WorkFlowMessages, WorkFlowMessage.SINGLEREFERENCE_WorkFlowStage, WorkFlowMessage.REFERENCE_WorkFlowMessage);_Steps = new MultipleAssociation<WorkFlowStage, WorkFlowStep> (this, MULTIPLEREFERENCE_Steps, WorkFlowStep.SINGLEREFERENCE_WorkFlowStage, WorkFlowStep.REFERENCE_WorkFlowStep);
        
        return this;
    }


    /**
     * Attribute Name
     */
    public String getName ()
    {
        assertValid();
        String valToReturn = AttributeDecoratorUtils.getValue (FIELD_Name_Decorators, (WorkFlowStage)this, FIELD_Name, _Name);

        
        for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
        {
            valToReturn = bhd.getName ((WorkFlowStage)this, valToReturn);
        }

        return valToReturn;
    }


    /**
     * Called prior to the attribute changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preNameChange (String newName) throws FieldException
    {
    }


    /**
     * Called after the attribute changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postNameChange () throws FieldException
    {
    }

    
    public FieldWriteability getWriteability_Name ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

    /**
     * Set the attribute Name.  Checks to ensure a new value
     * has been supplied.  If so, marks the field as altered and sets the attribute.
     */
    public void setName (String newName) throws FieldException
    {
        newName = AttributeDecoratorUtils.setValue (FIELD_Name_Decorators, (WorkFlowStage)this, FIELD_Name, newName);

        boolean oldAndNewIdentical = HELPER_Name.compare (_Name, newName);
        
        try
        {
            for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
            {
                newName = bhd.setName ((WorkFlowStage)this, newName);
                oldAndNewIdentical = HELPER_Name.compare (_Name, newName);
            }

            BusinessObjectParser.assertFieldCondition (newName != null, this, FIELD_Name, "mandatory");
            

            if (FIELD_Name_Validators.length > 0)
            {
                Object newNameObj = HELPER_Name.toObject (newName);

                if (newNameObj != null)
                {
                    int     loopMax = FIELD_Name_Validators.length;
                    Map     metadata = (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (FIELD_Name);

                    for (int v = 0 ; v < loopMax ; ++v)
                    {
                        FIELD_Name_Validators[v].checkAttribute (this, FIELD_Name, metadata, newNameObj);
                    }
                }
            }
        }
        catch (FieldException e)
        {
            if (!oldAndNewIdentical)
            {
                e.setWouldModify ();
            }
            
            throw e;
        }

        if (!oldAndNewIdentical)
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (FIELD_Name_Decorators, (WorkFlowStage)this, FIELD_Name ,getWriteability_Name ()) != FieldWriteability.FALSE, "Field  Name is not writeable");
            preNameChange (newName);
            markFieldChange (FIELD_Name);
            _Name = newName;            
            postFieldChange (FIELD_Name);
            postNameChange ();
        }
    }

    /**
     * Attribute UseMessaging
     */
    public Boolean getUseMessaging ()
    {
        assertValid();
        Boolean valToReturn = AttributeDecoratorUtils.getValue (FIELD_UseMessaging_Decorators, (WorkFlowStage)this, FIELD_UseMessaging, _UseMessaging);

        
        for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
        {
            valToReturn = bhd.getUseMessaging ((WorkFlowStage)this, valToReturn);
        }

        return valToReturn;
    }


    /**
     * Called prior to the attribute changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preUseMessagingChange (Boolean newUseMessaging) throws FieldException
    {
    }


    /**
     * Called after the attribute changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postUseMessagingChange () throws FieldException
    {
    }

    
    public FieldWriteability getWriteability_UseMessaging ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

    /**
     * Set the attribute UseMessaging.  Checks to ensure a new value
     * has been supplied.  If so, marks the field as altered and sets the attribute.
     */
    public void setUseMessaging (Boolean newUseMessaging) throws FieldException
    {
        newUseMessaging = AttributeDecoratorUtils.setValue (FIELD_UseMessaging_Decorators, (WorkFlowStage)this, FIELD_UseMessaging, newUseMessaging);

        boolean oldAndNewIdentical = HELPER_UseMessaging.compare (_UseMessaging, newUseMessaging);
        
        try
        {
            for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
            {
                newUseMessaging = bhd.setUseMessaging ((WorkFlowStage)this, newUseMessaging);
                oldAndNewIdentical = HELPER_UseMessaging.compare (_UseMessaging, newUseMessaging);
            }

            

            if (FIELD_UseMessaging_Validators.length > 0)
            {
                Object newUseMessagingObj = HELPER_UseMessaging.toObject (newUseMessaging);

                if (newUseMessagingObj != null)
                {
                    int     loopMax = FIELD_UseMessaging_Validators.length;
                    Map     metadata = (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (FIELD_UseMessaging);

                    for (int v = 0 ; v < loopMax ; ++v)
                    {
                        FIELD_UseMessaging_Validators[v].checkAttribute (this, FIELD_UseMessaging, metadata, newUseMessagingObj);
                    }
                }
            }
        }
        catch (FieldException e)
        {
            if (!oldAndNewIdentical)
            {
                e.setWouldModify ();
            }
            
            throw e;
        }

        if (!oldAndNewIdentical)
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (FIELD_UseMessaging_Decorators, (WorkFlowStage)this, FIELD_UseMessaging ,getWriteability_UseMessaging ()) != FieldWriteability.FALSE, "Field  UseMessaging is not writeable");
            preUseMessagingChange (newUseMessaging);
            markFieldChange (FIELD_UseMessaging);
            _UseMessaging = newUseMessaging;            
            postFieldChange (FIELD_UseMessaging);
            postUseMessagingChange ();
        }
    }

    /**
     * Attribute StageType
     */
    public StageType getStageType ()
    {
        assertValid();
        StageType valToReturn = AttributeDecoratorUtils.getValue (FIELD_StageType_Decorators, (WorkFlowStage)this, FIELD_StageType, _StageType);

        
        for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
        {
            valToReturn = bhd.getStageType ((WorkFlowStage)this, valToReturn);
        }

        return valToReturn;
    }


    /**
     * Called prior to the attribute changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preStageTypeChange (StageType newStageType) throws FieldException
    {
    }


    /**
     * Called after the attribute changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postStageTypeChange () throws FieldException
    {
    }

    
    public FieldWriteability getWriteability_StageType ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

    /**
     * Set the attribute StageType.  Checks to ensure a new value
     * has been supplied.  If so, marks the field as altered and sets the attribute.
     */
    public void setStageType (StageType newStageType) throws FieldException
    {
        newStageType = AttributeDecoratorUtils.setValue (FIELD_StageType_Decorators, (WorkFlowStage)this, FIELD_StageType, newStageType);

        boolean oldAndNewIdentical = HELPER_StageType.compare (_StageType, newStageType);
        
        try
        {
            for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
            {
                newStageType = bhd.setStageType ((WorkFlowStage)this, newStageType);
                oldAndNewIdentical = HELPER_StageType.compare (_StageType, newStageType);
            }

            BusinessObjectParser.assertFieldCondition (newStageType != null, this, FIELD_StageType, "mandatory");
            

            if (FIELD_StageType_Validators.length > 0)
            {
                Object newStageTypeObj = HELPER_StageType.toObject (newStageType);

                if (newStageTypeObj != null)
                {
                    int     loopMax = FIELD_StageType_Validators.length;
                    Map     metadata = (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (FIELD_StageType);

                    for (int v = 0 ; v < loopMax ; ++v)
                    {
                        FIELD_StageType_Validators[v].checkAttribute (this, FIELD_StageType, metadata, newStageTypeObj);
                    }
                }
            }
        }
        catch (FieldException e)
        {
            if (!oldAndNewIdentical)
            {
                e.setWouldModify ();
            }
            
            throw e;
        }

        if (!oldAndNewIdentical)
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (FIELD_StageType_Decorators, (WorkFlowStage)this, FIELD_StageType ,getWriteability_StageType ()) != FieldWriteability.FALSE, "Field  StageType is not writeable");
            preStageTypeChange (newStageType);
            markFieldChange (FIELD_StageType);
            _StageType = newStageType;            
            postFieldChange (FIELD_StageType);
            postStageTypeChange ();
        }
    }

    /**
     * Attribute SortOrder
     */
    public Integer getSortOrder ()
    {
        assertValid();
        Integer valToReturn = AttributeDecoratorUtils.getValue (FIELD_SortOrder_Decorators, (WorkFlowStage)this, FIELD_SortOrder, _SortOrder);

        
        for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
        {
            valToReturn = bhd.getSortOrder ((WorkFlowStage)this, valToReturn);
        }

        return valToReturn;
    }


    /**
     * Called prior to the attribute changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preSortOrderChange (Integer newSortOrder) throws FieldException
    {
    }


    /**
     * Called after the attribute changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postSortOrderChange () throws FieldException
    {
    }

    
    public FieldWriteability getWriteability_SortOrder ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

    /**
     * Set the attribute SortOrder.  Checks to ensure a new value
     * has been supplied.  If so, marks the field as altered and sets the attribute.
     */
    public void setSortOrder (Integer newSortOrder) throws FieldException
    {
        newSortOrder = AttributeDecoratorUtils.setValue (FIELD_SortOrder_Decorators, (WorkFlowStage)this, FIELD_SortOrder, newSortOrder);

        boolean oldAndNewIdentical = HELPER_SortOrder.compare (_SortOrder, newSortOrder);
        
        try
        {
            for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
            {
                newSortOrder = bhd.setSortOrder ((WorkFlowStage)this, newSortOrder);
                oldAndNewIdentical = HELPER_SortOrder.compare (_SortOrder, newSortOrder);
            }

            BusinessObjectParser.assertFieldCondition (newSortOrder != null, this, FIELD_SortOrder, "mandatory");
            

            if (FIELD_SortOrder_Validators.length > 0)
            {
                Object newSortOrderObj = HELPER_SortOrder.toObject (newSortOrder);

                if (newSortOrderObj != null)
                {
                    int     loopMax = FIELD_SortOrder_Validators.length;
                    Map     metadata = (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (FIELD_SortOrder);

                    for (int v = 0 ; v < loopMax ; ++v)
                    {
                        FIELD_SortOrder_Validators[v].checkAttribute (this, FIELD_SortOrder, metadata, newSortOrderObj);
                    }
                }
            }
        }
        catch (FieldException e)
        {
            if (!oldAndNewIdentical)
            {
                e.setWouldModify ();
            }
            
            throw e;
        }

        if (!oldAndNewIdentical)
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (FIELD_SortOrder_Decorators, (WorkFlowStage)this, FIELD_SortOrder ,getWriteability_SortOrder ()) != FieldWriteability.FALSE, "Field  SortOrder is not writeable");
            preSortOrderChange (newSortOrder);
            markFieldChange (FIELD_SortOrder);
            _SortOrder = newSortOrder;            
            postFieldChange (FIELD_SortOrder);
            postSortOrderChange ();
        }
    }

    /**
     * Attribute AutoProgress
     */
    public Boolean getAutoProgress ()
    {
        assertValid();
        Boolean valToReturn = AttributeDecoratorUtils.getValue (FIELD_AutoProgress_Decorators, (WorkFlowStage)this, FIELD_AutoProgress, _AutoProgress);

        
        for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
        {
            valToReturn = bhd.getAutoProgress ((WorkFlowStage)this, valToReturn);
        }

        return valToReturn;
    }


    /**
     * Called prior to the attribute changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preAutoProgressChange (Boolean newAutoProgress) throws FieldException
    {
    }


    /**
     * Called after the attribute changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postAutoProgressChange () throws FieldException
    {
    }

    
    public FieldWriteability getWriteability_AutoProgress ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

    /**
     * Set the attribute AutoProgress.  Checks to ensure a new value
     * has been supplied.  If so, marks the field as altered and sets the attribute.
     */
    public void setAutoProgress (Boolean newAutoProgress) throws FieldException
    {
        newAutoProgress = AttributeDecoratorUtils.setValue (FIELD_AutoProgress_Decorators, (WorkFlowStage)this, FIELD_AutoProgress, newAutoProgress);

        boolean oldAndNewIdentical = HELPER_AutoProgress.compare (_AutoProgress, newAutoProgress);
        
        try
        {
            for (WorkFlowStageBehaviourDecorator bhd : WorkFlowStage_BehaviourDecorators)
            {
                newAutoProgress = bhd.setAutoProgress ((WorkFlowStage)this, newAutoProgress);
                oldAndNewIdentical = HELPER_AutoProgress.compare (_AutoProgress, newAutoProgress);
            }

            

            if (FIELD_AutoProgress_Validators.length > 0)
            {
                Object newAutoProgressObj = HELPER_AutoProgress.toObject (newAutoProgress);

                if (newAutoProgressObj != null)
                {
                    int     loopMax = FIELD_AutoProgress_Validators.length;
                    Map     metadata = (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (FIELD_AutoProgress);

                    for (int v = 0 ; v < loopMax ; ++v)
                    {
                        FIELD_AutoProgress_Validators[v].checkAttribute (this, FIELD_AutoProgress, metadata, newAutoProgressObj);
                    }
                }
            }
        }
        catch (FieldException e)
        {
            if (!oldAndNewIdentical)
            {
                e.setWouldModify ();
            }
            
            throw e;
        }

        if (!oldAndNewIdentical)
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (FIELD_AutoProgress_Decorators, (WorkFlowStage)this, FIELD_AutoProgress ,getWriteability_AutoProgress ()) != FieldWriteability.FALSE, "Field  AutoProgress is not writeable");
            preAutoProgressChange (newAutoProgress);
            markFieldChange (FIELD_AutoProgress);
            _AutoProgress = newAutoProgress;            
            postFieldChange (FIELD_AutoProgress);
            postAutoProgressChange ();
        }
    }



    /**
     * A list of multi assoc names e.g. list of strings.
     */
    public List<String> getSingleAssocs()
    {
        List result = super.getSingleAssocs ();
        
        result.add("WithdrawalMessage");
        result.add("WorkFlowTemplate");

        return result;
    }
    
    
    public BaseBusinessClass getSingleAssocReferenceInstance (String assocName)
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return _WithdrawalMessage.getReferencedType ();
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return _WorkFlowTemplate.getReferencedType ();
        }
        else
        {
            return super.getSingleAssocReferenceInstance (assocName);
        }
    }


    public String getSingleAssocBackReference(String assocName)
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return null ;
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return WorkFlowTemplate.MULTIPLEREFERENCE_WorkFlowStages ;
        }
        else
        {
            return super.getSingleAssocBackReference (assocName);
        }
    }
    
    
    public BaseBusinessClass getSingleAssoc (String assocName) throws StorageException
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return getWithdrawalMessage ();
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return getWorkFlowTemplate ();
        }
        else
        {
            return super.getSingleAssoc (assocName);
        }
    }


    public BaseBusinessClass getSingleAssoc (String assocName, Get getType) throws StorageException
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return getWithdrawalMessage (getType);
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return getWorkFlowTemplate (getType);
        }
        else
        {
            return super.getSingleAssoc (assocName, getType);
        }
    }


    public Long getSingleAssocID (String assocName) throws StorageException
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return getWithdrawalMessageID ();
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return getWorkFlowTemplateID ();
        }
        else
        {
            return super.getSingleAssocID (assocName);
        }
    }


    public void setSingleAssoc (String assocName, BaseBusinessClass newValue) throws StorageException, FieldException
    {
        if (assocName == null)
        {
            throw new RuntimeException ("Game over == null!");
        }
        else if (assocName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            setWithdrawalMessage ((WorkFlowMessage)(newValue));
        }
        else if (assocName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            setWorkFlowTemplate ((WorkFlowTemplate)(newValue));
        }
        else
        {
            super.setSingleAssoc (assocName, newValue);
        }
    }



    /**
     * Get the reference WithdrawalMessage
     */
    public WorkFlowMessage getWithdrawalMessage () throws StorageException
    {
        assertValid();
        
        try
        {
            return (WorkFlowMessage)(_WithdrawalMessage.get ());
        }
        catch (ClassCastException e)
        {
            LogMgr.log (BUSINESS_OBJECTS, LogLevel.SYSTEMERROR2, "Cache collision in WorkFlowStage:", this.getObjectID (), ", was trying to get WorkFlowMessage:",  getWithdrawalMessageID ());
            LogMgr.log (BUSINESS_OBJECTS, LogLevel.SYSTEMERROR2, "Instead I got:", _WithdrawalMessage.get ().getClass ());
            throw e;
        }
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public WorkFlowMessage getWithdrawalMessage (Get getType) throws StorageException
    {
        assertValid();
        return _WithdrawalMessage.get(getType);
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public Long getWithdrawalMessageID ()
    {
        assertValid();
        
        if (_WithdrawalMessage == null)
        {
            return null;
        }
        else
        {
            return _WithdrawalMessage.getID ();
        }
    }

    /**
     * Called prior to the assoc changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preWithdrawalMessageChange (WorkFlowMessage newWithdrawalMessage) throws FieldException
    {
    }


    /**
     * Called after the assoc changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postWithdrawalMessageChange () throws FieldException
    {
    }


    
    public FieldWriteability getWriteability_WithdrawalMessage ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

        
    /**
     * Set the reference WithdrawalMessage.  Checks to ensure a new value
     * has been supplied.  If so, marks the reference as altered and sets it.
     */
    public void setWithdrawalMessage (WorkFlowMessage newWithdrawalMessage) throws StorageException, FieldException
    {
        if (_WithdrawalMessage.wouldReferencedChange (newWithdrawalMessage))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (SINGLEREFERENCE_WithdrawalMessage_Decorators, (WorkFlowStage)this, SINGLEREFERENCE_WithdrawalMessage ,getWriteability_WithdrawalMessage ()) != FieldWriteability.FALSE, "Assoc WithdrawalMessage is not writeable");
            preWithdrawalMessageChange (newWithdrawalMessage);
            
            _WithdrawalMessage.set (newWithdrawalMessage);
                
            postWithdrawalMessageChange ();
        }
    }

    /**
     * Get the reference WorkFlowTemplate
     */
    public WorkFlowTemplate getWorkFlowTemplate () throws StorageException
    {
        assertValid();
        
        try
        {
            return (WorkFlowTemplate)(_WorkFlowTemplate.get ());
        }
        catch (ClassCastException e)
        {
            LogMgr.log (BUSINESS_OBJECTS, LogLevel.SYSTEMERROR2, "Cache collision in WorkFlowStage:", this.getObjectID (), ", was trying to get WorkFlowTemplate:",  getWorkFlowTemplateID ());
            LogMgr.log (BUSINESS_OBJECTS, LogLevel.SYSTEMERROR2, "Instead I got:", _WorkFlowTemplate.get ().getClass ());
            throw e;
        }
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public WorkFlowTemplate getWorkFlowTemplate (Get getType) throws StorageException
    {
        assertValid();
        return _WorkFlowTemplate.get(getType);
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public Long getWorkFlowTemplateID ()
    {
        assertValid();
        
        if (_WorkFlowTemplate == null)
        {
            return null;
        }
        else
        {
            return _WorkFlowTemplate.getID ();
        }
    }

    /**
     * Called prior to the assoc changing.  Subclasses need not call super.  If a field exception
     * is thrown, the attribute change will fail.  The new value is different to the old value.
     */
    protected void preWorkFlowTemplateChange (WorkFlowTemplate newWorkFlowTemplate) throws FieldException
    {
    }


    /**
     * Called after the assoc changes.
     * If a field exception is thrown, the value is still changed, however it 
     * may lead to the TX being rolled back
     */
    protected void postWorkFlowTemplateChange () throws FieldException
    {
    }


    
    public FieldWriteability getWriteability_WorkFlowTemplate ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }

        
    /**
     * Set the reference WorkFlowTemplate.  Checks to ensure a new value
     * has been supplied.  If so, marks the reference as altered and sets it.
     */
    public void setWorkFlowTemplate (WorkFlowTemplate newWorkFlowTemplate) throws StorageException, FieldException
    {
        BusinessObjectParser.assertFieldCondition (newWorkFlowTemplate != null, this, SINGLEREFERENCE_WorkFlowTemplate, "mandatory");

        if (_WorkFlowTemplate.wouldReferencedChange (newWorkFlowTemplate))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (SINGLEREFERENCE_WorkFlowTemplate_Decorators, (WorkFlowStage)this, SINGLEREFERENCE_WorkFlowTemplate ,getWriteability_WorkFlowTemplate ()) != FieldWriteability.FALSE, "Assoc WorkFlowTemplate is not writeable");
            preWorkFlowTemplateChange (newWorkFlowTemplate);
            WorkFlowTemplate oldWorkFlowTemplate = getWorkFlowTemplate ();

            if (oldWorkFlowTemplate != null)
            {
                // This is to stop validation from triggering when we are removed
                _WorkFlowTemplate.set (null);
                oldWorkFlowTemplate.removeFromWorkFlowStages ((WorkFlowStage)(this));
            }

            _WorkFlowTemplate.set (newWorkFlowTemplate);

            if (newWorkFlowTemplate != null)
            {
                newWorkFlowTemplate.addToWorkFlowStages ((WorkFlowStage)(this));
            }
                
            postWorkFlowTemplateChange ();
        }
    }

    /**
     * A list of multi assoc names e.g. list of strings.
     */
    public List<String> getMultiAssocs()
    {
        List result = super.getMultiAssocs ();
        
        result.add("WorkFlowMessages");
        result.add("Steps");

        return result;
    }


    /**
     * Get the reference instance for the multi assoc name.
     */
    public BaseBusinessClass getMultiAssocReferenceInstance(String attribName)
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            return WorkFlowMessage.REFERENCE_WorkFlowMessage ;
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            return WorkFlowStep.REFERENCE_WorkFlowStep ;
        }

        return super.getMultiAssocReferenceInstance(attribName);
    }


    public String getMultiAssocBackReference(String attribName)
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            return WorkFlowMessage.SINGLEREFERENCE_WorkFlowStage ;
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            return WorkFlowStep.SINGLEREFERENCE_WorkFlowStage ;
        }

        return super.getMultiAssocBackReference(attribName);
    }


    /**
     * Get the assoc count for the multi assoc name.
     */
    public int getMultiAssocCount(String attribName) throws StorageException
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            return this.getWorkFlowMessagesCount();
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            return this.getStepsCount();
        }

        return super.getMultiAssocCount(attribName);
    }


    /**
     * Get the assoc at a particular index
     */
    public BaseBusinessClass getMultiAssocAt(String attribName, int index) throws StorageException
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            return this.getWorkFlowMessagesAt(index);
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            return this.getStepsAt(index);
        }

        return super.getMultiAssocAt(attribName, index);
    }


    /**
     * Add to a multi assoc by attribute name
     */
    public void addToMultiAssoc(String attribName, BaseBusinessClass newElement) throws StorageException
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            addToWorkFlowMessages((WorkFlowMessage)newElement);
            return;
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            addToSteps((WorkFlowStep)newElement);
            return;
        }

        super.addToMultiAssoc(attribName, newElement);
    }

    /**
     * Remove from a multi assoc by attribute name
     */
    public void removeFromMultiAssoc(String attribName, BaseBusinessClass oldElement) throws StorageException
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            removeFromWorkFlowMessages((WorkFlowMessage)oldElement);
            return;
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            removeFromSteps((WorkFlowStep)oldElement);
            return;
        }

        super.removeFromMultiAssoc(attribName, oldElement);
    }


    protected void __loadMultiAssoc (String attribName, BaseBusinessClass[] elements)
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            _WorkFlowMessages.__loadAssociation (elements);
            return;
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            _Steps.__loadAssociation (elements);
            return;
        }

        super.__loadMultiAssoc(attribName, elements);
    }


    protected boolean __isMultiAssocLoaded (String attribName)
    {
        if (MULTIPLEREFERENCE_WorkFlowMessages.equals(attribName))
        {
            return _WorkFlowMessages.isLoaded ();
        }
        if (MULTIPLEREFERENCE_Steps.equals(attribName))
        {
            return _Steps.isLoaded ();
        }

        return super.__isMultiAssocLoaded(attribName);
    }


    public FieldWriteability getWriteability_WorkFlowMessages ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }
    
    
    public int getWorkFlowMessagesCount () throws StorageException
    {
        assertValid();
        return _WorkFlowMessages.getReferencedObjectsCount ();
    }


    public void addToWorkFlowMessages (WorkFlowMessage newElement) throws StorageException
    {
        if (_WorkFlowMessages.wouldAddChange (newElement))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (MULTIPLEREFERENCE_WorkFlowMessages_Decorators, (WorkFlowStage)this, MULTIPLEREFERENCE_WorkFlowMessages ,getWriteability_WorkFlowMessages ()) != FieldWriteability.FALSE, "MultiAssoc WorkFlowMessages is not writeable (add)");
            _WorkFlowMessages.appendElement (newElement);

            try
            {
                if (newElement.getWorkFlowStage () != this)
                {
                    newElement.setWorkFlowStage ((WorkFlowStage)(this));
                }
            }
            catch (Exception e)
            {
                throw NestedException.wrap(e);
            }
        }
    }


    public void removeFromWorkFlowMessages (WorkFlowMessage elementToRemove) throws StorageException
    {
        if (_WorkFlowMessages.wouldRemoveChange (elementToRemove))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (MULTIPLEREFERENCE_WorkFlowMessages_Decorators, (WorkFlowStage)this, MULTIPLEREFERENCE_WorkFlowMessages ,getWriteability_WorkFlowMessages ()) != FieldWriteability.FALSE, "MultiAssoc WorkFlowMessages is not writeable (remove)");
            _WorkFlowMessages.removeElement (elementToRemove);
            try
            {
                if (elementToRemove.getWorkFlowStage () != null)
                {
                    elementToRemove.setWorkFlowStage (null);
                }
            }
            catch (Exception e)
            {
                throw NestedException.wrap(e);
            }
        }
    }


    public WorkFlowMessage getWorkFlowMessagesAt (int index) throws StorageException
    {
        return (WorkFlowMessage)(_WorkFlowMessages.getElementAt (index));
    }


    public SortedSet<WorkFlowMessage> getWorkFlowMessagesSet () throws StorageException
    {
        return _WorkFlowMessages.getSet ();
    }

    public FieldWriteability getWriteability_Steps ()
    {
        return getFieldWritabilityUtil (FieldWriteability.TRUE);
    }
    
    
    public int getStepsCount () throws StorageException
    {
        assertValid();
        return _Steps.getReferencedObjectsCount ();
    }


    public void addToSteps (WorkFlowStep newElement) throws StorageException
    {
        if (_Steps.wouldAddChange (newElement))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (MULTIPLEREFERENCE_Steps_Decorators, (WorkFlowStage)this, MULTIPLEREFERENCE_Steps ,getWriteability_Steps ()) != FieldWriteability.FALSE, "MultiAssoc Steps is not writeable (add)");
            _Steps.appendElement (newElement);

            try
            {
                if (newElement.getWorkFlowStage () != this)
                {
                    newElement.setWorkFlowStage ((WorkFlowStage)(this));
                }
            }
            catch (Exception e)
            {
                throw NestedException.wrap(e);
            }
        }
    }


    public void removeFromSteps (WorkFlowStep elementToRemove) throws StorageException
    {
        if (_Steps.wouldRemoveChange (elementToRemove))
        {
            assertValid();
            Debug.assertion (AttributeDecoratorUtils.getWriteability (MULTIPLEREFERENCE_Steps_Decorators, (WorkFlowStage)this, MULTIPLEREFERENCE_Steps ,getWriteability_Steps ()) != FieldWriteability.FALSE, "MultiAssoc Steps is not writeable (remove)");
            _Steps.removeElement (elementToRemove);
            try
            {
                if (elementToRemove.getWorkFlowStage () != null)
                {
                    elementToRemove.setWorkFlowStage (null);
                }
            }
            catch (Exception e)
            {
                throw NestedException.wrap(e);
            }
        }
    }


    public WorkFlowStep getStepsAt (int index) throws StorageException
    {
        return (WorkFlowStep)(_Steps.getElementAt (index));
    }


    public SortedSet<WorkFlowStep> getStepsSet () throws StorageException
    {
        return _Steps.getSet ();
    }



    public void onDelete ()
    {
        try 
        {
            // Ensure we are removed from any loaded multi-associations that aren't mandatory
            if (_WorkFlowTemplate.isLoaded () || getTransaction ().isObjectLoaded (_WorkFlowTemplate.getReferencedType (), getWorkFlowTemplateID ()))
            {
                WorkFlowTemplate  referenced = getWorkFlowTemplate ();

                if (referenced != null)
                {
                    // Stop the callback
                    LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Setting backreference to null WorkFlowStages from ", getObjectID (), " to ", referenced.getObjectID ());
                    _WorkFlowTemplate.set (null);
                    referenced.removeFromWorkFlowStages ((WorkFlowStage)this);
                }
            }
        
            for(WorkFlowMessage referenced : CollectionUtils.reverse(getWorkFlowMessagesSet()))
            { 
                LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Setting backreference to null WorkFlowStage from ", getObjectID (), " to ", referenced.getObjectID ());
                referenced.setWorkFlowStage(null);
            }

            for(WorkFlowStep referenced : CollectionUtils.reverse(getStepsSet()))
            { 
                LogMgr.log (BUSINESS_OBJECTS, LogLevel.DEBUG1, "Setting backreference to null WorkFlowStage from ", getObjectID (), " to ", referenced.getObjectID ());
                referenced.setWorkFlowStage(null);
            }

        }
        catch (Exception e)
        {
            throw NestedException.wrap(e);
        }

        super.onDelete ();
    }


    public WorkFlowStage newInstance ()
    {
        return new WorkFlowStage ();
    }


    public WorkFlowStage referenceInstance ()
    {
        return REFERENCE_WorkFlowStage;
    }


    public WorkFlowStage getInTransaction (ObjectTransaction t) throws StorageException
    {
        return getWorkFlowStageByID (t, getObjectID());
    }
    
    
    public BaseBusinessClass dummyInstance ()
    {
        return DUMMY_WorkFlowStage;
    }


    public String getBaseSetName ()
    {
        return "tl_work_flow_stage";
    }



    /**
     * This is where an object returns the Persistent sets that will
     * store it into the database.
     * The should be entered into allSets
     */
    public void getPersistentSets (PersistentSetCollection allSets)
    {
        ObjectStatus        myStatus = getStatus ();
        PersistentSetStatus myPSetStatus = myStatus.getPSetStatus();
        ObjectID            myID = getID();

        super.getPersistentSets (allSets);
        
        PersistentSet   tl_work_flow_stagePSet = allSets.getPersistentSet (myID, "tl_work_flow_stage", myPSetStatus);

        tl_work_flow_stagePSet.setAttrib (FIELD_ObjectID, myID);
        tl_work_flow_stagePSet.setAttrib (FIELD_Name, HELPER_Name.toObject (_Name)); //
        tl_work_flow_stagePSet.setAttrib (FIELD_UseMessaging, HELPER_UseMessaging.toObject (_UseMessaging)); //
        tl_work_flow_stagePSet.setAttrib (FIELD_StageType, HELPER_StageType.toObject (_StageType)); //
        tl_work_flow_stagePSet.setAttrib (FIELD_SortOrder, HELPER_SortOrder.toObject (_SortOrder)); //
        tl_work_flow_stagePSet.setAttrib (FIELD_AutoProgress, HELPER_AutoProgress.toObject (_AutoProgress)); //
        _WithdrawalMessage.getPersistentSets (allSets);
        _WorkFlowTemplate.getPersistentSets (allSets);
        
    }


    /**
     * Sets the objects state based on Persistent sets.
     */
    public void setFromPersistentSets (ObjectID objectID, PersistentSetCollection allSets)
    {
        super.setFromPersistentSets (objectID, allSets);
        
        PersistentSet   tl_work_flow_stagePSet = allSets.getPersistentSet (objectID, "tl_work_flow_stage");

        _Name = (String)(HELPER_Name.fromObject (_Name, tl_work_flow_stagePSet.getAttrib (FIELD_Name))); //
        _UseMessaging = (Boolean)(HELPER_UseMessaging.fromObject (_UseMessaging, tl_work_flow_stagePSet.getAttrib (FIELD_UseMessaging))); //
        _StageType = (StageType)(HELPER_StageType.fromObject (_StageType, tl_work_flow_stagePSet.getAttrib (FIELD_StageType))); //
        _SortOrder = (Integer)(HELPER_SortOrder.fromObject (_SortOrder, tl_work_flow_stagePSet.getAttrib (FIELD_SortOrder))); //
        _AutoProgress = (Boolean)(HELPER_AutoProgress.fromObject (_AutoProgress, tl_work_flow_stagePSet.getAttrib (FIELD_AutoProgress))); //
        _WithdrawalMessage.setFromPersistentSets (objectID, allSets);
        _WorkFlowTemplate.setFromPersistentSets (objectID, allSets);
        
    }


    public void setAttributesFrom (BaseBusinessClass other, MultiException e)
    {
        super.setAttributesFrom (other, e);

        if (other instanceof WorkFlowStage)
        {
            WorkFlowStage otherWorkFlowStage = (WorkFlowStage)other;
            

            try
            {
                setName (otherWorkFlowStage.getName ());
            }
            catch (FieldException ex)
            {
                e.addException (ex);
            }

            try
            {
                setUseMessaging (otherWorkFlowStage.getUseMessaging ());
            }
            catch (FieldException ex)
            {
                e.addException (ex);
            }

            try
            {
                setStageType (otherWorkFlowStage.getStageType ());
            }
            catch (FieldException ex)
            {
                e.addException (ex);
            }

            try
            {
                setSortOrder (otherWorkFlowStage.getSortOrder ());
            }
            catch (FieldException ex)
            {
                e.addException (ex);
            }

            try
            {
                setAutoProgress (otherWorkFlowStage.getAutoProgress ());
            }
            catch (FieldException ex)
            {
                e.addException (ex);
            }
        }
    }


    /**
     * Set the attributes in this to copies of the attributes in source.
     */
    public void copyAttributesFrom (BaseBusinessClass source)
    {
        super.copyAttributesFrom (source);

        if (source instanceof BaseWorkFlowStage)
        {
            BaseWorkFlowStage sourceWorkFlowStage = (BaseWorkFlowStage)(source);

            _Name = sourceWorkFlowStage._Name;
            _UseMessaging = sourceWorkFlowStage._UseMessaging;
            _StageType = sourceWorkFlowStage._StageType;
            _SortOrder = sourceWorkFlowStage._SortOrder;
            _AutoProgress = sourceWorkFlowStage._AutoProgress;
            
        }
    }


    /**
     * Set the associations in this to copies of the attributes in source.
     */
    public void copySingleAssociationsFrom (BaseBusinessClass source, boolean linkToGhosts)
    {
        super.copySingleAssociationsFrom (source, linkToGhosts);

        if (source instanceof BaseWorkFlowStage)
        {
            BaseWorkFlowStage sourceWorkFlowStage = (BaseWorkFlowStage)(source);

            _WithdrawalMessage.copyFrom (sourceWorkFlowStage._WithdrawalMessage, linkToGhosts);
            _WorkFlowTemplate.copyFrom (sourceWorkFlowStage._WorkFlowTemplate, linkToGhosts);
            
        }
    }


    /**
     * Set the associations in this to copies of the attributes in source.
     */
    public void copyAssociationsFrom (BaseBusinessClass source, boolean linkToGhosts)
    {
        super.copyAssociationsFrom (source, linkToGhosts);

        if (source instanceof BaseWorkFlowStage)
        {
            BaseWorkFlowStage sourceWorkFlowStage = (BaseWorkFlowStage)(source);

            _WorkFlowMessages.copyFrom (sourceWorkFlowStage._WorkFlowMessages, linkToGhosts);
            _Steps.copyFrom (sourceWorkFlowStage._Steps, linkToGhosts);
            
        }
    }


    public void validate (ValidationContext context)
    {
        super.validate (context);

        
        context.check (getWorkFlowTemplateID() != null, this, SINGLEREFERENCE_WorkFlowTemplate, "mandatory");
        
    }


    /**
     * Subclasses must override this to read in their attributes
     */
    protected void readExternalData(Map<String, Object> vals) throws IOException, ClassNotFoundException
    {
        super.readExternalData(vals);

        _Name = (String)(HELPER_Name.readExternal (_Name, vals.get(FIELD_Name))); //
        _UseMessaging = (Boolean)(HELPER_UseMessaging.readExternal (_UseMessaging, vals.get(FIELD_UseMessaging))); //
        _StageType = (StageType)(HELPER_StageType.readExternal (_StageType, vals.get(FIELD_StageType))); //
        _SortOrder = (Integer)(HELPER_SortOrder.readExternal (_SortOrder, vals.get(FIELD_SortOrder))); //
        _AutoProgress = (Boolean)(HELPER_AutoProgress.readExternal (_AutoProgress, vals.get(FIELD_AutoProgress))); //
        _WithdrawalMessage.readExternalData(vals.get(SINGLEREFERENCE_WithdrawalMessage));
        _WorkFlowTemplate.readExternalData(vals.get(SINGLEREFERENCE_WorkFlowTemplate));
        _WorkFlowMessages.readExternalData(vals.get(MULTIPLEREFERENCE_WorkFlowMessages));
        _Steps.readExternalData(vals.get(MULTIPLEREFERENCE_Steps));
        
    }


    /**
     * Subclasses must override this to write out their attributes
     */
    protected void writeExternalData(Map<String, Object> vals) throws IOException
    {
        super.writeExternalData(vals);

        vals.put (FIELD_Name, HELPER_Name.writeExternal (_Name));
        vals.put (FIELD_UseMessaging, HELPER_UseMessaging.writeExternal (_UseMessaging));
        vals.put (FIELD_StageType, HELPER_StageType.writeExternal (_StageType));
        vals.put (FIELD_SortOrder, HELPER_SortOrder.writeExternal (_SortOrder));
        vals.put (FIELD_AutoProgress, HELPER_AutoProgress.writeExternal (_AutoProgress));
        vals.put (SINGLEREFERENCE_WithdrawalMessage, _WithdrawalMessage.writeExternalData());
        vals.put (SINGLEREFERENCE_WorkFlowTemplate, _WorkFlowTemplate.writeExternalData());
        vals.put (MULTIPLEREFERENCE_WorkFlowMessages, _WorkFlowMessages.writeExternalData());
        vals.put (MULTIPLEREFERENCE_Steps, _Steps.writeExternalData());
        
    }


    public void compare (BaseBusinessClass other, AttributeChangeListener listener) throws StorageException
    {
        super.compare (other, listener);

        if (other instanceof BaseWorkFlowStage)
        {
            BaseWorkFlowStage otherWorkFlowStage = (BaseWorkFlowStage)(other);

            
            if (!HELPER_Name.compare(this._Name, otherWorkFlowStage._Name))
            {
                listener.notifyFieldChange(this, other, FIELD_Name, HELPER_Name.toObject(this._Name), HELPER_Name.toObject(otherWorkFlowStage._Name));
            }
            if (!HELPER_UseMessaging.compare(this._UseMessaging, otherWorkFlowStage._UseMessaging))
            {
                listener.notifyFieldChange(this, other, FIELD_UseMessaging, HELPER_UseMessaging.toObject(this._UseMessaging), HELPER_UseMessaging.toObject(otherWorkFlowStage._UseMessaging));
            }
            if (!HELPER_StageType.compare(this._StageType, otherWorkFlowStage._StageType))
            {
                listener.notifyFieldChange(this, other, FIELD_StageType, HELPER_StageType.toObject(this._StageType), HELPER_StageType.toObject(otherWorkFlowStage._StageType));
            }
            if (!HELPER_SortOrder.compare(this._SortOrder, otherWorkFlowStage._SortOrder))
            {
                listener.notifyFieldChange(this, other, FIELD_SortOrder, HELPER_SortOrder.toObject(this._SortOrder), HELPER_SortOrder.toObject(otherWorkFlowStage._SortOrder));
            }
            if (!HELPER_AutoProgress.compare(this._AutoProgress, otherWorkFlowStage._AutoProgress))
            {
                listener.notifyFieldChange(this, other, FIELD_AutoProgress, HELPER_AutoProgress.toObject(this._AutoProgress), HELPER_AutoProgress.toObject(otherWorkFlowStage._AutoProgress));
            }

            // Compare single assocs
            _WithdrawalMessage.compare (otherWorkFlowStage._WithdrawalMessage, listener);
            _WorkFlowTemplate.compare (otherWorkFlowStage._WorkFlowTemplate, listener);
            

            // Compare multiple assocs
            _WorkFlowMessages.compare (otherWorkFlowStage._WorkFlowMessages, listener);
            _Steps.compare (otherWorkFlowStage._Steps, listener);
            
        }
    }


    public void visitTransients (AttributeVisitor visitor) throws StorageException
    {
        super.visitAttributes (visitor);

        
    }


    public void visitAttributes (AttributeVisitor visitor) throws StorageException
    {
        super.visitAttributes (visitor);

        visitor.visitField(this, FIELD_Name, HELPER_Name.toObject(getName()));
        visitor.visitField(this, FIELD_UseMessaging, HELPER_UseMessaging.toObject(getUseMessaging()));
        visitor.visitField(this, FIELD_StageType, HELPER_StageType.toObject(getStageType()));
        visitor.visitField(this, FIELD_SortOrder, HELPER_SortOrder.toObject(getSortOrder()));
        visitor.visitField(this, FIELD_AutoProgress, HELPER_AutoProgress.toObject(getAutoProgress()));
        visitor.visitAssociation (_WithdrawalMessage);
        visitor.visitAssociation (_WorkFlowTemplate);
        visitor.visitAssociation (_WorkFlowMessages);
        visitor.visitAssociation (_Steps);
        
    }


    public void visitAssociations (AssociationVisitor visitor, AssociatedScope scope) throws StorageException
    {
        super.visitAssociations (visitor, scope);

        if (scope.includes (_WithdrawalMessage))
        {
            visitor.visit (_WithdrawalMessage);
        }
        if (scope.includes (_WorkFlowTemplate))
        {
            visitor.visit (_WorkFlowTemplate);
        }
        if (scope.includes (_WorkFlowMessages))
        {
            visitor.visit (_WorkFlowMessages);
        }
        if (scope.includes (_Steps))
        {
            visitor.visit (_Steps);
        }
        
    }


    public static WorkFlowStage createWorkFlowStage (ObjectTransaction transaction) throws StorageException
    {
        WorkFlowStage     result = new WorkFlowStage ();

        result.initialiseNewObject (transaction);

        return result;
    }


    public static WorkFlowStage getWorkFlowStageByID (ObjectTransaction transaction, Long objectID) throws StorageException
    {
        return (WorkFlowStage)(transaction.getObjectByID (REFERENCE_WorkFlowStage, objectID));
    }

    public boolean testFilter (String attribName, QueryFilter filter) throws StorageException
    {
        if (false)
        {
            throw new RuntimeException ("Game over man!!");
        }
        else if (attribName.equals (FIELD_Name))
        {
            return filter.matches (getName ());
        }
        else if (attribName.equals (FIELD_UseMessaging))
        {
            return filter.matches (getUseMessaging ());
        }
        else if (attribName.equals (FIELD_StageType))
        {
            return filter.matches (getStageType ());
        }
        else if (attribName.equals (FIELD_SortOrder))
        {
            return filter.matches (getSortOrder ());
        }
        else if (attribName.equals (FIELD_AutoProgress))
        {
            return filter.matches (getAutoProgress ());
        }
        else if (attribName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return filter.matches (getWithdrawalMessage ());
        }
        else if (attribName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return filter.matches (getWorkFlowTemplate ());
        }
        else
        {
            return super.testFilter (attribName, filter);
        }
    }


    public static SearchAll SearchByAll () { return new SearchAll (); }

    public static class SearchAll extends SearchObject<WorkFlowStage>
    {
        public SearchAll andObjectID (QueryFilter<Long> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.object_id", FIELD_ObjectID);
            return this;
        }

        public SearchAll andObjectCreated (QueryFilter<Date> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.object_created_date", FIELD_ObjectCreated);
            return this;
        }

        public SearchAll andObjectLastModified (QueryFilter<Date> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.object_last_updated_date", FIELD_ObjectLastModified);
            return this;
        }

            
        public SearchAll andName (QueryFilter<String> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.name", "Name");
            return this;
        }
            
        public SearchAll andUseMessaging (QueryFilter<Boolean> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.use_messaging", "UseMessaging");
            return this;
        }
            
        public SearchAll andStageType (QueryFilter<StageType> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.stage_type", "StageType");
            return this;
        }
            
        public SearchAll andSortOrder (QueryFilter<Integer> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.sort_order", "SortOrder");
            return this;
        }
            
        public SearchAll andAutoProgress (QueryFilter<Boolean> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.auto_progress", "AutoProgress");
            return this;
        }
            
        public SearchAll andWithdrawalMessage (QueryFilter<WorkFlowMessage> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.withdrawal_message_id", "WithdrawalMessage");
            return this;
        }
            
        public SearchAll andWorkFlowTemplate (QueryFilter<WorkFlowTemplate> filter)
        {
            filter.addFilter (context, "tl_work_flow_stage.work_flow_template_id", "WorkFlowTemplate");
            return this;
        }
            
        public WorkFlowStage[] search (ObjectTransaction transaction) throws StorageException
        {
            
            BaseBusinessClass[]     results = super.search (transaction, REFERENCE_WorkFlowStage, SEARCH_All, criteria);
            Set<WorkFlowStage>   typedResults = new LinkedHashSet <WorkFlowStage> ();
            for (BaseBusinessClass bbcResult : results)
            {
                WorkFlowStage aResult = (WorkFlowStage)bbcResult;
                
                typedResults.add (aResult);
            }
            
            return ObjstoreUtils.removeDeleted(transaction, typedResults).toArray (new WorkFlowStage[0]);
                            
        }
    }

        
    public static WorkFlowStage[] searchAll (ObjectTransaction transaction) throws StorageException
    {
        return SearchByAll ()
               .search (transaction);
    }



    public Object getAttribute (String attribName)
    {
        if (false)
        {
            throw new RuntimeException ("Game over man!!");
        }
        else if (attribName.equals (FIELD_Name))
        {
            return HELPER_Name.toObject (getName ());
        }
        else if (attribName.equals (FIELD_UseMessaging))
        {
            return HELPER_UseMessaging.toObject (getUseMessaging ());
        }
        else if (attribName.equals (FIELD_StageType))
        {
            return HELPER_StageType.toObject (getStageType ());
        }
        else if (attribName.equals (FIELD_SortOrder))
        {
            return HELPER_SortOrder.toObject (getSortOrder ());
        }
        else if (attribName.equals (FIELD_AutoProgress))
        {
            return HELPER_AutoProgress.toObject (getAutoProgress ());
        }
        else
        {
            return super.getAttribute (attribName);
        }
    }


    public AttributeHelper getAttributeHelper (String attribName)
    {
        if (false)
        {
            throw new RuntimeException ("Game over man!!");
        }
        else if (attribName.equals (FIELD_Name))
        {
            return HELPER_Name;
        }
        else if (attribName.equals (FIELD_UseMessaging))
        {
            return HELPER_UseMessaging;
        }
        else if (attribName.equals (FIELD_StageType))
        {
            return HELPER_StageType;
        }
        else if (attribName.equals (FIELD_SortOrder))
        {
            return HELPER_SortOrder;
        }
        else if (attribName.equals (FIELD_AutoProgress))
        {
            return HELPER_AutoProgress;
        }
        else
        {
            return super.getAttributeHelper (attribName);
        }
    }


    public void setAttribute (String attribName, Object attribValue) throws FieldException
    {
        if (false)
        {
            throw new RuntimeException ("Game over man!!");
        }
        else if (attribName.equals (FIELD_Name))
        {
            setName ((String)(HELPER_Name.fromObject (_Name, attribValue)));            
        }
        else if (attribName.equals (FIELD_UseMessaging))
        {
            setUseMessaging ((Boolean)(HELPER_UseMessaging.fromObject (_UseMessaging, attribValue)));            
        }
        else if (attribName.equals (FIELD_StageType))
        {
            setStageType ((StageType)(HELPER_StageType.fromObject (_StageType, attribValue)));            
        }
        else if (attribName.equals (FIELD_SortOrder))
        {
            setSortOrder ((Integer)(HELPER_SortOrder.fromObject (_SortOrder, attribValue)));            
        }
        else if (attribName.equals (FIELD_AutoProgress))
        {
            setAutoProgress ((Boolean)(HELPER_AutoProgress.fromObject (_AutoProgress, attribValue)));            
        }
        else
        {
            super.setAttribute (attribName, attribValue);
        }
    }

    

    public boolean isWriteable (String fieldName)
    {        
        return getWriteable (fieldName) == FieldWriteability.TRUE;
    }

    public boolean isReadable ()
    {
        return super.isReadable();
    }

    public boolean isReadable (String fieldName)
    {
        return super.isReadable(fieldName);
    }


    public FieldWriteability getWriteable (String fieldName)
    {
        if (false)
        {
            throw new RuntimeException ("Game over man!!");
        }
        else if (fieldName.equals (FIELD_Name))
        {
            return getWriteability_Name ();
        }
        else if (fieldName.equals (FIELD_UseMessaging))
        {
            return getWriteability_UseMessaging ();
        }
        else if (fieldName.equals (FIELD_StageType))
        {
            return getWriteability_StageType ();
        }
        else if (fieldName.equals (FIELD_SortOrder))
        {
            return getWriteability_SortOrder ();
        }
        else if (fieldName.equals (FIELD_AutoProgress))
        {
            return getWriteability_AutoProgress ();
        }
        else if (fieldName.equals (MULTIPLEREFERENCE_WorkFlowMessages))
        {
            return getWriteability_WorkFlowMessages ();
        }
        else if (fieldName.equals (MULTIPLEREFERENCE_Steps))
        {
            return getWriteability_Steps ();
        }
        else if (fieldName.equals (SINGLEREFERENCE_WithdrawalMessage))
        {
            return getWriteability_WithdrawalMessage ();
        }
        else if (fieldName.equals (SINGLEREFERENCE_WorkFlowTemplate))
        {
            return getWriteability_WorkFlowTemplate ();
        }
        else
        {
            return super.getWriteable (fieldName);
        }
    }


    public void putUnwriteable (Set<String> fields)
    {
        if (getWriteability_Name () != FieldWriteability.TRUE)
        {
            fields.add (FIELD_Name);
        }
        
        if (getWriteability_UseMessaging () != FieldWriteability.TRUE)
        {
            fields.add (FIELD_UseMessaging);
        }
        
        if (getWriteability_StageType () != FieldWriteability.TRUE)
        {
            fields.add (FIELD_StageType);
        }
        
        if (getWriteability_SortOrder () != FieldWriteability.TRUE)
        {
            fields.add (FIELD_SortOrder);
        }
        
        if (getWriteability_AutoProgress () != FieldWriteability.TRUE)
        {
            fields.add (FIELD_AutoProgress);
        }
        

        super.putUnwriteable (fields);
    }

    public String[] getAllTableNames()
    {
        return new String[] {"tl_work_flow_stage"};
    }
    
    public boolean isPolymorphic(String tableName)
    {
        return super.isPolymorphic(tableName);
    }


    public List<AbstractAttribute> getAttributes ()
    {
        List result = super.getAttributes ();

        
        result.add(HELPER_Name.getAttribObject (getClass (), _Name, true, FIELD_Name));
        result.add(HELPER_UseMessaging.getAttribObject (getClass (), _UseMessaging, false, FIELD_UseMessaging));
        result.add(HELPER_StageType.getAttribObject (getClass (), _StageType, true, FIELD_StageType));
        result.add(HELPER_SortOrder.getAttribObject (getClass (), _SortOrder, true, FIELD_SortOrder));
        result.add(HELPER_AutoProgress.getAttribObject (getClass (), _AutoProgress, false, FIELD_AutoProgress));

        return result;
    }


    public Map getAttributeMetadata (String attribute)
    {
        if (ATTRIBUTES_METADATA_WorkFlowStage.containsKey (attribute))
        {
            return (Map)ATTRIBUTES_METADATA_WorkFlowStage.get (attribute);
        }
        else
        {
            return super.getAttributeMetadata (attribute);
        }
    }


    public Object getAttributeMetadata (String attribute, String metadata)
    {
        if (ATTRIBUTES_METADATA_WorkFlowStage.containsKey (attribute))
        {
            return ((Map)ATTRIBUTES_METADATA_WorkFlowStage.get (attribute)).get(metadata);
        }
        else
        {
            return super.getAttributeMetadata (attribute, metadata);
        }
    }

    public void copyAllAttributeMetadata (Map copyInto)
    {
        super.copyAllAttributeMetadata(copyInto);

        copyInto.putAll(ATTRIBUTES_METADATA_WorkFlowStage);
    }
            

    public void preCommit (boolean willBeStored) throws Exception
    {
        super.preCommit(willBeStored);
        
        if(willBeStored)
        {
        
        }
    }

    public oneit.servlets.objstore.binary.BinaryContentHandler getBinaryContentHandler(String attribName)
    {
        
        return super.getBinaryContentHandler(attribName);
    }

    public static class WorkFlowStageBehaviourDecorator extends BaseBusinessClass.BBCBehaviourDecorator<WorkFlowStage>
    {

    /**
     * Get the attribute Name
     */
    public String getName (WorkFlowStage obj, String original)
    {
        return original;
    }

    /**
     * Change the value set for attribute Name.
     * May modify the field beforehand
     * Occurs before validation.
     */
    public String setName (WorkFlowStage obj, String newName) throws FieldException
    {
        return newName;
    }

    /**
     * Get the attribute UseMessaging
     */
    public Boolean getUseMessaging (WorkFlowStage obj, Boolean original)
    {
        return original;
    }

    /**
     * Change the value set for attribute UseMessaging.
     * May modify the field beforehand
     * Occurs before validation.
     */
    public Boolean setUseMessaging (WorkFlowStage obj, Boolean newUseMessaging) throws FieldException
    {
        return newUseMessaging;
    }

    /**
     * Get the attribute StageType
     */
    public StageType getStageType (WorkFlowStage obj, StageType original)
    {
        return original;
    }

    /**
     * Change the value set for attribute StageType.
     * May modify the field beforehand
     * Occurs before validation.
     */
    public StageType setStageType (WorkFlowStage obj, StageType newStageType) throws FieldException
    {
        return newStageType;
    }

    /**
     * Get the attribute SortOrder
     */
    public Integer getSortOrder (WorkFlowStage obj, Integer original)
    {
        return original;
    }

    /**
     * Change the value set for attribute SortOrder.
     * May modify the field beforehand
     * Occurs before validation.
     */
    public Integer setSortOrder (WorkFlowStage obj, Integer newSortOrder) throws FieldException
    {
        return newSortOrder;
    }

    /**
     * Get the attribute AutoProgress
     */
    public Boolean getAutoProgress (WorkFlowStage obj, Boolean original)
    {
        return original;
    }

    /**
     * Change the value set for attribute AutoProgress.
     * May modify the field beforehand
     * Occurs before validation.
     */
    public Boolean setAutoProgress (WorkFlowStage obj, Boolean newAutoProgress) throws FieldException
    {
        return newAutoProgress;
    }

    }

    @Override
    public ORMPipeLine pipes()
    {
        return new WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> ((WorkFlowStage)this);
    }

    @Override
    public ORMPipeLine pipes(Collection _items)
    {
        return pipesWorkFlowStage(_items);
    }
      
    /**
     * Use this instead of pipes() to get rid of type casting.
     */  
    public WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> pipelineWorkFlowStage()
    {
        return (WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage>) pipes();
    }
    
    public static WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> pipesWorkFlowStage(Collection<WorkFlowStage> items)
    {
        return REFERENCE_WorkFlowStage.new WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> (items);
    }
    
    public static WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> pipesWorkFlowStage(WorkFlowStage[] _items)
    {
        return pipesWorkFlowStage(Arrays.asList (_items));
    }
    
    public static WorkFlowStagePipeLineFactory<WorkFlowStage, WorkFlowStage> pipesWorkFlowStage()
    {
        return pipesWorkFlowStage((Collection)null);
    }
    
    
    public class WorkFlowStagePipeLineFactory<From extends BaseBusinessClass, Me extends WorkFlowStage> extends BaseBusinessClass.ORMPipeLine<From, Me>    
    {
        public <Prev> WorkFlowStagePipeLineFactory (PipeLine<From, Prev> pipeLine, Pipe<Prev, Me> nextPipe)
        {
            super (pipeLine, nextPipe);
        }
        
        public WorkFlowStagePipeLineFactory (From seed)
        {
            super(seed);
        }

        public WorkFlowStagePipeLineFactory (Collection<From> seed)
        {
            super(seed);
        }
        
        
        public PipeLine<From, ? extends Object> to(String name)
        {
            if (name.equals ("WorkFlowMessages"))
            {
                return toWorkFlowMessages ();
            }                
            if (name.equals ("Steps"))
            {
                return toSteps ();
            }                
            if (name.equals ("Name"))
            {
                return toName ();
            }                
            if (name.equals ("UseMessaging"))
            {
                return toUseMessaging ();
            }                
            if (name.equals ("StageType"))
            {
                return toStageType ();
            }                
            if (name.equals ("SortOrder"))
            {
                return toSortOrder ();
            }                
            if (name.equals ("AutoProgress"))
            {
                return toAutoProgress ();
            }                
            if (name.equals ("WithdrawalMessage"))
            {
                return toWithdrawalMessage ();
            }                
            if (name.equals ("WorkFlowTemplate"))
            {
                return toWorkFlowTemplate ();
            }                
            
            
            return super.to(name);
        }
        
        
        public PipeLine<From, String> toName () { return pipe(new ORMAttributePipe<Me, String>(FIELD_Name));  }
        
        public PipeLine<From, Boolean> toUseMessaging () { return pipe(new ORMAttributePipe<Me, Boolean>(FIELD_UseMessaging));  }
        
        public StageType.StageTypePipeLineFactory<From, StageType> toStageType () 
        { 
            return new StageType.StageTypePipeLineFactory<> (this, new ORMAttributePipe<>(FIELD_StageType));
        }
        
        public PipeLine<From, Integer> toSortOrder () { return pipe(new ORMAttributePipe<Me, Integer>(FIELD_SortOrder));  }
        
        public PipeLine<From, Boolean> toAutoProgress () { return pipe(new ORMAttributePipe<Me, Boolean>(FIELD_AutoProgress));  }

        public WorkFlowMessage.WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> toWithdrawalMessage () { return toWithdrawalMessage (Filter.ALL); }

        public WorkFlowMessage.WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> toWithdrawalMessage (Filter<WorkFlowMessage> filter) 
        { 
            return WorkFlowMessage.REFERENCE_WorkFlowMessage.new WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> (this, new ORMSingleAssocPipe<Me, WorkFlowMessage>(SINGLEREFERENCE_WithdrawalMessage, filter)); 
        }

        public WorkFlowTemplate.WorkFlowTemplatePipeLineFactory<From, WorkFlowTemplate> toWorkFlowTemplate () { return toWorkFlowTemplate (Filter.ALL); }

        public WorkFlowTemplate.WorkFlowTemplatePipeLineFactory<From, WorkFlowTemplate> toWorkFlowTemplate (Filter<WorkFlowTemplate> filter) 
        { 
            return WorkFlowTemplate.REFERENCE_WorkFlowTemplate.new WorkFlowTemplatePipeLineFactory<From, WorkFlowTemplate> (this, new ORMSingleAssocPipe<Me, WorkFlowTemplate>(SINGLEREFERENCE_WorkFlowTemplate, filter)); 
        }

        public WorkFlowMessage.WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> toWorkFlowMessages () { return toWorkFlowMessages(Filter.ALL); }        

        public WorkFlowMessage.WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> toWorkFlowMessages (Filter<WorkFlowMessage> filter)
        {
            return WorkFlowMessage.REFERENCE_WorkFlowMessage.new WorkFlowMessagePipeLineFactory<From, WorkFlowMessage> (this, new ORMMultiAssocPipe<Me, WorkFlowMessage>(MULTIPLEREFERENCE_WorkFlowMessages, filter)); 
        }

        public WorkFlowStep.WorkFlowStepPipeLineFactory<From, WorkFlowStep> toSteps () { return toSteps(Filter.ALL); }        

        public WorkFlowStep.WorkFlowStepPipeLineFactory<From, WorkFlowStep> toSteps (Filter<WorkFlowStep> filter)
        {
            return WorkFlowStep.REFERENCE_WorkFlowStep.new WorkFlowStepPipeLineFactory<From, WorkFlowStep> (this, new ORMMultiAssocPipe<Me, WorkFlowStep>(MULTIPLEREFERENCE_Steps, filter)); 
        }
    }
    
    public boolean isTransientAttrib(String attribName)
    {
        

        return super.isTransientAttrib(attribName);
    }

    public boolean isTransientSingleReference(String assocName)
    {
        

        return super.isTransientSingleReference(assocName);
    }
}

class DummyWorkFlowStage extends WorkFlowStage
{
    // Default constructor primarily to support Externalisable
    public DummyWorkFlowStage()
    {
        super();
    }

    public void assertValid ()
    {
    }


    public WorkFlowMessage getWithdrawalMessage () throws StorageException
    {
        return (WorkFlowMessage)(WorkFlowMessage.DUMMY_WorkFlowMessage);
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public Long getWithdrawalMessageID ()
    {
        return WorkFlowMessage.DUMMY_WorkFlowMessage.getObjectID();
    }

    public WorkFlowTemplate getWorkFlowTemplate () throws StorageException
    {
        return (WorkFlowTemplate)(WorkFlowTemplate.DUMMY_WorkFlowTemplate);
    }


    /**
     * Get the object id for the referenced object.  Does not force a DB access.
     */
    public Long getWorkFlowTemplateID ()
    {
        return WorkFlowTemplate.DUMMY_WorkFlowTemplate.getObjectID();
    }

    public int getWorkFlowMessagesCount () throws StorageException
    {
        return 0;
    }


    public WorkFlowMessage getWorkFlowMessagesAt (int index) throws StorageException
    {
        throw new RuntimeException ("No elements in a dummy object in association WorkFlowMessages");
    }


    public SortedSet getWorkFlowMessagesSet () throws StorageException
    {
        return new TreeSet();
    }

    public int getStepsCount () throws StorageException
    {
        return 0;
    }


    public WorkFlowStep getStepsAt (int index) throws StorageException
    {
        throw new RuntimeException ("No elements in a dummy object in association Steps");
    }


    public SortedSet getStepsSet () throws StorageException
    {
        return new TreeSet();
    }

}

    
