/*
 * 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.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<ClassDescriptor, String> 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<DatabaseField> targetKeysEnum = mapping.getTargetForeignKeyFields().elements();
        Enumeration<DatabaseField> sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = sourceKeysEnum.nextElement();
            DatabaseField targetField = 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<DatabaseField> sourceKeysEnum = mapping.getSourceKeyFields().elements();
        Enumeration<DatabaseField> referenceKeysEnum = mapping.getReferenceKeyFields().elements();
        while (referenceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = sourceKeysEnum.nextElement();
            DatabaseField referenceField = 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<String, FetchGroup> 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<FetchGroup> namedFetchGroupIter = namedFetchGroups.values().iterator();
             namedFetchGroupIter.hasNext();) {
            FetchGroup namedFetchGroup = 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<Expression> 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;
            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<String> indicatorsEnum = policy.getClassNameIndicatorMapping().keySet().iterator();
                             indicatorsEnum.hasNext();) {
                        String className = 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<DatabaseField> sourceRelationKeysEnum = mapping.getSourceRelationKeyFields().elements();
        Enumeration<DatabaseField> sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceRelationKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = sourceKeysEnum.nextElement();
            DatabaseField relationField = sourceRelationKeysEnum.nextElement();
            method.addLine(mappingName + ".addSourceRelationKeyFieldName(\"" + relationField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }

        Enumeration<DatabaseField> targetRelationKeysEnum = mapping.getTargetRelationKeyFields().elements();
        Enumeration<DatabaseField> targetKeysEnum = mapping.getTargetKeyFields().elements();
        while (targetRelationKeysEnum.hasMoreElements()) {
            DatabaseField targetField = targetKeysEnum.nextElement();
            DatabaseField relationField = 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<Object> 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<Object> 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<DatabaseField> targetKeysEnum = mapping.getTargetForeignKeyFields().elements();
        Enumeration<DatabaseField> sourceKeysEnum = mapping.getSourceKeyFields().elements();
        while (sourceKeysEnum.hasMoreElements()) {
            DatabaseField sourceField = sourceKeysEnum.nextElement();
            DatabaseField targetField = targetKeysEnum.nextElement();
            method.addLine(mappingName + ".addTargetForeignKeyFieldName(\"" + targetField.getQualifiedName() + "\", \"" + sourceField.getQualifiedName() + "\");");
        }
    }

    protected void addOneToOneMappingLines(NonreflectiveMethodDefinition method, String mappingName, OneToOneMapping mapping) {
        for (Iterator<DatabaseField> foreignKeysEnum = mapping.getSourceToTargetKeyFields().keySet().iterator();
             foreignKeysEnum.hasNext();) {
            DatabaseField sourceField = 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<DatabaseQuery> namedQueries = descriptor.getQueryManager().getAllQueries().elements();
            int iteration = 0;
            while (namedQueries.hasMoreElements()) {
                addNamedQueryLines(method, 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 = 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" + 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(" + query.getQueryTimeout() + ");");
        }
        if (query.getQueryTimeoutUnit() != DescriptorQueryManager.DefaultTimeoutUnit) {
            method.addLine(queryIdentifier + ".setQueryTimeoutUnit(" + query.getQueryTimeoutUnit() + ");");
        }
        if (!query.shouldUseWrapperPolicy()) {
            method.addLine(queryIdentifier + ".setShouldUseWrapperPolicy(" + query.shouldUseWrapperPolicy() + ");");
        }
        if (!query.shouldIgnoreBindAllParameters()) {
            method.addLine(queryIdentifier + ".setShouldBindAllParameters(" + query.shouldBindAllParameters() + ");");
        }
        if (!query.shouldIgnoreCacheStatement()) {
            method.addLine(queryIdentifier + ".setShouldCacheStatement(" + query.shouldCacheStatement() + ");");
        }
        if (query.getSessionName() != null) {
            method.addLine(queryIdentifier + ".setSessionName(\"" + query.getSessionName() + "\");");
        }
        if (!query.shouldMaintainCache()) {
            method.addLine(queryIdentifier + ".setShouldMaintainCache(" + query.shouldMaintainCache() + ");");
        }
        if (!query.shouldPrepare()) {
            method.addLine(queryIdentifier + ".setShouldPrepare(" + 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(" + readQuery.getMaxRows() + ");");
            }
            if (readQuery.getFirstResult() != 0) {
                method.addLine(queryIdentifier + ".setFirstResult(" + readQuery.getFirstResult() + ");");
            }
        }

        //ExpressionBuilder string
        String builderString = null;

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

            // Refresh.
            if (readQuery.shouldRefreshIdentityMapResult()) {
                method.addLine(queryIdentifier + ".setShouldRefreshIdentityMapResult(" + 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(" + 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<Expression> joinedEnum = readQuery.getJoinedAttributeManager().getJoinedAttributeExpressions().iterator(); joinedEnum.hasNext();) {
                Expression joinedExp = 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 + ");");
                    } else { //i.e. addFunctionItem(itemName, attributeExpression, functionName) only
                        method.addLine(queryIdentifier + functionString + itemName + "\", " + writer + ", \"" + 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<String> arguments = query.getArguments().iterator(); arguments.hasNext();) {
            String argument = 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" + 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 + ");");
    }

    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<FieldTransformation> fieldTransformations = mapping.getFieldTransformations().iterator();
        while (fieldTransformations.hasNext()) {
            FieldTransformation trans = 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<DatabaseField> foreignKeysEnum = mapping.getSourceToTargetQueryKeyNames().keySet().iterator();
                 foreignKeysEnum.hasNext();) {
            DatabaseField sourceField = 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<String> typeIndicatorsEnum = mapping.getTypeIndicatorNameTranslation().keySet().iterator();
                     typeIndicatorsEnum.hasNext();) {
                String className = 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<DatabaseTable> tablesEnum = descriptor.getTables().elements();
                 tablesEnum.hasMoreElements();) {
                String tableName = tablesEnum.nextElement().getQualifiedName();
                method.addLine("descriptor.addTableName(\"" + tableName + "\");");
            }

            // Primary key
            if (!descriptor.isChildDescriptor()) {
                for (Enumeration<String> keysEnum = descriptor.getPrimaryKeyFieldNames().elements();
                     keysEnum.hasMoreElements();) {
                    method.addLine("descriptor.addPrimaryKeyFieldName(\"" + keysEnum.nextElement() + "\");");
                }
            }
            for (Iterator<Map<DatabaseField, DatabaseField>> multipleTablePrimaryKeysEnum = descriptor.getAdditionalTablePrimaryKeyFields().values().iterator();
                 multipleTablePrimaryKeysEnum.hasNext();) {
                Map<DatabaseField, DatabaseField> keyMapping = multipleTablePrimaryKeysEnum.next();
                Iterator<DatabaseField> keyMappingSourceFieldsEnum = keyMapping.keySet().iterator();
                Iterator<DatabaseField> keyMappingTargetFieldsEnum = keyMapping.values().iterator();
                while (keyMappingSourceFieldsEnum.hasNext()) {
                    DatabaseField sourceField = keyMappingSourceFieldsEnum.next();
                    DatabaseField targetField = 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<QueryKey> queryKeysEnum = descriptor.getQueryKeys().values().iterator(); queryKeysEnum.hasNext();) {
                addQueryKeyLines(method, queryKeysEnum.next());
            }
        }

        // Mappings
        if (!descriptor.getMappings().isEmpty()) {
            method.addLine("");
            method.addLine("// Mappings.");
            for (Enumeration<DatabaseMapping> mappingsEnum = sortMappings(descriptor.getMappings()).elements();
                     mappingsEnum.hasMoreElements();) {
                addMappingLines(method, 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<ClassDescriptor> returnDescriptors = Helper.addAllUniqueToList(new ArrayList<>(descriptors.size()), descriptors);
        returnDescriptors.sort(new DescriptorCompare());
        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<String, Sequence> sequences = ((DatasourceLogin)datasourceLogin).getSequencesToWrite();
        if ((sequences != null) && !sequences.isEmpty()) {
            if (!addedSequencingHeader) {
                method.addLine("");
                method.addLine("// Sequencing.");
            }
            Iterator<Sequence> it = sequences.values().iterator();
            while (it.hasNext()) {
                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<String, ClassDescriptor> shortNames = new Hashtable<>();
        Iterator<ClassDescriptor> descriptors = project.getOrderedDescriptors().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = 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 = 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<ClassDescriptor, String> 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() + "(\"" + 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));

        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);
            setPackageName(newClassName.substring(0, lastDotIndex));
        } else {
            className = newClassName;
        }
        setOutputFileName(newClassName);
    }

    protected void setDescriptorMethodNames(Hashtable<ClassDescriptor, String> 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.contains(".java")) {
            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<DatabaseMapping> sortMappings(Vector<DatabaseMapping> mappings) {
        Vector<DatabaseMapping> sortedMappings = new Vector<>(mappings.size());

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

        // Others
        for (Enumeration<DatabaseMapping> mappingsEnum = mappings.elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = 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();
    }
}
