/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
package org.eclipse.persistence.sessions.factories;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.descriptors.CMPPolicy;
import org.eclipse.persistence.descriptors.CachePolicy;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.descriptors.InterfacePolicy;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.descriptors.ReturningPolicy;
import org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy;
import org.eclipse.persistence.descriptors.TimestampLockingPolicy;
import org.eclipse.persistence.descriptors.VersionLockingPolicy;
import org.eclipse.persistence.descriptors.copying.CloneCopyPolicy;
import org.eclipse.persistence.descriptors.invalidation.CacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.invalidation.DailyCacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.invalidation.NoExpiryCacheInvalidationPolicy;
import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy;
import org.eclipse.persistence.eis.EISLogin;
import org.eclipse.persistence.eis.interactions.XMLInteraction;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.history.HistoryPolicy;
import org.eclipse.persistence.indirection.IndirectMap;
import org.eclipse.persistence.internal.codegen.ClassDefinition;
import org.eclipse.persistence.internal.codegen.CodeGenerator;
import org.eclipse.persistence.internal.codegen.NonreflectiveMethodDefinition;
import org.eclipse.persistence.internal.descriptors.FieldTransformation;
import org.eclipse.persistence.internal.descriptors.MethodBasedFieldTransformation;
import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy;
import org.eclipse.persistence.internal.descriptors.TransformerBasedFieldTransformation;
import org.eclipse.persistence.internal.expressions.ExpressionJavaPrinter;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.DescriptorCompare;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.indirection.BasicIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.ContainerIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.IndirectionPolicy;
import org.eclipse.persistence.internal.indirection.NoIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.ProxyIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.TransparentIndirectionPolicy;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.internal.sessions.factories.DirectToXMLTypeMappingHelper;
import org.eclipse.persistence.mappings.AggregateCollectionMapping;
import org.eclipse.persistence.mappings.AggregateObjectMapping;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.DirectMapMapping;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.mappings.TransformationMapping;
import org.eclipse.persistence.mappings.VariableOneToOneMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.converters.ObjectTypeConverter;
import org.eclipse.persistence.mappings.converters.SerializedObjectConverter;
import org.eclipse.persistence.mappings.converters.TypeConversionConverter;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.mappings.querykeys.DirectQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.InMemoryQueryIndirectionPolicy;
import org.eclipse.persistence.queries.MethodBaseQueryRedirector;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sequencing.UnaryTableSequence;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.sessions.Project;

/**
 * <p><b>Purpose</b>: Allow for a class storing a TopLink project's descriptors (meta-data) to be generated.
 * This class can then be used at runtime to deploy the TopLink descriptor's instead of XML files.
 *
 * @since TopLink 3.0
 * @author James Sutherland
 */
public class ProjectClassGenerator {
    protected String className;
    protected String packageName;
    protected String outputPath;
    protected String outputFileName;
    protected Writer outputWriter;
    protected Project project;
    protected Hashtable descriptorMethodNames;

    /**
     * PUBLIC:
     * Create a new generator.
     */
    public ProjectClassGenerator() {
        this.outputPath = "";
        this.outputFileName = "TopLinkProject.java";
        this.className = "TopLinkProject";
        this.packageName = "";
        this.descriptorMethodNames = new Hashtable();
    }

    /**
     * PUBLIC:
     * Create a new generator to output the project.
     */
    public ProjectClassGenerator(Project project) {
        this();
        this.project = project;
    }

    /**
     * PUBLIC:
     * Create a new generator to output to the writer.
     */
    public ProjectClassGenerator(Project project, String projectClassName, Writer outputWriter) {
        this(project);
        this.outputWriter = outputWriter;
        setClassName(projectClassName);
    }

    /**
     * PUBLIC:
     * Create a new generator to output to the file.
     */
    public ProjectClassGenerator(Project project, String projectClassName, String fileName) {
        this(project);
        setClassName(projectClassName);
        setOutputFileName(fileName);
    }

    protected void addAggregateCollectionMappingLines(NonreflectiveMethodDefinition method, String mappingName, AggregateCollectionMapping mapping) {
        Enumeration targetKeysEnum = mapping.getTargetForeignKeyFields().elements();
        Enumeration sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = (DatabaseField)sourceKeysEnum.nextElement();
            DatabaseField targetField = (DatabaseField)targetKeysEnum.nextElement();
            method.addLine(mappingName + ".addTargetForeignKeyFieldName(\"" + targetField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }
    }

    protected void addAggregateObjectMappingLines(NonreflectiveMethodDefinition method, String mappingName, AggregateObjectMapping mapping) {
        if (mapping.getReferenceClassName() != null) {
            method.addLine(mappingName + ".setReferenceClass(" + mapping.getReferenceClassName() + ".class);");
        }
        method.addLine(mappingName + ".setIsNullAllowed(" + mapping.isNullAllowed() + ");");

        for (Iterator<String> fieldTranslationEnum = mapping.getAggregateToSourceFields().keySet().iterator();
                 fieldTranslationEnum.hasNext();) {
            String aggregateFieldName = fieldTranslationEnum.next();
            DatabaseField sourceField = mapping.getAggregateToSourceFields().get(aggregateFieldName);
            //may need to account for delimiting on the sourceField in the future
            method.addLine(mappingName + ".addFieldNameTranslation(\"" + sourceField.getQualifiedName() + "\", \"" + aggregateFieldName + "\");");
        }
    }

    protected void addCacheInvalidationPolicyLines(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        CacheInvalidationPolicy policy = descriptor.getCacheInvalidationPolicy();
        if (policy instanceof NoExpiryCacheInvalidationPolicy) {
            if (policy.shouldUpdateReadTimeOnUpdate()) {
                method.addLine("// Cache Invalidation Policy");
                method.addLine("NoExpiryCacheInvalidationPolicy policy = new NoExpiryCacheInvalidationPolicy();");
                method.addLine("policy.setShouldUpdateReadTimeOnUpdate(" + policy.shouldUpdateReadTimeOnUpdate() + ");");
                method.addLine("descriptor.setCacheInvalidationPolicy(policy);");
            }
        } else if (policy instanceof TimeToLiveCacheInvalidationPolicy) {
            method.addLine("// Cache Invalidation Policy");
            method.addLine("TimeToLiveCacheInvalidationPolicy policy = new TimeToLiveCacheInvalidationPolicy(" + ((TimeToLiveCacheInvalidationPolicy)policy).getTimeToLive() + ");");
            method.addLine("policy.setShouldUpdateReadTimeOnUpdate(" + policy.shouldUpdateReadTimeOnUpdate() + ");");
            method.addLine("descriptor.setCacheInvalidationPolicy(policy);");
        } else if (policy instanceof DailyCacheInvalidationPolicy) {
            Calendar calendar = ((DailyCacheInvalidationPolicy)policy).getExpiryTime();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int minute = calendar.get(Calendar.MINUTE);
            int second = calendar.get(Calendar.SECOND);
            int millisecond = calendar.get(Calendar.MILLISECOND);
            method.addLine("// Cache Invalidation Policy");
            method.addLine("DailyCacheInvalidationPolicy policy = new DailyCacheInvalidationPolicy(" + hour + ", " + minute + ", " + second + ", " + millisecond + ");");
            method.addLine("policy.setShouldUpdateReadTimeOnUpdate(" + policy.shouldUpdateReadTimeOnUpdate() + ");");
            method.addLine("descriptor.setCacheInvalidationPolicy(policy);");
        }
    }

    protected void addCMPPolicyLines(NonreflectiveMethodDefinition method, CMPPolicy sourceCMPPolicy) {
        if (sourceCMPPolicy == null) {
            return;
        }
        method.addLine("");
        method.addLine("// CMP Policy");

        method.addLine("CMPPolicy cmpPolicy = new CMPPolicy();");
        method.addLine("cmpPolicy.setDeferModificationsUntilCommit(" + sourceCMPPolicy.getDeferModificationsUntilCommit() + ");");
        method.addLine("cmpPolicy.setForceUpdate(" + sourceCMPPolicy.getForceUpdate() + ");");
        method.addLine("cmpPolicy.setNonDeferredCreateTime( " + sourceCMPPolicy.getNonDeferredCreateTime() + ");");
        method.addLine("cmpPolicy.setUpdateAllFields(" + sourceCMPPolicy.getUpdateAllFields() + ");");

        if (sourceCMPPolicy.hasPessimisticLockingPolicy()) {
            method.addLine("");
            method.addLine("// Pessimistic Locking Policy");
            method.addLine("cmpPolicy.setPessimisticLockingPolicy(new PessimisticLockingPolicy());");

            if (ObjectLevelReadQuery.LOCK == sourceCMPPolicy.getPessimisticLockingPolicy().getLockingMode()) {
                method.addLine("cmpPolicy.getPessimisticLockingPolicy().setLockingMode(ObjectLevelReadQuery.LOCK);");
            } else {
                method.addLine("cmpPolicy.getPessimisticLockingPolicy().setLockingMode(ObjectLevelReadQuery.LOCK_NOWAIT);");
            }
        }
        method.addLine("descriptor.setCMPPolicy(cmpPolicy);");
    }

    protected void addDescriptorPropertyLines(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        method.addLine("// ClassDescriptor Properties.");

        // Identity map
        if ((!descriptor.isChildDescriptor()) && !descriptor.isDescriptorTypeAggregate() && (!descriptor.isDescriptorForInterface())) {
            if (descriptor.shouldUseFullIdentityMap()) {
                method.addLine("descriptor.useFullIdentityMap();");
            } else if (descriptor.shouldUseCacheIdentityMap()) {
                method.addLine("descriptor.useCacheIdentityMap();");
            } else if (descriptor.shouldUseSoftCacheWeakIdentityMap()) {
                method.addLine("descriptor.useSoftCacheWeakIdentityMap();");
            } else if (descriptor.shouldUseHardCacheWeakIdentityMap()) {
                method.addLine("descriptor.useHardCacheWeakIdentityMap();");
            } else if (descriptor.shouldUseWeakIdentityMap()) {
                method.addLine("descriptor.useWeakIdentityMap();");
            } else if (descriptor.shouldUseSoftIdentityMap()) {
                method.addLine("descriptor.useSoftIdentityMap();");
            } else if (descriptor.shouldUseNoIdentityMap()) {
                method.addLine("descriptor.useNoIdentityMap();");
            }

            method.addLine("descriptor.setIdentityMapSize(" + descriptor.getIdentityMapSize() + ");");
            // Remote
            if (descriptor.shouldUseRemoteFullIdentityMap()) {
                method.addLine("descriptor.useRemoteFullIdentityMap();");
            } else if (descriptor.shouldUseRemoteCacheIdentityMap()) {
                method.addLine("descriptor.useRemoteCacheIdentityMap();");
            } else if (descriptor.shouldUseRemoteSoftCacheWeakIdentityMap()) {
                method.addLine("descriptor.useRemoteSoftCacheWeakIdentityMap();");
            } else if (descriptor.shouldUseRemoteHardCacheWeakIdentityMap()) {
                method.addLine("descriptor.useRemoteHardCacheWeakIdentityMap();");
            } else if (descriptor.shouldUseRemoteWeakIdentityMap()) {
                method.addLine("descriptor.useRemoteWeakIdentityMap();");
            } else if (descriptor.shouldUseRemoteNoIdentityMap()) {
                method.addLine("descriptor.useRemoteNoIdentityMap();");
            }

            method.addLine("descriptor.setRemoteIdentityMapSize(" + descriptor.getRemoteIdentityMapSize() + ");");
        }

        // Sequencing
        if (descriptor.usesSequenceNumbers()) {
            method.addLine("descriptor.setSequenceNumberFieldName(\"" + descriptor.getSequenceNumberField().getQualifiedName() + "\");");
            if (descriptor.getSequenceNumberName() != null) {
                method.addLine("descriptor.setSequenceNumberName(\"" + descriptor.getSequenceNumberName() + "\");");
            }
        }

        // Returning
        if (descriptor.hasReturningPolicy()) {
            addReturningPolicyLines(method, descriptor.getReturningPolicy());
        }

        // Locking
        if (descriptor.usesOptimisticLocking()) {
            addOptimisticLockingLines(method, descriptor.getOptimisticLockingPolicy());
        }

        // Always Conform Results in Unit of Work
        if (descriptor.shouldAlwaysConformResultsInUnitOfWork()) {
            method.addLine("descriptor.alwaysConformResultsInUnitOfWork();");
        }

        // Is Read Only
        if (descriptor.shouldBeReadOnly()) {
            method.addLine("descriptor.setReadOnly();");
        }

        // Isolated Session support
        if (descriptor.getCachePolicy().isIsolated()) {
            method.addLine("descriptor.setIsIsolated(true);");
        }

        // Refreshing
        if (descriptor.getCachePolicy().shouldAlwaysRefreshCache()) {
            method.addLine("descriptor.alwaysRefreshCache();");
        }
        if (descriptor.getCachePolicy().shouldAlwaysRefreshCacheOnRemote()) {
            method.addLine("descriptor.alwaysRefreshCacheOnRemote();");
        }
        if (descriptor.getCachePolicy().shouldDisableCacheHits()) {
            method.addLine("descriptor.disableCacheHits();");
        }
        if (descriptor.getCachePolicy().shouldDisableCacheHitsOnRemote()) {
            method.addLine("descriptor.disableCacheHitsOnRemote();");
        }
        if (descriptor.getCachePolicy().shouldOnlyRefreshCacheIfNewerVersion()) {
            method.addLine("descriptor.onlyRefreshCacheIfNewerVersion();");
        }

        // ClassDescriptor alias
        if (descriptor.getAlias() != null) {
            method.addLine("descriptor.setAlias(\"" + descriptor.getAlias() + "\");");
        }

        // Copying
        if ((descriptor.getCopyPolicy() instanceof CloneCopyPolicy) && (((CloneCopyPolicy)descriptor.getCopyPolicy()).getMethodName() != null)) {
            method.addLine("descriptor.useCloneCopyPolicy(\"" + ((CloneCopyPolicy)descriptor.getCopyPolicy()).getMethodName() + "\");");
        }

        // Instantiation
        if (!descriptor.getInstantiationPolicy().isUsingDefaultConstructor()) {
            if (descriptor.getInstantiationPolicy().getFactoryClassName() != null) {
                if (descriptor.getInstantiationPolicy().getFactoryMethodName() != null) {
                    method.addLine("descriptor.useFactoryInstantiationPolicy(" + descriptor.getInstantiationPolicy().getFactoryClassName() + ".class, \"" + descriptor.getInstantiationPolicy().getMethodName() + "\", \"" + descriptor.getInstantiationPolicy().getFactoryMethodName() + "\");");
                } else {
                    method.addLine("descriptor.useFactoryInstantiationPolicy(" + descriptor.getInstantiationPolicy().getFactoryClassName() + ".class, \"" + descriptor.getInstantiationPolicy().getMethodName() + "\");");
                }
            } else {
                method.addLine("descriptor.useMethodInstantiationPolicy(\"" + descriptor.getInstantiationPolicy().getMethodName() + "\");");
            }
        }

        // Amendment
        if (descriptor.getAmendmentClassName() != null) {
            method.addLine("descriptor.setAmendmentClass(" + descriptor.getAmendmentClassName() + ".class);");
        }
        if (descriptor.getAmendmentMethodName() != null) {
            method.addLine("descriptor.setAmendmentMethodName(\"" + descriptor.getAmendmentMethodName() + "\");");
        }

        if (descriptor.getCachePolicy().getCacheSynchronizationType() != CachePolicy.UNDEFINED_OBJECT_CHANGE_BEHAVIOR) {
            StringBuilder lineToAdd = new StringBuilder("descriptor.setCacheSynchronizationType(");
            if (descriptor.getCachePolicy().getCacheSynchronizationType() == CachePolicy.INVALIDATE_CHANGED_OBJECTS) {
                lineToAdd.append("ClassDescriptor.INVALIDATE_CHANGED_OBJECTS");
            } else if (descriptor.getCachePolicy().getCacheSynchronizationType() == CachePolicy.DO_NOT_SEND_CHANGES) {
                lineToAdd.append("ClassDescriptor.DO_NOT_SEND_CHANGES");
            } else if (descriptor.getCachePolicy().getCacheSynchronizationType() == CachePolicy.SEND_NEW_OBJECTS_WITH_CHANGES) {
                lineToAdd.append("ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES");
            } else if (descriptor.getCachePolicy().getCacheSynchronizationType() == CachePolicy.SEND_OBJECT_CHANGES) {
                lineToAdd.append("ClassDescriptor.SEND_OBJECT_CHANGES");
            }
            lineToAdd.append(");");
            method.addLine(lineToAdd.toString());
        }

        // CMP descriptor
        addCMPPolicyLines(method, descriptor.getCMPPolicy());
    }

    protected void addDirectCollectionMappingLines(NonreflectiveMethodDefinition method, String mappingName, DirectCollectionMapping mapping) {
        if (mapping.getReferenceTable() != null) {
            method.addLine(mappingName + ".setReferenceTableName(\"" + mapping.getReferenceTable().getQualifiedName() + "\");");
        }

        method.addLine(mappingName + ".setDirectFieldName(\"" + mapping.getDirectFieldName() + "\");");

        Enumeration sourceKeysEnum = mapping.getSourceKeyFields().elements();
        Enumeration referenceKeysEnum = mapping.getReferenceKeyFields().elements();
        while (referenceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = (DatabaseField)sourceKeysEnum.nextElement();
            DatabaseField referenceField = (DatabaseField)referenceKeysEnum.nextElement();
            method.addLine(mappingName + ".addReferenceKeyFieldName(\"" + referenceField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }

        Converter converter = mapping.getValueConverter();
        if (converter != null) {
            addConverterLines(method, mappingName + "Converter", converter);
            method.addLine(mappingName + ".setValueConverter(" + mappingName + "Converter" + ");");
        }

        addHistoryPolicyLines(method, mapping, mappingName);
    }

    protected void addDirectMapMappingLines(NonreflectiveMethodDefinition method, String mappingName, DirectMapMapping mapping) {
        DatabaseField  directKeyField = mapping.getDirectKeyField();
        if(directKeyField != null) {
            method.addLine(mappingName + ".setDirectKeyFieldName(\"" + directKeyField.getQualifiedName() + "\");");
        }

        Converter converter = mapping.getKeyConverter();
        if (converter != null) {
            addConverterLines(method, mappingName + "KeyConverter", converter);
            method.addLine(mappingName + ".setKeyConverter(" + mappingName + "KeyConverter" + ");");
        }
    }

    protected void addFetchGroupManagerLine(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        if (descriptor.getFetchGroupManager() == null) {
            return;
        }
        method.addLine("//Fetch groups");
        method.addLine("descriptor.setFetchGroupManager(new FetchGroupManager());");

        Map namedFetchGroups = descriptor.getFetchGroupManager().getFetchGroups();

        if (descriptor.getFetchGroupManager().getDefaultFetchGroup() != null) {
            String defaultFetchGroupIdentifier = descriptor.getFetchGroupManager().getDefaultFetchGroup().getName() + "FetchGroup";
            method.addLine("");
            method.addLine("//Default fetch group -- " + defaultFetchGroupIdentifier);
            method.addLine("descriptor.getFetchGroupManager().setDefaultFetchGroup(" + defaultFetchGroupIdentifier + ");");
        }

        if (namedFetchGroups.isEmpty()) {
            return;
        }
        for (Iterator namedFetchGroupIter = namedFetchGroups.values().iterator();
                 namedFetchGroupIter.hasNext();) {
            FetchGroup namedFetchGroup = (FetchGroup)namedFetchGroupIter.next();
            String fetchGroupIdentifier = namedFetchGroup.getName() + "FetchGroup";
            method.addLine("");
            method.addLine("//Named fetch group -- " + fetchGroupIdentifier);
            addFetchGroupLines(method, namedFetchGroup, fetchGroupIdentifier);
            method.addLine("descriptor.getFetchGroupManager().addFetchGroup(" + fetchGroupIdentifier + ");");
        }
    }

    // TODO-dclarke: Needs to be enhanced to handle nested FetchGroup and FetchItem properties
    // OR throw an exception when a nested FetchGroup is encountered since the MW does not
    // supported nested FetchGroup and FetchItem properties
    protected void addFetchGroupLines(NonreflectiveMethodDefinition method, FetchGroup fetchGroup, String fetchGroupIdentifier) {
        method.addLine("FetchGroup " + fetchGroupIdentifier + " = new FetchGroup();");
        if (!fetchGroup.getName().equals("")) {
            method.addLine(fetchGroupIdentifier + ".setName(\"" + fetchGroup.getName() + "\");");
        }
        for (String attribute: fetchGroup.getAttributeNames()) {
            method.addLine(fetchGroupIdentifier + ".addAttribute(\"" + attribute + "\");");
        }
    }

    protected void addEventManagerPropertyLines(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        method.addLine("// Event Manager.");

        // Method events
        if (descriptor.getEventManager().getAboutToInsertSelector() != null) {
            method.addLine("descriptor.getEventManager().setAboutToInsertSelector(\"" + descriptor.getEventManager().getAboutToInsertSelector() + "\");");
        }
        if (descriptor.getEventManager().getAboutToUpdateSelector() != null) {
            method.addLine("descriptor.getEventManager().setAboutToUpdateSelector(\"" + descriptor.getEventManager().getAboutToUpdateSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostBuildSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostBuildSelector(\"" + descriptor.getEventManager().getPostBuildSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostCloneSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostCloneSelector(\"" + descriptor.getEventManager().getPostCloneSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostDeleteSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostDeleteSelector(\"" + descriptor.getEventManager().getPostDeleteSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostInsertSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostInsertSelector(\"" + descriptor.getEventManager().getPostInsertSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostMergeSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostMergeSelector(\"" + descriptor.getEventManager().getPostMergeSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostRefreshSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostRefreshSelector(\"" + descriptor.getEventManager().getPostRefreshSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostUpdateSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostUpdateSelector(\"" + descriptor.getEventManager().getPostUpdateSelector() + "\");");
        }
        if (descriptor.getEventManager().getPostWriteSelector() != null) {
            method.addLine("descriptor.getEventManager().setPostWriteSelector(\"" + descriptor.getEventManager().getPostWriteSelector() + "\");");
        }
        if (descriptor.getEventManager().getPreDeleteSelector() != null) {
            method.addLine("descriptor.getEventManager().setPreDeleteSelector(\"" + descriptor.getEventManager().getPreDeleteSelector() + "\");");
        }
        if (descriptor.getEventManager().getPreInsertSelector() != null) {
            method.addLine("descriptor.getEventManager().setPreInsertSelector(\"" + descriptor.getEventManager().getPreInsertSelector() + "\");");
        }
        if (descriptor.getEventManager().getPreUpdateSelector() != null) {
            method.addLine("descriptor.getEventManager().setPreUpdateSelector(\"" + descriptor.getEventManager().getPreUpdateSelector() + "\");");
        }
        if (descriptor.getEventManager().getPreWriteSelector() != null) {
            method.addLine("descriptor.getEventManager().setPreWriteSelector(\"" + descriptor.getEventManager().getPreWriteSelector() + "\");");
        }
    }

    protected void addForeignReferenceMappingLines(NonreflectiveMethodDefinition method, String mappingName, ForeignReferenceMapping mapping) {
        if (mapping.getReferenceClassName() != null) {
            method.addLine(mappingName + ".setReferenceClass(" + mapping.getReferenceClassName() + ".class);");
        }

        if (mapping.getRelationshipPartnerAttributeName() != null) {
            method.addLine(mappingName + ".setRelationshipPartnerAttributeName(\"" + mapping.getRelationshipPartnerAttributeName() + "\");");
        }

        IndirectionPolicy policy = mapping.getIndirectionPolicy();
        if (policy instanceof ContainerIndirectionPolicy) {
            String containerClassName = ((ContainerIndirectionPolicy)policy).getContainerClassName();
            method.addLine(mappingName + ".useContainerIndirection(" + containerClassName + ".class);");
        //Bug#4251902 used in ObjectReferenceMapping
        } else if (policy instanceof ProxyIndirectionPolicy) {
            method.addLine(mappingName + ".useProxyIndirection();");
        } else if (policy instanceof BasicIndirectionPolicy) {
            method.addLine(mappingName + ".useBasicIndirection();");
        } else if (policy instanceof NoIndirectionPolicy) {
            method.addLine(mappingName + ".dontUseIndirection();");
        }

        if (mapping.shouldUseBatchReading()) {
            method.addLine(mappingName + ".useBatchReading();");
        }
        if (mapping.isJoinFetched()) {
            if (mapping.isInnerJoinFetched()) {
                method.addLine(mappingName + ".useInnerJoinFetch();");
            } else if (mapping.isOuterJoinFetched()) {
                method.addLine(mappingName + ".useOuterJoinFetch();");
            }
        }

        if ((!mapping.isDirectCollectionMapping()) && mapping.isPrivateOwned()) {
            method.addLine(mappingName + ".privateOwnedRelationship();");
        }

        if (mapping.isCollectionMapping()) {
            CollectionMapping collectionMapping = (CollectionMapping)mapping;
            String collectionClassName = collectionMapping.getContainerPolicy().getContainerClassName();
            if (mapping.getContainerPolicy().isCollectionPolicy()) {
                if (policy instanceof TransparentIndirectionPolicy) {
                    method.addLine(mappingName + ".useTransparentCollection();");
                }
                if (!collectionClassName.equals(Vector.class.getName())) {
                    method.addLine(mappingName + ".useCollectionClass(" + collectionClassName + ".class);");
                }
            } else if (collectionMapping.isDirectMapMapping()) {
                if (policy instanceof TransparentIndirectionPolicy) {
                    method.addLine(mappingName + ".useTransparentMap();");
                    if (!collectionClassName.equals(IndirectMap.class.getName())) {
                        method.addLine(mappingName + ".useMapClass(" + collectionClassName + ".class);");
                    }
                } else {
                    method.addLine(mappingName + ".useMapClass(" + collectionClassName + ".class);");
                }
            } else if (collectionMapping.getContainerPolicy().isMapPolicy()) {
                String keyMethodName = ((org.eclipse.persistence.internal.queries.MapContainerPolicy)collectionMapping.getContainerPolicy()).getKeyName();
                if (policy instanceof TransparentIndirectionPolicy) {
                    method.addLine(mappingName + ".useTransparentMap(\"" + keyMethodName + "\");");
                    if (!collectionClassName.equals(IndirectMap.class.getName())) {
                        method.addLine(mappingName + ".useMapClass(" + collectionClassName + ".class, \"" + keyMethodName + "\");");
                    }
                } else {
                    method.addLine(mappingName + ".useMapClass(" + collectionClassName + ".class, \"" + keyMethodName + "\");");
                }
            }

            // Ordering.
            Iterator queryKeyExpressions = collectionMapping.getOrderByQueryKeyExpressions().iterator();
            while (queryKeyExpressions.hasNext()) {
                FunctionExpression expression = (FunctionExpression) queryKeyExpressions.next();
                String queryKeyName = expression.getBaseExpression().getName();

                if (expression.getOperator().getSelector() == ExpressionOperator.Descending) {
                    method.addLine(mappingName + ".addDescendingOrdering(\"" + queryKeyName + "\");");
                } else {
                    method.addLine(mappingName + ".addAscendingOrdering(\"" + queryKeyName + "\");");
                }
            }
        }
    }

    protected void addHistoryPolicyLines(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        if (descriptor.getHistoryPolicy() == null) {
            return;
        }
        addHistoryPolicyLines(method, descriptor.getHistoryPolicy(), "historyPolicy");
        method.addLine("descriptor.setHistoryPolicy(historyPolicy);");
    }

    protected void addHistoryPolicyLines(NonreflectiveMethodDefinition method, DirectCollectionMapping mapping, String mappingName) {
        if (mapping.getHistoryPolicy() == null) {
            return;
        }
        String policyName = mapping.getAttributeName() + "HistoryPolicy";
        addHistoryPolicyLines(method, mapping.getHistoryPolicy(), policyName);
        method.addLine(mappingName + ".setHistoryPolicy(" + policyName + ");");
    }

    protected void addHistoryPolicyLines(NonreflectiveMethodDefinition method, ManyToManyMapping mapping, String mappingName) {
        if (mapping.getHistoryPolicy() == null) {
            return;
        }
        String policyName = mapping.getAttributeName() + "HistoryPolicy";
        addHistoryPolicyLines(method, mapping.getHistoryPolicy(), policyName);
        method.addLine(mappingName + ".setHistoryPolicy(" + policyName + ");");
    }

    protected void addHistoryPolicyLines(NonreflectiveMethodDefinition method, HistoryPolicy policy, String policyName) {
        method.addLine("");
        method.addLine("// History Policy");

        method.addLine("HistoryPolicy " + policyName + " = new HistoryPolicy();");
        for (DatabaseTable table : policy.getHistoricalTables()) {
            String sourceName = null;
            if (table.getTableQualifier().equals("")) {
                sourceName = table.getName();
            } else {
                sourceName = table.getTableQualifier() + "." + table.getName();
            }
            String historyName = table.getQualifiedName();
            method.addLine(policyName + ".addHistoryTableName(\"" + sourceName + "\", \"" + historyName + "\");");
        }
        for (DatabaseField field : policy.getStartFields()) {
            method.addLine(policyName + ".addStartFieldName(\"" + field.getQualifiedName() + "\");");

            // Field classifications don't seem to be supported in workbench integration.
            //method.addLine(policyName + ".setStartFieldType(\"" + field.getQualifiedName() + "\", " + field.getType().getName() + ".class);");
        }
        for (DatabaseField field : policy.getEndFields()) {
            method.addLine(policyName + ".addEndFieldName(\"" + field.getQualifiedName() + "\");");
            //method.addLine(policyName + ".setEndFieldType(\"" + field.getQualifiedName() + "\", " + field.getType().getName() + ".class);");
        }
        method.addLine(policyName + ".setShouldHandleWrites(" + (policy.shouldHandleWrites() ? "true" : "false") + ");");
        if (policy.shouldUseLocalTime()) {
            method.addLine(policyName + ".useLocalTime();");
        } else {
            method.addLine(policyName + ".useDatabaseTime();");
        }
    }

    protected void addInheritanceLines(NonreflectiveMethodDefinition method, InheritancePolicy policy) {
        method.addLine("// Inheritance Properties.");
        if (policy.isChildDescriptor()) {
            method.addLine("descriptor.getInheritancePolicy().setParentClass(" + policy.getParentClassName() + ".class);");
        } else {
            if (policy.getClassExtractionMethodName() != null) {
                method.addLine("descriptor.getInheritancePolicy().setClassExtractionMethodName(\"" + policy.getClassExtractionMethodName() + "\");");
            } else if (policy.getClassIndicatorField() != null) {
                method.addLine("descriptor.getInheritancePolicy().setClassIndicatorFieldName(\"" + policy.getClassIndicatorField().getQualifiedName() + "\");");

                if (policy.shouldUseClassNameAsIndicator()) {
                    method.addLine("descriptor.getInheritancePolicy().useClassNameAsIndicator();");
                } else {
                    for (Iterator indicatorsEnum = policy.getClassNameIndicatorMapping().keySet().iterator();
                             indicatorsEnum.hasNext();) {
                        String className = (String)indicatorsEnum.next();
                        Object value = policy.getClassNameIndicatorMapping().get(className);
                        method.addLine("descriptor.getInheritancePolicy().addClassIndicator(" + className + ".class, " + printString(value) + ");");
                    }
                }
            }
        }
        // Subclasses view
        if (policy.getReadAllSubclassesView() != null) {
            method.addLine("descriptor.getInheritancePolicy().setReadAllSubclassesViewName(\"" + policy.getReadAllSubclassesViewName() + "\");");
        }
        // Join-subclasses
        if (policy.shouldOuterJoinSubclasses()) {
            method.addLine("descriptor.getInheritancePolicy().setShouldOuterJoinSubclasses(true);");
        }

        if (!policy.shouldReadSubclasses()) {
            method.addLine("descriptor.getInheritancePolicy().dontReadSubclassesOnQueries();");
        }
    }

    protected void addInterfaceLines(NonreflectiveMethodDefinition method, InterfacePolicy policy) {
        method.addLine("// Interface Properties.");
        if (policy.isInterfaceChildDescriptor()) {
            for (Iterator<String> interfacesEnum = policy.getParentInterfaceNames().iterator();
                     interfacesEnum.hasNext();) {
                String parentInterfaceName = interfacesEnum.next();
                method.addLine("descriptor.getInterfacePolicy().addParentInterface(" + parentInterfaceName + ".class);");
            }
        }
    }

    protected void addManyToManyMappingLines(NonreflectiveMethodDefinition method, String mappingName, ManyToManyMapping mapping) {
        if (mapping.getRelationTable() != null) {
            method.addLine(mappingName + ".setRelationTableName(\"" + mapping.getRelationTable().getQualifiedName() + "\");");
        }

        Enumeration sourceRelationKeysEnum = mapping.getSourceRelationKeyFields().elements();
        Enumeration sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceRelationKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = (DatabaseField)sourceKeysEnum.nextElement();
            DatabaseField relationField = (DatabaseField)sourceRelationKeysEnum.nextElement();
            method.addLine(mappingName + ".addSourceRelationKeyFieldName(\"" + relationField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }

        Enumeration targetRelationKeysEnum = mapping.getTargetRelationKeyFields().elements();
        Enumeration targetKeysEnum = mapping.getTargetKeyFields().elements();
        while (targetRelationKeysEnum.hasMoreElements()) {
            DatabaseField targetField = (DatabaseField)targetKeysEnum.nextElement();
            DatabaseField relationField = (DatabaseField)targetRelationKeysEnum.nextElement();
            method.addLine(mappingName + ".addTargetRelationKeyFieldName(\"" + relationField.getQualifiedName() + "\", \"" + targetField.getQualifiedName() + "\");");
        }

        addHistoryPolicyLines(method, mapping, mappingName);
    }

    protected void addMappingLines(NonreflectiveMethodDefinition method, DatabaseMapping mapping) {
        String mappingName = mapping.getAttributeName() + "Mapping";
        String mappingClassName = mapping.getClass().getName();
        String packageName = mappingClassName.substring(0, mappingClassName.lastIndexOf('.'));
        if (packageName.equals("org.eclipse.persistence.mappings")) {
            mappingClassName = Helper.getShortClassName(mapping);
        }
        method.addLine(mappingClassName + " " + mappingName + " = new " + mappingClassName + "();");
        if (!mapping.isWriteOnly()) {
            method.addLine(mappingName + ".setAttributeName(\"" + mapping.getAttributeName() + "\");");
            if (mapping.getGetMethodName() != null) {
                method.addLine(mappingName + ".setGetMethodName(\"" + mapping.getGetMethodName() + "\");");
            }
            if (mapping.getSetMethodName() != null) {
                method.addLine(mappingName + ".setSetMethodName(\"" + mapping.getSetMethodName() + "\");");
            }
        }
        if (mapping.isAbstractDirectMapping()) {
            AbstractDirectMapping directMapping = (AbstractDirectMapping)mapping;
            if (mapping.getDescriptor().isAggregateDescriptor()) {
                method.addLine(mappingName + ".setFieldName(\"" + directMapping.getField().getName() + "\");");
            } else {
                method.addLine(mappingName + ".setFieldName(\"" + directMapping.getField().getQualifiedName() + "\");");
            }
            if (directMapping.getNullValue() != null) {
                method.addLine(mappingName + ".setNullValue(" + printString(directMapping.getNullValue()) + ");");
            }
            Converter converter = directMapping.getConverter();
            if (converter != null) {
                addConverterLines(method, mappingName + "Converter", converter);
                method.addLine(mappingName + ".setConverter(" + mappingName + "Converter" + ");");
            }
        } else if (mapping.isForeignReferenceMapping()) {
            addForeignReferenceMappingLines(method, mappingName, (ForeignReferenceMapping)mapping);
        }

        if (mapping.isReadOnly()) {
            method.addLine(mappingName + ".readOnly();");
        }

        if (mapping.isAggregateObjectMapping()) {
            addAggregateObjectMappingLines(method, mappingName, (AggregateObjectMapping)mapping);
        } else if (mapping.isOneToOneMapping()) {
            addOneToOneMappingLines(method, mappingName, (OneToOneMapping)mapping);
        } else if (mapping.isOneToManyMapping()) {
            addOneToManyMappingLines(method, mappingName, (OneToManyMapping)mapping);
        } else if (mapping.isManyToManyMapping()) {
            addManyToManyMappingLines(method, mappingName, (ManyToManyMapping)mapping);
        } else if (mapping.isTransformationMapping()) {
            addTransformationMappingLines(method, mappingName, (TransformationMapping)mapping);
        } else if (mapping.isDirectCollectionMapping()) {
            addDirectCollectionMappingLines(method, mappingName, (DirectCollectionMapping)mapping);
        } else if (mapping.isAggregateCollectionMapping()) {
            addAggregateCollectionMappingLines(method, mappingName, (AggregateCollectionMapping)mapping);
        } else if (mapping.isVariableOneToOneMapping()) {
            addVariableOneToOneMappingLines(method, mappingName, (VariableOneToOneMapping)mapping);
        }

        if (mapping.isDirectMapMapping()) {
            addDirectMapMappingLines(method, mappingName, (DirectMapMapping)mapping);
        }
        if (mapping.isDirectToXMLTypeMapping()) {
            DirectToXMLTypeMappingHelper.getInstance().writeShouldreadWholeDocument(method, mappingName, mapping);
        }
        method.addLine("descriptor.addMapping(" + mapping.getAttributeName() + "Mapping);");
    }

    protected void addObjectTypeConverterLines(NonreflectiveMethodDefinition method, String converterName, ObjectTypeConverter converter) {
        if (converter.getDefaultAttributeValue() != null) {
            method.addLine(converterName + ".setDefaultAttributeValue(" + printString(converter.getDefaultAttributeValue()) + ");");
        }
        for (Iterator typesEnum = converter.getAttributeToFieldValues().keySet().iterator();
                 typesEnum.hasNext();) {
            Object attributeValue = typesEnum.next();
            Object fieldValue = converter.getAttributeToFieldValues().get(attributeValue);
            method.addLine(converterName + ".addConversionValue(" + printString(fieldValue) + ", " + printString(attributeValue) + ");");
        }

        // Read-only conversions.
        for (Iterator typesEnum = converter.getFieldToAttributeValues().keySet().iterator();
                 typesEnum.hasNext();) {
            Object fieldValue = typesEnum.next();
            Object attributeValue = converter.getFieldToAttributeValues().get(fieldValue);
            if (!converter.getAttributeToFieldValues().containsKey(attributeValue)) {
                method.addLine(converterName + ".addToAttributeOnlyConversionValue(" + printString(fieldValue) + ", " + printString(attributeValue) + ");");
            }
        }
    }

    protected void addOneToManyMappingLines(NonreflectiveMethodDefinition method, String mappingName, OneToManyMapping mapping) {
        Enumeration targetKeysEnum = mapping.getTargetForeignKeyFields().elements();
        Enumeration sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = (DatabaseField)sourceKeysEnum.nextElement();
            DatabaseField targetField = (DatabaseField)targetKeysEnum.nextElement();
            method.addLine(mappingName + ".addTargetForeignKeyFieldName(\"" + targetField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }
    }

    protected void addOneToOneMappingLines(NonreflectiveMethodDefinition method, String mappingName, OneToOneMapping mapping) {
        for (Iterator foreignKeysEnum = mapping.getSourceToTargetKeyFields().keySet().iterator();
                 foreignKeysEnum.hasNext();) {
            DatabaseField sourceField = (DatabaseField)foreignKeysEnum.next();
            DatabaseField targetField = mapping.getSourceToTargetKeyFields().get(sourceField);
            if (mapping.getForeignKeyFields().contains(sourceField)) {
                method.addLine(mappingName + ".addForeignKeyFieldName(\"" + sourceField.getQualifiedName() + "\", \"" + targetField.getQualifiedName() + "\");");
            } else {
                method.addLine(mappingName + ".addTargetForeignKeyFieldName(\"" + targetField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
            }
        }
        if (!mapping.shouldVerifyDelete()) {
            method.addLine(mappingName + ".setShouldVerifyDelete(false);");
        }
    }

    protected void addOptimisticLockingLines(NonreflectiveMethodDefinition method, OptimisticLockingPolicy policy) {
        String policyClassName = policy.getClass().getName();
        String packageName = policyClassName.substring(0, policyClassName.lastIndexOf('.'));
        if (packageName.equals("org.eclipse.persistence.descriptors")) {
            policyClassName = Helper.getShortClassName(policy);
        }
        method.addLine(policyClassName + " lockingPolicy = new " + policyClassName + "();");

        if (policy instanceof SelectedFieldsLockingPolicy) {
            SelectedFieldsLockingPolicy fieldPolicy = (SelectedFieldsLockingPolicy)policy;
            for ( DatabaseField field : fieldPolicy.getLockFields()) {
                method.addLine("lockingPolicy.addLockFieldName(\"" + field.getQualifiedName() + "\");");
            }
        } else if (policy instanceof VersionLockingPolicy) {
            VersionLockingPolicy versionPolicy = (VersionLockingPolicy)policy;
            method.addLine("lockingPolicy.setWriteLockFieldName(\"" + versionPolicy.getWriteLockField().getQualifiedName() + "\");");
            if (versionPolicy.isStoredInObject()) {
                method.addLine("lockingPolicy.storeInObject();");
            }
            if (policy instanceof TimestampLockingPolicy) {
                TimestampLockingPolicy timestampPolicy = (TimestampLockingPolicy)policy;
                if (timestampPolicy.usesLocalTime()) {
                    method.addLine("lockingPolicy.useLocalTime();");
                }
            }
        }

        method.addLine("descriptor.setOptimisticLockingPolicy(lockingPolicy);");
    }

    protected void addQueryKeyLines(NonreflectiveMethodDefinition method, QueryKey queryKey) {
        if (queryKey.isDirectQueryKey()) {
            method.addLine("descriptor.addDirectQueryKey(\"" + queryKey.getName() + "\", \"" + ((DirectQueryKey)queryKey).getField().getQualifiedName() + "\");");
        } else if (queryKey.isAbstractQueryKey()) {
            method.addLine("descriptor.addAbstractQueryKey(\"" + queryKey.getName() + "\");");
        }
    }

    protected void addQueryManagerPropertyLines(NonreflectiveMethodDefinition method, ClassDescriptor descriptor) {
        method.addLine("// Query Manager.");
        // Existence check.
        if (!descriptor.isDescriptorTypeAggregate() && (!descriptor.isDescriptorForInterface())) {
            if (descriptor.getQueryManager().getDoesExistQuery().shouldAssumeExistenceForDoesExist()) {
                method.addLine("descriptor.getQueryManager().assumeExistenceForDoesExist();");
            } else if (descriptor.getQueryManager().getDoesExistQuery().shouldAssumeNonExistenceForDoesExist()) {
                method.addLine("descriptor.getQueryManager().assumeNonExistenceForDoesExist();");
            } else if (descriptor.getQueryManager().getDoesExistQuery().shouldCheckCacheForDoesExist()) {
                method.addLine("descriptor.getQueryManager().checkCacheForDoesExist();");
            } else if (descriptor.getQueryManager().getDoesExistQuery().shouldCheckDatabaseForDoesExist()) {
                method.addLine("descriptor.getQueryManager().checkDatabaseForDoesExist();");
            }
        }

        // Query timeout.
        if (descriptor.getQueryManager().getQueryTimeout() != DescriptorQueryManager.DefaultTimeout) {
            method.addLine("descriptor.getQueryManager().setQueryTimeout(" + descriptor.getQueryManager().getQueryTimeout() + ");");
        }
        if (!descriptor.getQueryManager().getQueryTimeoutUnit().equals(DescriptorQueryManager.DefaultTimeoutUnit)) {
            method.addLine("descriptor.getQueryManager().setQueryTimeoutUnit(" + descriptor.getQueryManager().getQueryTimeoutUnit() + ");");
        }

        // Custom SQL.
        if (descriptor.getQueryManager().hasReadObjectQuery() && descriptor.getQueryManager().getReadObjectQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setReadObjectSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getReadObjectQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasReadObjectQuery() && descriptor.getQueryManager().getReadObjectQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getReadObjectQuery().getDatasourceCall(), "readObjectCall");
            method.addLine("descriptor.getQueryManager().setReadObjectCall(readObjectCall);");
        }
        if (descriptor.getQueryManager().hasReadAllQuery() && descriptor.getQueryManager().getReadAllQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setReadAllSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getReadAllQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasReadAllQuery() && descriptor.getQueryManager().getReadAllQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getReadAllQuery().getDatasourceCall(), "readAllCall");
            method.addLine("descriptor.getQueryManager().setReadAllCall(readAllCall);");
        }
        if (descriptor.getQueryManager().hasInsertQuery() && descriptor.getQueryManager().getInsertQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setInsertSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getInsertQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasInsertQuery() && descriptor.getQueryManager().getInsertQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getInsertQuery().getDatasourceCall(), "insertCall");
            method.addLine("descriptor.getQueryManager().setInsertCall(insertCall);");
        }
        if (descriptor.getQueryManager().hasUpdateQuery() && descriptor.getQueryManager().getUpdateQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setUpdateSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getUpdateQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasUpdateQuery() && descriptor.getQueryManager().getUpdateQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getUpdateQuery().getDatasourceCall(), "updateCall");
            method.addLine("descriptor.getQueryManager().setUpdateCall(updateCall);");
        }
        if (descriptor.getQueryManager().hasDeleteQuery() && descriptor.getQueryManager().getDeleteQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setDeleteSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getDeleteQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasDeleteQuery() && descriptor.getQueryManager().getUpdateQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getDeleteQuery().getDatasourceCall(), "deleteCall");
            method.addLine("descriptor.getQueryManager().setDeleteCall(deleteCall);");
        }
        if (descriptor.getQueryManager().hasDoesExistQuery() && descriptor.getQueryManager().getDoesExistQuery().isSQLCallQuery()) {
            method.addLine("descriptor.getQueryManager().setDoesExistSQLString(\""
              + constructValidSQLorEJBQLLinesForJavaSource(descriptor.getQueryManager().getDoesExistQuery().getSQLString()) + "\");");
        } else if (descriptor.getQueryManager().hasDoesExistQuery() && descriptor.getQueryManager().getDoesExistQuery().getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)descriptor.getQueryManager().getDoesExistQuery().getDatasourceCall(), "doesExistCall");
            method.addLine("descriptor.getQueryManager().setDoesExistCall(doesExistCall);");
        }

        // Named queries.
        if (descriptor.getQueryManager().getAllQueries().size() > 0) {
            method.addLine("// Named Queries.");
            Enumeration namedQueries = descriptor.getQueryManager().getAllQueries().elements();
            int iteration = 0;
            while (namedQueries.hasMoreElements()) {
                addNamedQueryLines(method, (DatabaseQuery)namedQueries.nextElement(), descriptor.getQueryManager(), iteration);
                ++iteration;
            }
        }
    }

    private String constructValidSQLorEJBQLLinesForJavaSource(String qlString){
        //Bug2612384 Deals with the possibility of multi-line SQL statements.
        //Expects beginning and closing quotes to be in place
        if (qlString != null) {
            String insertString = "\" " + Helper.cr() + '\t' + '\t' + "+ " + "\"";
            qlString = qlString.trim().replaceAll("\n", insertString);
        }
        return qlString;
    }

    protected void addXMLInteractionLines(NonreflectiveMethodDefinition method, XMLInteraction interaction, String variableName) {
        method.addLine("org.eclipse.persistence.eis.XMLInteraction " + variableName + " = new org.eclipse.persistence.eis.XMLInteraction();");
        if ((interaction.getFunctionName() != null) && (interaction.getFunctionName().length() != 0)) {
            method.addLine(variableName + ".setFunctionName(\"" + interaction.getFunctionName() + "\");");
        }
        if ((interaction.getInputRecordName() != null) && (interaction.getInputRecordName().length() != 0)) {
            method.addLine(variableName + ".setInputRecordName(\"" + interaction.getInputRecordName() + "\");");
        }
        if ((interaction.getInputRootElementName() != null) && (interaction.getInputRootElementName().length() != 0)) {
            method.addLine(variableName + ".setInputRootElementName(\"" + interaction.getInputRootElementName() + "\");");
        }
        if ((interaction.getInputResultPath() != null) && (interaction.getInputResultPath().length() != 0)) {
            method.addLine(variableName + ".setInputResultPath(\"" + interaction.getInputResultPath() + "\");");
        }
        if ((interaction.getOutputResultPath() != null) && (interaction.getOutputResultPath().length() != 0)) {
            method.addLine(variableName + ".setOutputResultPath(\"" + interaction.getOutputResultPath() + "\");");
        }
        for (int index = interaction.getArgumentNames().size();
                 index < interaction.getArgumentNames().size(); index++) {
            String argumentName = (String)interaction.getArgumentNames().get(index);
            String argument = (String)interaction.getArguments().get(index);
            method.addLine(variableName + ".addArgument(\"" + argumentName + "\", \"" + argument + "\");");
        }
    }

    protected void addNamedQueryLines(NonreflectiveMethodDefinition method, DatabaseQuery query, DescriptorQueryManager queryManager, int iteration) {
        String queryIdentifier = "namedQuery" + String.valueOf(iteration);
        method.addLine("// Named Query -- " + query.getName());
        String className = "";
        if (query.getDescriptor() != null) {
            className = query.getDescriptor().getJavaClassName();
        } else {
            //in default mapping, the query has not been associated with a descriptor before generation.
            className = query.getReferenceClassName();
        }
        if (query.isReportQuery()) {
            method.addLine("ReportQuery " + queryIdentifier + " = new ReportQuery(" + className + ".class, new ExpressionBuilder());");
        } else if (query.isReadAllQuery()) {
            method.addLine("ReadAllQuery " + queryIdentifier + " = new ReadAllQuery(" + className + ".class);");
        } else if (query.isReadObjectQuery()) {
            method.addLine("ReadObjectQuery " + queryIdentifier + " = new ReadObjectQuery(" + className + ".class);");
        } else if (query.isValueReadQuery()) {
            method.addLine("ValueReadQuery " + queryIdentifier + " = new ValueReadQuery();");
        } else if (query.isDataReadQuery()) {
            method.addLine("DataReadQuery " + queryIdentifier + " = new DataReadQuery();");
        } else if (query.isDirectReadQuery()) {
            method.addLine("DirectReadQuery " + queryIdentifier + " = new DirectReadQuery();");
        }
        if (query.getSQLString() != null) {
            method.addLine(queryIdentifier + ".setSQLString(\"" + constructValidSQLorEJBQLLinesForJavaSource(query.getSQLString()) + "\");");
        } else if (query.getEJBQLString() != null) {
            method.addLine(queryIdentifier + ".setEJBQLString(\"" + constructValidSQLorEJBQLLinesForJavaSource(query.getEJBQLString()) + "\");");
        } else if (query.getDatasourceCall() instanceof XMLInteraction) {
            addXMLInteractionLines(method, (XMLInteraction)query.getDatasourceCall(), queryIdentifier + "Call");
            method.addLine(queryIdentifier + ".setCall(" + queryIdentifier + "Call" + ");");
        }

        if ((query.getRedirector() != null) && (query.getRedirector().getClass().equals(MethodBaseQueryRedirector.class))) {
            method.addLine(queryIdentifier + ".setRedirector(new MethodBaseQueryRedirector(" + ((MethodBaseQueryRedirector)query.getRedirector()).getMethodClassName() + ".class, \"" + ((MethodBaseQueryRedirector)query.getRedirector()).getMethodName() + "\"));");
        }
        method.addLine(queryIdentifier + ".setName(\"" + query.getName() + "\");");
        if ((!query.isReadQuery()) || (query.getCascadePolicy() != DatabaseQuery.NoCascading)) {
            String cascadePolicy = "DatabaseQuery.NoCascading";
            if (query.getCascadePolicy() == DatabaseQuery.CascadePrivateParts) {
                cascadePolicy = "DatabaseQuery.CascadePrivateParts";
            } else if (query.getCascadePolicy() == DatabaseQuery.CascadeDependentParts) {
                cascadePolicy = "DatabaseQuery.CascadeDependentParts";
            } else if (query.getCascadePolicy() == DatabaseQuery.CascadeAllParts) {
                cascadePolicy = "DatabaseQuery.CascadeAllParts";
            }
            method.addLine(queryIdentifier + ".setCascadePolicy(" + cascadePolicy + ");");
        }
        if (query.getQueryTimeout() != DescriptorQueryManager.DefaultTimeout) {
            method.addLine(queryIdentifier + ".setQueryTimeout(" + String.valueOf(query.getQueryTimeout()) + ");");
        }
        if (query.getQueryTimeoutUnit() != DescriptorQueryManager.DefaultTimeoutUnit) {
            method.addLine(queryIdentifier + ".setQueryTimeoutUnit(" + query.getQueryTimeoutUnit() + ");");
        }
        if (!query.shouldUseWrapperPolicy()) {
            method.addLine(queryIdentifier + ".setShouldUseWrapperPolicy(" + String.valueOf(query.shouldUseWrapperPolicy()) + ");");
        }
        if (!query.shouldIgnoreBindAllParameters()) {
            method.addLine(queryIdentifier + ".setShouldBindAllParameters(" + String.valueOf(query.shouldBindAllParameters()) + ");");
        }
        if (!query.shouldIgnoreCacheStatement()) {
            method.addLine(queryIdentifier + ".setShouldCacheStatement(" + String.valueOf(query.shouldCacheStatement()) + ");");
        }
        if (query.getSessionName() != null) {
            method.addLine(queryIdentifier + ".setSessionName(\"" + query.getSessionName() + "\");");
        }
        if (!query.shouldMaintainCache()) {
            method.addLine(queryIdentifier + ".setShouldMaintainCache(" + String.valueOf(query.shouldMaintainCache()) + ");");
        }
        if (!query.shouldPrepare()) {
            method.addLine(queryIdentifier + ".setShouldPrepare(" + String.valueOf(query.shouldPrepare()) + ");");
        }

        if (query.isReadQuery()) {
            ReadQuery readQuery = (ReadQuery)query;
            if (readQuery.shouldCacheQueryResults()) {
                method.addLine(queryIdentifier + ".setQueryResultsCachePolicy(new QueryResultsCachePolicy());");
            }
            if (readQuery.getMaxRows() != 0) {
                method.addLine(queryIdentifier + ".setMaxRows(" + String.valueOf(readQuery.getMaxRows()) + ");");
            }
            if (readQuery.getFirstResult() != 0) {
                method.addLine(queryIdentifier + ".setFirstResult(" + String.valueOf(readQuery.getFirstResult()) + ");");
            }
        }

        //ExpressionBuilder string
        String builderString = null;

        if (query.isObjectLevelReadQuery()) {
            ObjectLevelReadQuery readQuery = (ObjectLevelReadQuery)query;

            // Refresh.
            if (readQuery.shouldRefreshIdentityMapResult()) {
                method.addLine(queryIdentifier + ".setShouldRefreshIdentityMapResult(" + String.valueOf(readQuery.shouldRefreshIdentityMapResult()) + ");");
            }

            // Cache usage.
            if (readQuery.getCacheUsage() != ObjectLevelReadQuery.UseDescriptorSetting) {
                String cacheUsage = "ObjectLevelReadQuery.UseDescriptorSetting";
                if (readQuery.getCacheUsage() == ObjectLevelReadQuery.DoNotCheckCache) {
                    cacheUsage = "ObjectLevelReadQuery.DoNotCheckCache";
                } else if (readQuery.getCacheUsage() == ObjectLevelReadQuery.CheckCacheByExactPrimaryKey) {
                    cacheUsage = "ObjectLevelReadQuery.CheckCacheByExactPrimaryKey";
                } else if (readQuery.getCacheUsage() == ObjectLevelReadQuery.CheckCacheByPrimaryKey) {
                    cacheUsage = "ObjectLevelReadQuery.CheckCacheByPrimaryKey";
                } else if (readQuery.getCacheUsage() == ObjectLevelReadQuery.CheckCacheThenDatabase) {
                    cacheUsage = "ObjectLevelReadQuery.CheckCacheThenDatabase";
                } else if (readQuery.getCacheUsage() == ObjectLevelReadQuery.CheckCacheOnly) {
                    cacheUsage = "ObjectLevelReadQuery.CheckCacheOnly";
                } else if (readQuery.getCacheUsage() == ObjectLevelReadQuery.ConformResultsInUnitOfWork) {
                    cacheUsage = "ObjectLevelReadQuery.ConformResultsInUnitOfWork";
                }
                method.addLine(queryIdentifier + ".setCacheUsage(" + cacheUsage + ");");
            }

            // Lock mode.
            if (readQuery.getLockMode() != ObjectLevelReadQuery.DEFAULT_LOCK_MODE) {
                String lockMode = null;
                if (readQuery.getLockMode() == ObjectLevelReadQuery.NO_LOCK && !readQuery.isReportQuery()) {
                    lockMode = "ObjectLevelReadQuery.NO_LOCK";
                } else if (readQuery.getLockMode() == ObjectLevelReadQuery.LOCK) {
                    lockMode = "ObjectLevelReadQuery.LOCK";
                } else if (readQuery.getLockMode() == ObjectLevelReadQuery.LOCK_NOWAIT) {
                    lockMode = "ObjectLevelReadQuery.LOCK_NOWAIT";
                }
                if (lockMode != null) {
                    method.addLine(queryIdentifier + ".setLockMode(" + lockMode + ");");
                }
            }

            // Remote refresh.
            if (readQuery.shouldRefreshRemoteIdentityMapResult()) {
                method.addLine(queryIdentifier + ".setShouldRefreshRemoteIdentityMapResult(" + String.valueOf(readQuery.shouldRefreshRemoteIdentityMapResult()) + ");");
            }

            // Distinct state.
            if (readQuery.getDistinctState() != ObjectLevelReadQuery.UNCOMPUTED_DISTINCT) {
                String distinctState = "ObjectLevelReadQuery.UNCOMPUTED_DISTINCT";
                if (readQuery.getDistinctState() == ObjectLevelReadQuery.USE_DISTINCT) {
                    distinctState = "ObjectLevelReadQuery.USE_DISTINCT";
                } else if (readQuery.getDistinctState() == ObjectLevelReadQuery.DONT_USE_DISTINCT) {
                    distinctState = "ObjectLevelReadQuery.DONT_USE_DISTINCT";
                }
                method.addLine(queryIdentifier + ".setDistinctState((short)" + distinctState + ");");
            }

            // In-memory policy.
            if (readQuery.getInMemoryQueryIndirectionPolicy().getPolicy() != InMemoryQueryIndirectionPolicy.SHOULD_THROW_INDIRECTION_EXCEPTION) {
                String inMemoryQueryIndirectionPolicy = "InMemoryQueryIndirectionPolicy.SHOULD_THROW_INDIRECTION_EXCEPTION";
                if (readQuery.getInMemoryQueryIndirectionPolicy().getPolicy() == InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION) {
                    inMemoryQueryIndirectionPolicy = "InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION";
                } else if (readQuery.getInMemoryQueryIndirectionPolicy().getPolicy() == InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_CONFORMED) {
                    inMemoryQueryIndirectionPolicy = "InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_CONFORMED";
                } else if (readQuery.getInMemoryQueryIndirectionPolicy().getPolicy() == InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_NOT_CONFORMED) {
                    inMemoryQueryIndirectionPolicy = "InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_NOT_CONFORMED";
                }
                method.addLine(queryIdentifier + ".setInMemoryQueryIndirectionPolicy(new InMemoryQueryIndirectionPolicy(" + inMemoryQueryIndirectionPolicy + "));");
            }

            // Fetch groups.
            if (!readQuery.shouldUseDefaultFetchGroup()) {
                method.addLine(queryIdentifier + ".setShouldUseDefaultFetchGroup(false);");
            }
            if (readQuery.getFetchGroupName() != null) {
                method.addLine(queryIdentifier + ".setFetchGroupName(\"" + readQuery.getFetchGroupName() + "\");");
            } else if (readQuery.getFetchGroup() != null) {
                String fetchGroupIdentifier = readQuery.getFetchGroup().getName() + "FetchGroup";
                addFetchGroupLines(method, readQuery.getFetchGroup(), fetchGroupIdentifier);
                method.addLine(queryIdentifier + ".setFetchGroup(" + fetchGroupIdentifier + ");");
            }

            // Exclusive Connection (VPD).
            if (readQuery.shouldUseExclusiveConnection()) {
                method.addLine(queryIdentifier + ".setShouldUseExclusiveConnection(true);");
            }

            // Read-only
            if (readQuery.isReadOnly()) {
                method.addLine(queryIdentifier + ".setIsReadOnly(true);");
            }

            // Join-subclasses
            if (readQuery.shouldOuterJoinSubclasses()) {
                method.addLine(queryIdentifier + ".setShouldOuterJoinSubclasses(true);");
            }

            // Selection criteria.
            if (readQuery.getSelectionCriteria() != null) {
                builderString = buildBuilderString(builderString, method, iteration, queryIdentifier);
                buildExpressionString(builderString, method, queryIdentifier, readQuery.getSelectionCriteria(), ".setSelectionCriteria(");
            }

            //joinedAttribute
            for (Iterator joinedEnum = readQuery.getJoinedAttributeManager().getJoinedAttributeExpressions().iterator(); joinedEnum.hasNext();) {
                Expression joinedExp = (Expression)joinedEnum.next();
                builderString = buildBuilderString(builderString, method, iteration, queryIdentifier);
                buildExpressionString(builderString, method, queryIdentifier, joinedExp, ".addJoinedAttribute(");
            }
        }

        //ReadAllQuery
        if (query.isReadAllQuery()) {
            ReadAllQuery readAllQuery = (ReadAllQuery)query;
            //orderBy
            for (Expression orderbyExpression : readAllQuery.getOrderByExpressions()) {
                builderString = buildBuilderString(builderString, method, iteration, queryIdentifier);
                buildExpressionString(builderString, method, queryIdentifier, orderbyExpression, ".addOrdering(");
            }
            //batchReadAttribute
            for (Expression batchReadExp : readAllQuery.getBatchReadAttributeExpressions()) {
                builderString = buildBuilderString(builderString, method, iteration, queryIdentifier);
                buildExpressionString(builderString, method, queryIdentifier, batchReadExp, ".addBatchReadAttribute(");
            }
            //resultCollection
            if (readAllQuery.getContainerPolicy().isCursoredStreamPolicy()) {
                method.addLine(queryIdentifier + ".useCursoredStream();");
            }
            if (readAllQuery.getContainerPolicy().isScrollableCursorPolicy()) {
                method.addLine(queryIdentifier + ".useScrollableCursor();");
            }
            if (readAllQuery.getContainerPolicy().isCollectionPolicy()) {
                String collectionClass = readAllQuery.getContainerPolicy().getContainerClassName();
                if (!collectionClass.equals("java.util.Vector")) {
                    method.addLine(queryIdentifier + ".useCollectionClass(" + collectionClass + ".class);");
                }
            }
        }

        //ReportQuery
        if (query.isReportQuery()) {
            ReportQuery reportQuery = (ReportQuery)query;
            //ExpressionBuilder string
            builderString = buildBuilderString(builderString, method, iteration, queryIdentifier);
            //ReportItems
            for (ReportItem item : reportQuery.getItems()) {
                Expression expression = item.getAttributeExpression();
                String itemName = item.getName();
                StringWriter writer = new StringWriter();
                ExpressionJavaPrinter javaPrinter = new ExpressionJavaPrinter(builderString, writer, project.getDatasourceLogin().getPlatform());
                if (expression != null) {
                    String functionString;
                    Expression baseExpression;  //used in ReportQuery API, e.g. addCount(itemName, baseExpression)
                    String databaseString = null;  //used in addFunctionItem()
                    if (expression.isQueryKeyExpression()) {
                        functionString = ".addAttribute(\"";
                        baseExpression = expression;
                    } else if (expression.isFunctionExpression()) {
                        int selector = expression.getOperator().getSelector();
                        baseExpression = ((FunctionExpression)expression).getBaseExpression();
                        if (selector == ExpressionOperator.Average) {
                            functionString = ".addAverage(\"";
                        } else if (selector == ExpressionOperator.Count) {
                            functionString = ".addCount(\"";
                        } else if (selector == ExpressionOperator.Maximum) {
                            functionString = ".addMaximum(\"";
                        } else if (selector == ExpressionOperator.Minimum) {
                            functionString = ".addMinimum(\"";
                        } else if (selector == ExpressionOperator.StandardDeviation) {
                            functionString = ".addStandardDeviation(\"";
                        } else if (selector == ExpressionOperator.Sum) {
                            functionString = ".addSum(\"";
                        } else if (selector == ExpressionOperator.Variance) {
                            functionString = ".addVariance(\"";
                        } else { //custom function
                            functionString = ".addFunctionItem(\"";
                            databaseString = expression.getOperator().getDatabaseStrings()[0];
                            databaseString = databaseString.substring(0, databaseString.length()-1);
                        }
                    } else {
                        functionString = ".addItem(\"";
                        baseExpression = expression;
                    }
                    baseExpression.printJava(javaPrinter);
                    if (databaseString == null) { //e.g. addCount(itemName, attributeExpression)
                        method.addLine(queryIdentifier + functionString + itemName + "\", " + writer.toString() + ");");
                    } else { //i.e. addFunctionItem(itemName, attributeExpression, functionName) only
                        method.addLine(queryIdentifier + functionString + itemName + "\", " + writer.toString() + ", \"" + databaseString + "\");");
                    }
                }
            }
            //groupBy
            for (Expression groupByExp : reportQuery.getGroupByExpressions()) {
                buildExpressionString(builderString, method, queryIdentifier, groupByExp, ".addGrouping(");
            }
            //shouldRetrievePrimaryKeys
            if (reportQuery.shouldRetrieveFirstPrimaryKey()) {
                method.addLine(queryIdentifier + ".setShouldRetrieveFirstPrimaryKey(true);");
            } else if (reportQuery.shouldRetrievePrimaryKeys()) {
                method.addLine(queryIdentifier + ".setShouldRetrievePrimaryKeys(true);");
            }
            //returnChoice
            if (reportQuery.shouldReturnSingleAttribute()) {
                method.addLine(queryIdentifier + ".setShouldReturnSingleAttribute(true);");
            } else if (reportQuery.shouldReturnSingleValue()) {
                method.addLine(queryIdentifier + ".setShouldReturnSingleValue(true);");
            } else {
                method.addLine(queryIdentifier + ".setShouldReturnSingleResult(true);");
            }
        }

        // Query arguments.
        Iterator<String> argumentTypes = query.getArgumentTypeNames().iterator();
        for (Iterator arguments = query.getArguments().iterator(); arguments.hasNext();) {
            String argument = (String)arguments.next();
            String argumentTypeName = argumentTypes.next();
            method.addLine(queryIdentifier + ".addArgument(\"" + argument + "\", " + argumentTypeName + ".class);");
        }

        method.addLine("descriptor.getQueryManager().addQuery(\"" + query.getName() + "\", " + queryIdentifier + ");");
        method.addLine("");
    }

    //Build ExpressionBuilder string
    protected String buildBuilderString(String builderString, NonreflectiveMethodDefinition method, int iteration, String queryIdentifier) {
        if (builderString == null) {
            builderString = "expBuilder" + String.valueOf(iteration);
            method.addLine("ExpressionBuilder " + builderString + " = " + queryIdentifier + ".getExpressionBuilder();");
        }
        return builderString;
    }

    //Build expression string for orderBy, batchRead, joined, selectionCriteria and groupBy. e.g. reportQuery1.addGrouping(exp)
    protected void buildExpressionString(String builderString, NonreflectiveMethodDefinition method, String queryIdentifier, Expression exp, String attrString) {
        StringWriter writer = new StringWriter();
        ExpressionJavaPrinter javaPrinter = new ExpressionJavaPrinter(builderString, writer, project.getDatasourceLogin().getPlatform());
        exp.printJava(javaPrinter);
        method.addLine(queryIdentifier + attrString + writer.toString() + ");");
    }

    protected void addReturningPolicyLines(NonreflectiveMethodDefinition method, ReturningPolicy policy) {
        if (policy.getFieldInfos().isEmpty()) {
            return;
        }
        addReturningPolicyLines(method, policy, "returningPolicy");
        method.addLine("descriptor.setReturningPolicy(returningPolicy);");
    }

    protected void addReturningPolicyLines(NonreflectiveMethodDefinition method, ReturningPolicy policy, String policyName) {
        method.addLine("");
        method.addLine("// Returning Policy");

        method.addLine("ReturningPolicy " + policyName + " = new ReturningPolicy();");
        String prefix = policyName + ".addFieldFor";
        String[] str = { null, null };
        for (ReturningPolicy.Info info : policy.getFieldInfos()) {
            String qualifiedFieldName = info.getField().getQualifiedName();
            String type = null;
            if (info.getField().getType() != null) {
                type = info.getField().getType().getName() + ".class";
            }
            if (info.isInsert()) {
                String strInsert = prefix + "Insert";
                if (info.isInsertModeReturnOnly()) {
                    strInsert = strInsert + "ReturnOnly";
                }
                str[0] = strInsert;
            }
            if (info.isUpdate()) {
                String strUpdate = prefix + "Update";
                str[1] = strUpdate;
            }
            for (int i = 0; i < 2; i++) {
                if (str[i] != null) {
                    str[i] = str[i] + "(\"" + qualifiedFieldName + "\"";
                    if (type != null) {
                        str[i] = str[i] + ", " + type;
                    }
                    str[i] = str[i] + ");";
                    method.addLine(str[i]);

                    str[i] = null;
                }
            }
        }
    }

    protected void addTransformationMappingLines(NonreflectiveMethodDefinition method, String mappingName, TransformationMapping mapping) {
        if (!mapping.isWriteOnly()) {
            if (mapping.getAttributeMethodName() != null) {
                method.addLine(mappingName + ".setAttributeTransformation(\"" + mapping.getAttributeMethodName() + "\");");
            } else {
                method.addLine(mappingName + ".setAttributeTransformer(new " + mapping.getAttributeTransformerClassName() + "());");
            }
        }

        Iterator fieldTransformations = mapping.getFieldTransformations().iterator();
        while (fieldTransformations.hasNext()) {
            FieldTransformation trans = (FieldTransformation)fieldTransformations.next();
            String fieldName = trans.getFieldName();
            if (trans instanceof MethodBasedFieldTransformation) {
                String methodName = ((MethodBasedFieldTransformation)trans).getMethodName();
                method.addLine(mappingName + ".addFieldTransformation(\"" + fieldName + "\", \"" + methodName + "\");");
            } else {
                String transformerClass = ((TransformerBasedFieldTransformation)trans).getTransformerClassName();
                method.addLine(mappingName + ".addFieldTransformer(\"" + fieldName + "\", new " + transformerClass + "());");
            }
        }

        IndirectionPolicy policy = mapping.getIndirectionPolicy();
        if (policy instanceof ContainerIndirectionPolicy) {
            String containerClassName = ((ContainerIndirectionPolicy)policy).getContainerClassName();
            method.addLine(mappingName + ".useContainerIndirection(" + containerClassName + ".class);");
        } else if (policy instanceof BasicIndirectionPolicy) {
            method.addLine(mappingName + ".useBasicIndirection();");
        }
        method.addLine(mappingName + ".setIsMutable(" + mapping.isMutable() + ");");
    }

    protected void addConverterLines(NonreflectiveMethodDefinition method, String converterName, Converter converter) {
        if (converter instanceof ObjectTypeConverter) {
            method.addLine("ObjectTypeConverter " + converterName + " = new ObjectTypeConverter();");
            addObjectTypeConverterLines(method, converterName, (ObjectTypeConverter)converter);
        } else if (converter instanceof TypeConversionConverter) {
            method.addLine("TypeConversionConverter " + converterName + " = new TypeConversionConverter();");
            addTypeConversionConverterLines(method, converterName, (TypeConversionConverter)converter);
        } else if (converter instanceof SerializedObjectConverter) {
            method.addLine("SerializedObjectConverter " + converterName + " = new SerializedObjectConverter();");
        } else {
            method.addLine(converter.getClass().getName() + " " + converterName + " = new " + converter.getClass().getName() + "();");
        }
    }

    protected void addTypeConversionConverterLines(NonreflectiveMethodDefinition method, String converterName, TypeConversionConverter converter) {
        if (converter.getObjectClassName() != null) {
            // Bug 5170735 - if a conversion object class is an array type, we need to use different notation
            // retrieve the component type from the converter's ocj
            String arrayComponentType = Helper.getComponentTypeNameFromArrayString(converter.getObjectClassName());
            if (arrayComponentType != null) {
                method.addLine(converterName + ".setObjectClass(" + arrayComponentType + "[].class);");
            } else {
                method.addLine(converterName + ".setObjectClass(" + converter.getObjectClassName() + ".class);");
            }
        }
        if (converter.getDataClassName() != null) {
            // Bug 5170735 - if a conversion data class is an array type, we need to use different notation
            String arrayComponentType = Helper.getComponentTypeNameFromArrayString(converter.getDataClassName());
            if (arrayComponentType != null) {
                method.addLine(converterName + ".setDataClass(" + arrayComponentType + "[].class);");
            } else {
                method.addLine(converterName + ".setDataClass(" + converter.getDataClassName() + ".class);");
            }
        }
    }

    protected void addVariableOneToOneMappingLines(NonreflectiveMethodDefinition method, String mappingName, VariableOneToOneMapping mapping) {
        for (Iterator foreignKeysEnum = mapping.getSourceToTargetQueryKeyNames().keySet().iterator();
                 foreignKeysEnum.hasNext();) {
            DatabaseField sourceField = (DatabaseField)foreignKeysEnum.next();
            String targetQueryKey = (String)mapping.getSourceToTargetQueryKeyNames().get(sourceField);
            if (mapping.getForeignKeyFields().contains(sourceField)) {
                method.addLine(mappingName + ".addForeignQueryKeyName(\"" + sourceField.getQualifiedName() + "\", \"" + targetQueryKey + "\");");
            } else {
                method.addLine(mappingName + ".addTargetForeignQueryKeyName(\"" + targetQueryKey + "\", \"" + sourceField.getQualifiedName() + "\");");
            }
        }

        if (mapping.getTypeField() != null) {
            method.addLine(mappingName + ".setTypeFieldName(\"" + mapping.getTypeFieldName() + "\");");

            for (Iterator typeIndicatorsEnum = mapping.getTypeIndicatorNameTranslation().keySet().iterator();
                     typeIndicatorsEnum.hasNext();) {
                String className = (String)typeIndicatorsEnum.next();
                Object value = mapping.getTypeIndicatorNameTranslation().get(className);
                method.addLine(mappingName + ".addClassIndicator(" + className + ".class, " + printString(value) + ");");
            }
        }
    }

    protected NonreflectiveMethodDefinition buildConstructor() {
        NonreflectiveMethodDefinition methodDefinition = new NonreflectiveMethodDefinition();

        methodDefinition.setName(getClassName());
        methodDefinition.setIsConstructor(true);

        methodDefinition.addLine("setName(\"" + getProject().getName() + "\");");

        methodDefinition.addLine("applyLogin();");

        if (!getProject().getDefaultReadOnlyClasses().isEmpty()) {
            methodDefinition.addLine("setDefaultReadOnlyClasses(buildDefaultReadOnlyClasses());");
        }

        methodDefinition.addLine("");

        // Sort by name.
        List<ClassDescriptor> descriptors = buildSortedListOfDescriptors(getProject().getOrderedDescriptors());

        for (ClassDescriptor descriptor : descriptors) {
            // Singleton interface descriptors should not exist.
            if (!(descriptor.isDescriptorForInterface() && (descriptor.getInterfacePolicy().getImplementorDescriptor() != null))) {
                methodDefinition.addLine("addDescriptor(build" + getDescriptorMethodNames().get(descriptor) + "ClassDescriptor());");
            }
        }

        return methodDefinition;
    }

    protected NonreflectiveMethodDefinition buildDescriptorMethod(ClassDescriptor descriptor) {
        if (descriptor.isFullyInitialized()) {
            throw ValidationException.descriptorMustBeNotInitialized(descriptor);
        }

        NonreflectiveMethodDefinition method = new NonreflectiveMethodDefinition();

        method.setName("build" + getDescriptorMethodNames().get(descriptor) + "ClassDescriptor");
        method.setReturnType("ClassDescriptor");

        // ClassDescriptor
        String descriptorClass = "RelationalDescriptor";
        if ((descriptor.getClass() != ClassDescriptor.class) && (descriptor.getClass() != RelationalDescriptor.class)) {
            descriptorClass = descriptor.getClass().getName();
        }
        method.addLine(descriptorClass + " descriptor = new " + descriptorClass + "();");

        // ClassDescriptor type
        if (descriptor.isDescriptorForInterface()) {
            method.addLine("descriptor.descriptorIsForInterface();");
        } else if (descriptor.isAggregateDescriptor()) {
            method.addLine("descriptor.descriptorIsAggregate();");
        } else if (descriptor.isAggregateCollectionDescriptor()) {
            method.addLine("descriptor.descriptorIsAggregateCollection();");
        }

        // Java class
        method.addLine("descriptor.setJavaClass(" + descriptor.getJavaClassName() + ".class);");

        if ((!descriptor.isAggregateDescriptor()) && (!descriptor.isDescriptorForInterface())) {
            // Tables
            for (Enumeration tablesEnum = descriptor.getTables().elements();
                     tablesEnum.hasMoreElements();) {
                String tableName = ((DatabaseTable)tablesEnum.nextElement()).getQualifiedName();
                method.addLine("descriptor.addTableName(\"" + tableName + "\");");
            }

            // Primary key
            if (!descriptor.isChildDescriptor()) {
                for (Enumeration keysEnum = descriptor.getPrimaryKeyFieldNames().elements();
                         keysEnum.hasMoreElements();) {
                    method.addLine("descriptor.addPrimaryKeyFieldName(\"" + keysEnum.nextElement() + "\");");
                }
            }
            for (Iterator multipleTablePrimaryKeysEnum = descriptor.getAdditionalTablePrimaryKeyFields().values().iterator();
                     multipleTablePrimaryKeysEnum.hasNext();) {
                Map keyMapping = (Map)multipleTablePrimaryKeysEnum.next();
                Iterator keyMappingSourceFieldsEnum = keyMapping.keySet().iterator();
                Iterator keyMappingTargetFieldsEnum = keyMapping.values().iterator();
                while (keyMappingSourceFieldsEnum.hasNext()) {
                    DatabaseField sourceField = (DatabaseField)keyMappingSourceFieldsEnum.next();
                    DatabaseField targetField = (DatabaseField)keyMappingTargetFieldsEnum.next();
                    if (descriptor.getMultipleTableForeignKeys().containsKey(sourceField.getTable())) {
                        method.addLine("descriptor.addForeignKeyFieldNameForMultipleTable(\"" + targetField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
                    }
                }
            }
        }

        // Inheritance
        if (descriptor.hasInheritance()) {
            method.addLine("");
            addInheritanceLines(method, descriptor.getInheritancePolicy());
        }

        // Interface
        if (descriptor.hasInterfacePolicy()) {
            method.addLine("");
            addInterfaceLines(method, descriptor.getInterfacePolicy());
        }

        // ClassDescriptor properties
        method.addLine("");
        addDescriptorPropertyLines(method, descriptor);

        // Cache Invalidation policy
        method.addLine("");
        addCacheInvalidationPolicyLines(method, descriptor);

        // HistoryPolicy
        addHistoryPolicyLines(method, descriptor);

        // Query manager
        method.addLine("");
        addQueryManagerPropertyLines(method, descriptor);

        //fetch group
        method.addLine("");
        addFetchGroupManagerLine(method, descriptor);

        // Event manager
        method.addLine("");
        addEventManagerPropertyLines(method, descriptor);

        // Query keys
        if (!descriptor.getQueryKeys().isEmpty()) {
            method.addLine("");
            method.addLine("// Query keys.");
            for (Iterator queryKeysEnum = descriptor.getQueryKeys().values().iterator(); queryKeysEnum.hasNext();) {
                addQueryKeyLines(method, (QueryKey)queryKeysEnum.next());
            }
        }

        // Mappings
        if (!descriptor.getMappings().isEmpty()) {
            method.addLine("");
            method.addLine("// Mappings.");
            for (Enumeration mappingsEnum = sortMappings(descriptor.getMappings()).elements();
                     mappingsEnum.hasMoreElements();) {
                addMappingLines(method, (DatabaseMapping)mappingsEnum.nextElement());
                method.addLine("");
            }
        } else {
            method.addLine("");
        }

        // Amendment
        if ((descriptor.getAmendmentClassName() != null) && (descriptor.getAmendmentMethodName() != null)) {
            method.addLine("descriptor.applyAmendmentMethod();");
        }

        method.addLine("return descriptor;");

        return method;
    }

    /**
     *  Take an unsorted list of descriptors and sort it so that the order is maintained.
     */
    private List<ClassDescriptor> buildSortedListOfDescriptors(List<ClassDescriptor> descriptors) {
        List returnDescriptors = Helper.addAllUniqueToList(new ArrayList(descriptors.size()), descriptors);
        Object[] descriptorsArray = new Object[returnDescriptors.size()];
        for (int index = 0; index < returnDescriptors.size(); index++) {
            descriptorsArray[index] = returnDescriptors.get(index);
        }
        Arrays.sort(descriptorsArray, new DescriptorCompare());
        returnDescriptors = new ArrayList(descriptorsArray.length);
        for (Object descriptor : descriptorsArray) {
            returnDescriptors.add(descriptor);
        }
        return returnDescriptors;
    }

    protected NonreflectiveMethodDefinition buildLoginMethod(Login datasourceLogin) {
        NonreflectiveMethodDefinition method = new NonreflectiveMethodDefinition();

        method.setName("applyLogin");

        String loginClassName = datasourceLogin.getClass().getName();
        if (datasourceLogin.getClass().equals(DatabaseLogin.class)) {
            loginClassName = Helper.getShortClassName(datasourceLogin);
        }
        method.addLine(loginClassName + " login = new " + loginClassName + "();");

        if (datasourceLogin instanceof DatabaseLogin) {
            DatabaseLogin login = (DatabaseLogin)datasourceLogin;
            method.addLine("login.usePlatform(new " + login.getPlatformClassName() + "());");
            // CR#3349 Change from setDriverClass() to setDriverClassName()
            method.addLine("login.setDriverClassName(\"" + login.getDriverClassName() + "\");");
            method.addLine("login.setConnectionString(\"" + login.getConnectionString() + "\");");

            if (login.getUserName() != null) {
                method.addLine("login.setUserName(\"" + login.getUserName() + "\");");
            }

            if (login.getPassword() != null) {
                method.addLine("login.setEncryptedPassword(\"" + login.getPassword() + "\");");
            }

            method.addLine("");
            method.addLine("// Configuration Properties.");

            if (!login.shouldBindAllParameters()) {
                method.addLine("login.setShouldBindAllParameters(" + login.shouldBindAllParameters() + ");");
            }
            if (login.shouldCacheAllStatements()) {
                method.addLine("login.setShouldCacheAllStatements(" + login.shouldCacheAllStatements() + ");");
            }
            if (!login.shouldUseByteArrayBinding()) {
                method.addLine("login.setUsesByteArrayBinding(" + login.shouldUseByteArrayBinding() + ");");
            }
            if (login.shouldUseStringBinding()) {
                method.addLine("login.setUsesStringBinding(" + login.shouldUseStringBinding() + ");");
            }
            if (login.shouldUseStreamsForBinding()) {
                method.addLine("\tlogin.setUsesStreamsForBinding(" + login.shouldUseStreamsForBinding() + ");");
            }
            if (login.shouldForceFieldNamesToUpperCase()) {
                method.addLine("login.setShouldForceFieldNamesToUpperCase(" + login.shouldForceFieldNamesToUpperCase() + ");");
            }
            if (!login.shouldOptimizeDataConversion()) {
                method.addLine("login.setShouldOptimizeDataConversion(" + login.shouldOptimizeDataConversion() + ");");
            }
            if (!login.shouldTrimStrings()) {
                method.addLine("login.setShouldTrimStrings(" + login.shouldTrimStrings() + ");");
            }
            if (login.shouldUseBatchWriting()) {
                method.addLine("login.setUsesBatchWriting(" + login.shouldUseBatchWriting() + ");");
            }
            if (!login.shouldUseJDBCBatchWriting()) {
                method.addLine("\tlogin.setUsesJDBCBatchWriting(" + login.shouldUseJDBCBatchWriting() + ");");
            }
            if (login.shouldUseExternalConnectionPooling()) {
                method.addLine("login.setUsesExternalConnectionPooling(" + login.shouldUseExternalConnectionPooling() + ");");
            }
            if (login.shouldUseExternalTransactionController()) {
                method.addLine("login.setUsesExternalTransactionController(" + login.shouldUseExternalTransactionController() + ");");
            }
        } else if (datasourceLogin instanceof EISLogin) {
            EISLogin eisLogin = (EISLogin)datasourceLogin;
            method.addLine("login.setConnectionSpec(new " + eisLogin.getConnectionSpec().getClass().getName() + "());");
            if (eisLogin.getConnectionFactoryURL() != null) {
                method.addLine("login.setConnectionFactoryURL(\"" + eisLogin.getConnectionFactoryURL() + "\");");
            }
        }

        boolean addedSequencingHeader = false;
        Sequence defaultSequence = ((DatasourceLogin)datasourceLogin).getDefaultSequenceToWrite();
        if (defaultSequence != null) {
            method.addLine("");
            method.addLine("// Sequencing.");
            addedSequencingHeader = true;
            method.addLine(setDefaultOrAddSequenceString(defaultSequence, true));
        }
        Map sequences = ((DatasourceLogin)datasourceLogin).getSequencesToWrite();
        if ((sequences != null) && !sequences.isEmpty()) {
            if (!addedSequencingHeader) {
                method.addLine("");
                method.addLine("// Sequencing.");
                addedSequencingHeader = true;
            }
            Iterator it = sequences.values().iterator();
            while (it.hasNext()) {
                Sequence sequence = (Sequence)it.next();
                method.addLine(setDefaultOrAddSequenceString(sequence, false));
            }
        }

        method.addLine("");
        method.addLine("setDatasourceLogin(login);");

        return method;
    }

    protected String setDefaultOrAddSequenceString(Sequence sequence, boolean isSetDefault) {
        String prefix;
        if (isSetDefault) {
            prefix = "login.setDefaultSequence(new ";
        } else {
            prefix = "login.addSequence(new ";
        }
        String str;
        if (sequence instanceof TableSequence) {
            TableSequence ts = (TableSequence)sequence;
            str = "TableSequence(\"" + ts.getName() + "\", " + ts.getPreallocationSize() + ", \"" + ts.getTableName() + "\", \"" + ts.getNameFieldName() + "\", \"" + ts.getCounterFieldName() + "\"));";
        } else if (sequence instanceof UnaryTableSequence) {
            UnaryTableSequence uts = (UnaryTableSequence)sequence;
            str = "UnaryTableSequence(\"" + uts.getName() + "\", " + uts.getPreallocationSize() + ", \"" + uts.getCounterFieldName() + "\"));";
        } else {
            String typeName = Helper.getShortClassName(sequence);
            str = typeName + "(\"" + sequence.getName() + "\", " + sequence.getPreallocationSize() + "));";
        }
        return prefix + str;
    }

    /**
     * This figures out the best name for each descriptor,
     * first using the local class name then the qualified one for duplicates.
     */
    protected void computeDescriptorMethodNames() {
        Hashtable shortNames = new Hashtable();
        Iterator descriptors = project.getOrderedDescriptors().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = (ClassDescriptor)descriptors.next();

            // Singleton interface descriptors should not exist.
            if (!(descriptor.isDescriptorForInterface() && (descriptor.getInterfacePolicy().getImplementorDescriptor() != null))) {
                String shortName = Helper.getShortClassName(descriptor.getJavaClassName());
                if (shortNames.containsKey(shortName)) {
                    // Use the full package name.
                    ClassDescriptor firstDescriptor = (ClassDescriptor)shortNames.get(shortName);
                    getDescriptorMethodNames().put(firstDescriptor, removeDots(firstDescriptor.getJavaClassName()));
                    getDescriptorMethodNames().put(descriptor, removeDots(descriptor.getJavaClassName()));
                } else {
                    shortNames.put(shortName, descriptor);
                    getDescriptorMethodNames().put(descriptor, shortName);
                }
            }
        }
    }

    /**
     * PUBLIC:
     * Generate the project class, output the java source code to the stream or file.
     * useUnicode determines if unicode escaped characters for non_ASCII charaters will be used.
     */
    public void generate(boolean useUnicode) throws ValidationException {
        if (getOutputWriter() == null) {
            try {
                setOutputWriter(new OutputStreamWriter(new FileOutputStream(getOutputPath() + getOutputFileName())));
            } catch (IOException exception) {
                throw ValidationException.fileError(exception);
            }
        }

        CodeGenerator generator = new CodeGenerator(useUnicode);
        generator.setOutput(getOutputWriter());
        generateProjectClass().write(generator);
        try {
            getOutputWriter().flush();
            getOutputWriter().close();
        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }
    }

    /**
     * PUBLIC:
     * Generate the project class, output the java source code to the stream or file.
     * Unicode escaped characters for non_ASCII charaters will be used.
     */
    public void generate() throws ValidationException {
        generate(true);
    }

    /**
     * Return a class definition object representing the code to be generated for the project and its descriptors.
     * This class will have one method per descriptor and its toString can be used to convert it to code.
     */
    protected ClassDefinition generateProjectClass() {
        computeDescriptorMethodNames();

        ClassDefinition classDefinition = new ClassDefinition();

        classDefinition.setName(getClassName());
        classDefinition.setSuperClass("org.eclipse.persistence.sessions.Project");
        classDefinition.setPackageName(getPackageName());

        classDefinition.addImport("org.eclipse.persistence.sessions.*");
        classDefinition.addImport("org.eclipse.persistence.descriptors.*");
        classDefinition.addImport("org.eclipse.persistence.descriptors.invalidation.*");
        classDefinition.addImport("org.eclipse.persistence.mappings.*");
        classDefinition.addImport("org.eclipse.persistence.mappings.converters.*");
        classDefinition.addImport("org.eclipse.persistence.queries.*");
        classDefinition.addImport("org.eclipse.persistence.expressions.ExpressionBuilder");
        classDefinition.addImport("org.eclipse.persistence.history.HistoryPolicy");
        classDefinition.addImport("org.eclipse.persistence.sequencing.*");

        classDefinition.setComment("This class was generated by the TopLink project class generator." + Helper.cr() + "It stores the meta-data (descriptors) that define the TopLink mappings." + Helper.cr() + "## " + DatabaseLogin.getVersion() + " ##" + Helper.cr() + "@see org.eclipse.persistence.sessions.factories.ProjectClassGenerator");

        classDefinition.addMethod(buildConstructor());

        if (getProject().getDatasourceLogin() != null) {
            classDefinition.addMethod(buildLoginMethod(getProject().getDatasourceLogin()));
        }

        for (ClassDescriptor descriptor : buildSortedListOfDescriptors(getProject().getOrderedDescriptors())) {
            // Singleton interface descriptors should not exist.
            if (!(descriptor.isDescriptorForInterface() && (descriptor.getInterfacePolicy().getImplementorDescriptor() != null))) {
                classDefinition.addMethod(buildDescriptorMethod(descriptor));
            }
        }

        return classDefinition;
    }

    /**
     * PUBLIC:
     * Return the name of class to be generated.
     * This is the unqualified name.
     */
    public String getClassName() {
        return className;
    }

    protected Hashtable getDescriptorMethodNames() {
        return descriptorMethodNames;
    }

    /**
     * PUBLIC:
     * Return the file name that the generate .java file will be output to.
     */
    public String getOutputFileName() {
        return outputFileName;
    }

    /**
     * PUBLIC:
     * Return the path that the generate .java file will be output to.
     */
    public String getOutputPath() {
        return outputPath;
    }

    /**
     * PUBLIC:
     * Return the writer the output to.
     */
    public Writer getOutputWriter() {
        return outputWriter;
    }

    /**
     * PUBLIC:
     * Return the package name of class to be generated.
     */
    public String getPackageName() {
        return packageName;
    }

    /**
     * PUBLIC:
     * Return the project to generate from.
     */
    public Project getProject() {
        return project;
    }

    /**
     * Return the printed version of the primitive value object.
     * This must determine the class and use the correct constructor arguments.
     */
    protected String printString(Object value) {
        if ((value == null) || (value == Helper.NULL_VALUE)) {
            return "null";
        }

        if (value instanceof String) {
            return "\"" + value + "\"";
        }

        if (value instanceof Character) {
            return "Character.valueOf('" + value + "')";
        }

        if (value instanceof Boolean) {
            return "Boolean.valueOf(\"" + value + "\")";
        }
        if (value instanceof Integer) {
            return "Integer.valueOf(\"" + value + "\")";
        }
        if (value instanceof Double) {
            return "Double.valueOf(\"" + value + "\")";
        }
        if (value instanceof Float) {
            return "Float.valueOf(\"" + value + "\")";
        }
        if (value instanceof Long) {
            return "Long.valueOf(\"" + value + "\")";
        }
        if (value instanceof Byte) {
            return "Byte.valueOf(\"" + value + "\")";
        }

        if (value instanceof Short) {
            return "Short.valueOf(\"" + value + "\")";
        }

        //Bug2662265
        if (value instanceof java.util.Date) {
            java.util.Date date = (java.util.Date)value;
            return "new " + value.getClass().getName() + "(" + date.getTime() + "L)";
        }

        // This handles most cases.
        //CR#2648.  Get fully qualified name for object.
        // Bug 298443 - account for Byte, Double, Short, Long, etc. constructors.
        return "new " + value.getClass().getName() + "(\"" + String.valueOf(value) + "\")";

    }

    protected String removeDots(String packageName) {
        StringWriter writer = new StringWriter();
        int startIndex = 0;
        int dotIndex = packageName.indexOf('.', startIndex);
        while (dotIndex >= 0) {
            writer.write(packageName.substring(startIndex, dotIndex));
            startIndex = dotIndex + 1;
            dotIndex = packageName.indexOf('.', startIndex);
        }
        writer.write(packageName.substring(startIndex, packageName.length()));

        return writer.toString();
    }

    /**
     * PUBLIC:
     * Set the name of class to be generated.
     * This can be qualified or unqualified name and will set the file name to match.
     */
    public void setClassName(String newClassName) {
        int lastDotIndex = newClassName.lastIndexOf('.');
        if (lastDotIndex >= 0) {
            className = newClassName.substring(lastDotIndex + 1, newClassName.length());
            setPackageName(newClassName.substring(0, lastDotIndex));
        } else {
            className = newClassName;
        }
        setOutputFileName(newClassName);
    }

    protected void setDescriptorMethodNames(Hashtable descriptorMethodNames) {
        this.descriptorMethodNames = descriptorMethodNames;
    }

    /**
     * PUBLIC:
     * Set the file name that the generate .java file will be output to.
     * If the file does not include .java it will be appended.
     */
    public void setOutputFileName(String newOutputFileName) {
        if (newOutputFileName.indexOf(".java") < 0) {
            outputFileName = newOutputFileName + ".java";
        } else {
            outputFileName = newOutputFileName;
        }
    }

    /**
     * PUBLIC:
     * Set the path that the generate .java file will be output to.
     */
    public void setOutputPath(String newOutputPath) {
        outputPath = newOutputPath;
    }

    /**
     * PUBLIC:
     * Set the writer the output to.
     */
    public void setOutputWriter(Writer outputWriter) {
        this.outputWriter = outputWriter;
    }

    /**
     * PUBLIC:
     * Set the package name of class to be generated.
     */
    public void setPackageName(String newPackageName) {
        packageName = newPackageName;
    }

    /**
     * PUBLIC:
     * Set the project to generate from.
     * All of the projects descriptors will be stored into the file.
     */
    public void setProject(Project newProject) {
        project = newProject;
    }

    /**
     * Short the mappings by type.
     */
    protected Vector sortMappings(Vector mappings) {
        Vector sortedMappings = new Vector(mappings.size());

        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.getClass().equals(DirectToFieldMapping.class)) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isTransformationMapping()) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isAggregateMapping()) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isDirectCollectionMapping()) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isObjectReferenceMapping()) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isOneToManyMapping()) {
                sortedMappings.addElement(mapping);
            }
        }
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (mapping.isManyToManyMapping()) {
                sortedMappings.addElement(mapping);
            }
        }

        // Others
        for (Enumeration mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
            if (!sortedMappings.contains(mapping)) {
                sortedMappings.addElement(mapping);
            }
        }

        return sortedMappings;
    }

    /**
     * PUBLIC:
     * Generate the source code to a project class to the project's descriptor into the writer.
     */
    public static void write(Project project, String projectClassName, Writer writer) {
        ProjectClassGenerator generator = new ProjectClassGenerator(project, projectClassName, writer);
        generator.generate();
    }

    /**
     * PUBLIC:
     * Generate the source code to a project class to the project's descriptor into the file.
     */
    public static void write(Project project, String projectClassName, String fileName) {
        ProjectClassGenerator generator = new ProjectClassGenerator(project, projectClassName, fileName);
        generator.generate();
    }
}
