/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. 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
//     08/23/2010-2.2 Michael O'Brien
//        - 323043: application.xml module ordering may cause weaving not to occur causing an NPE.
//                       warn if expected "_persistence_//_vh" method not found
//                       instead of throwing NPE during deploy validation.
//     10/15/2010-2.2 Guy Pelletier
//       - 322008: Improve usability of additional criteria applied to queries at the session/EM
package org.eclipse.persistence.exceptions;

import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.eclipse.persistence.internal.sessions.AbstractRecord;

import java.lang.reflect.*;
import java.util.Collection;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator;

/**
 *    <B>Purpose</B>: This exception is used for any problem that is detected with a descriptor or mapping.
 */
public class DescriptorException extends ValidationException {
    protected transient ClassDescriptor descriptor;
    protected transient DatabaseMapping mapping;
    public final static int ATTRIBUTE_AND_MAPPING_WITH_INDIRECTION_MISMATCH = 1;
    public final static int ATTRIBUTE_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH = 2;
    public final static int ATTRIBUTE_NAME_NOT_SPECIFIED = 6;
    public final static int ATTRIBUTE_TYPE_NOT_VALID = 7;
    public final static int CLASS_INDICATOR_FIELD_NOT_FOUND = 8;
    public final static int DIRECT_FIELD_NAME_NOT_SET = 9;
    public final static int FIELD_NAME_NOT_SET_IN_MAPPING = 10;
    public final static int FOREIGN_KEYS_DEFINED_INCORRECTLY = 11;
    public final static int IDENTITY_MAP_NOT_SPECIFIED = 12;
    public final static int ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 13;
    public final static int ILLEGAL_ACCESS_WHILE_CLONING = 14;
    public final static int ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION = 15;
    public final static int ILLEGAL_ACCESS_WHILE_EVENT_EXECUTION = 16;
    public final static int ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR = 17;
    public final static int ILLEGAL_ACCESS_WHILE_INSTANTIATING_METHOD_BASED_PROXY = 18;
    public final static int ILLEGAL_ACCESS_WHILE_INVOKING_ATTRIBUTE_METHOD = 19;
    public final static int ILLEGAL_ACCESS_WHILE_INVOKING_FIELD_TO_METHOD = 20;
    public final static int ILLEGAL_ACCESS_WHILE_INVOKING_ROW_EXTRACTION_METHOD = 21;
    public final static int ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION = 22;
    public final static int ILLEGAL_ACCESS_WHILE_OBSOLETE_EVENT_EXECUTION = 23;
    public final static int ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 24;
    public final static int ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR = 25;
    public final static int ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 26;
    public final static int ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR = 27;
    public final static int ILLEGAL_ARGUMENT_WHILE_INSTANTIATING_METHOD_BASED_PROXY = 28;
    public final static int ILLEGAL_ARGUMENT_WHILE_INVOKING_ATTRIBUTE_METHOD = 29;
    public final static int ILLEGAL_ARGUMENT_WHILE_INVOKING_FIELD_TO_METHOD = 30;
    public final static int ILLEGAL_ARGUMENT_WHILE_OBSOLETE_EVENT_EXECUTION = 31;
    public final static int ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 32;
    public final static int ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR = 33;
    public final static int INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION = 34;
    public final static int INVALID_DATA_MODIFICATION_EVENT = 35;
    public final static int INVALID_DATA_MODIFICATION_EVENT_CODE = 36;
    public final static int INVALID_DESCRIPTOR_EVENT_CODE = 37;
    public final static int INVALID_IDENTITY_MAP = 38;
    public final static int JAVA_CLASS_NOT_SPECIFIED = 39;
    public final static int DESCRIPTOR_FOR_INTERFACE_IS_MISSING = 40;
    public final static int MAPPING_FOR_SEQUENCE_NUMBER_FIELD = 41;
    public final static int MISSING_CLASS_FOR_INDICATOR_FIELD_VALUE = 43;
    public final static int MISSING_CLASS_INDICATOR_FIELD = 44;
    public final static int MISSING_MAPPING_FOR_FIELD = 45;
    public final static int NO_MAPPING_FOR_PRIMARY_KEY = 46;
    public final static int MULTIPLE_TABLE_PRIMARY_KEY_NOT_SPECIFIED = 47;
    public final static int MULTIPLE_WRITE_MAPPINGS_FOR_FIELD = 48;
    public final static int NO_ATTRIBUTE_TRANSFORMATION_METHOD = 49;
    public final static int NO_FIELD_NAME_FOR_MAPPING = 50;
    public final static int NO_FOREIGN_KEYS_ARE_SPECIFIED = 51;
    public final static int NO_REFERENCE_KEY_IS_SPECIFIED = 52;
    public final static int NO_RELATION_TABLE = 53;
    public final static int NO_SOURCE_RELATION_KEYS_SPECIFIED = 54;
    public final static int NO_SUCH_METHOD_ON_FIND_OBSOLETE_METHOD = 55;
    public final static int NO_SUCH_METHOD_ON_INITIALIZING_ATTRIBUTE_METHOD = 56;
    public final static int NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION = 57;
    public final static int NO_SUCH_METHOD_WHILE_CONVERTING_TO_METHOD = 58;
    public final static int NO_SUCH_FIELD_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR = 59;
    public final static int NO_SUCH_METHOD_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR = 60;
    public final static int NO_SUCH_METHOD_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD = 61;
    public final static int NO_SUCH_METHOD_WHILE_INITIALIZING_COPY_POLICY = 62;
    public final static int NO_SUCH_METHOD_WHILE_INITIALIZING_INSTANTIATION_POLICY = 63;
    public final static int NO_TARGET_FOREIGN_KEYS_SPECIFIED = 64;
    public final static int NO_TARGET_RELATION_KEYS_SPECIFIED = 65;
    public final static int NOT_DESERIALIZABLE = 66;
    public final static int NOT_SERIALIZABLE = 67;
    public final static int NULL_FOR_NON_NULL_AGGREGATE = 68;
    public final static int NULL_POINTER_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 69;
    public final static int NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR = 70;
    public final static int NULL_POINTER_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR = 71;
    public final static int NULL_POINTER_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR = 72;
    public final static int PARENT_DESCRIPTOR_NOT_SPECIFIED = 73;
    public final static int PRIMARY_KEY_FIELDS_NOT_SPECIFIED = 74;
    public final static int REFERENCE_CLASS_NOT_SPECIFIED = 75;
    public final static int REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATE = 77;
    public final static int REFERENCE_KEY_FIELD_NOT_PROPERLY_SPECIFIED = 78;
    public final static int REFERENCE_TABLE_NOT_SPECIFIED = 79;
    public final static int RELATION_KEY_FIELD_NOT_PROPERLY_SPECIFIED = 80;
    public final static int RETURN_TYPE_IN_GET_ATTRIBUTE_ACCESSOR = 81;
    public final static int SECURITY_ON_FIND_METHOD = 82;
    public final static int SECURITY_ON_FIND_OBSOLETE_METHOD = 83;
    public final static int SECURITY_ON_INITIALIZING_ATTRIBUTE_METHOD = 84;
    public final static int SECURITY_WHILE_CONVERTING_TO_METHOD = 85;
    public final static int SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR = 86;
    public final static int SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR = 87;
    public final static int SECURITY_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD = 88;
    public final static int SECURITY_WHILE_INITIALIZING_COPY_POLICY = 89;
    public final static int SECURITY_WHILE_INITIALIZING_INSTANTIATION_POLICY = 90;
    public final static int SEQUENCE_NUMBER_PROPERTY_NOT_SPECIFIED = 91;
    public final static int SIZE_MISMATCH_OF_FOREIGN_KEYS = 92;
    public final static int TABLE_NOT_PRESENT = 93;
    public final static int TABLE_NOT_SPECIFIED = 94;
    public final static int TARGET_FOREIGN_KEYS_SIZE_MISMATCH = 96;
    public final static int TARGET_INVOCATION_WHILE_CLONING = 97;
    public final static int TARGET_INVOCATION_WHILE_EVENT_EXECUTION = 98;
    public final static int TARGET_INVOCATION_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR = 99;
    public final static int TARGET_INVOCATION_WHILE_INSTANTIATING_METHOD_BASED_PROXY = 100;
    public final static int TARGET_INVOCATION_WHILE_INVOKING_ATTRIBUTE_METHOD = 101;
    public final static int TARGET_INVOCATION_WHILE_INVOKING_FIELD_TO_METHOD = 102;
    public final static int TARGET_INVOCATION_WHILE_INVOKING_ROW_EXTRACTION_METHOD = 103;
    public final static int TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION = 104;
    public final static int TARGET_INVOCATION_WHILE_OBSOLETE_EVENT_EXECUTION = 105;
    public final static int TARGET_INVOCATION_WHILE_SETTING_VALUE_THRU_METHOD_ACESSOR = 106;
    public final static int VALUE_NOT_FOUND_IN_CLASS_INDICATOR_MAPPING = 108;
    public final static int WRITE_LOCK_FIELD_IN_CHILD_DESCRIPTOR = 109;
    public final static int DESCRIPTOR_IS_MISSING = 110;
    public final static int MULTIPLE_TABLE_PRIMARY_KEY_MUST_BE_FULLY_QUALIFIED = 111;
    public final static int ONLY_ONE_TABLE_CAN_BE_ADDED_WITH_THIS_METHOD = 112;
    public final static int NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION = 113;
    public final static int NULL_POINTER_WHILE_METHOD_INSTANTIATION = 114;
    public final static int NO_ATTRBUTE_VALUE_CONVERSION_TO_FIELD_VALUE_PROVIDED = 115;
    public final static int NO_FIELD_VALUE_CONVERSION_TO_ATTRIBUTE_VALUE_PROVIDED = 116;
    public final static int LOCK_MAPPING_CANNOT_BE_READONLY = 118;
    public final static int LOCK_MAPPING_MUST_BE_READONLY = 119;
    public final static int CHILD_DOES_NOT_DEFINE_ABSTRACT_QUERY_KEY = 120;
    public final static int SET_EXISTENCE_CHECKING_NOT_UNDERSTOOD = 122;
    public final static int VALUE_HOLDER_INSTANTIATION_MISMATCH = 125;
    public final static int NO_SUB_CLASS_MATCH = 126;
    public final static int RETURN_AND_MAPPING_WITH_INDIRECTION_MISMATCH = 127;
    public final static int RETURN_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH = 128;
    public final static int PARAMETER_AND_MAPPING_WITH_INDIRECTION_MISMATCH = 129;
    public final static int PARAMETER_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH = 130;
    public final static int GET_METHOD_RETURN_TYPE_NOT_VALID = 131;
    public final static int SET_METHOD_PARAMETER_TYPE_NOT_VALID = 133;
    public final static int ILLEGAL_TABLE_NAME_IN_MULTIPLE_TABLE_FOREIGN_KEY = 135;
    public final static int ATTRIBUTE_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH = 138;
    public final static int RETURN_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH = 139;
    public final static int PARAMETER_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH = 140;
    public final static int FIELD_IS_NOT_PRESENT_IN_DATABASE = 141;
    public final static int TABLE_IS_NOT_PRESENT_IN_DATABASE = 142;
    public final static int MULTIPLE_TABLE_INSERT_ORDER_MISMATCH = 143;
    public final static int INVALID_USE_OF_TRANSPARENT_INDIRECTION = 144;
    public final static int MISSING_INDIRECT_CONTAINER_CONSTRUCTOR = 145;
    public final static int COULD_NOT_INSTANTIATE_INDIRECT_CONTAINER_CLASS = 146;
    public final static int INVALID_CONTAINER_POLICY = 147;
    public final static int INVALID_CONTAINER_POLICY_WITH_TRANSPARENT_INDIRECTION = 148;
    public final static int INVALID_USE_OF_NO_INDIRECTION = 149;
    public final static int INDIRECT_CONTAINER_INSTANTIATION_MISMATCH = 150;
    public final static int INVALID_MAPPING_OPERATION = 151;
    public final static int INVALID_INDIRECTION_POLICY_OPERATION = 152;
    public final static int REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATECOLLECTION = 153;
    public final static int INVALID_INDIRECTION_CONTAINER_CLASS = 154;
    public final static int MISSING_FOREIGN_KEY_TRANSLATION = 155;
    public final static int STRUCTURE_NAME_NOT_SET_IN_MAPPING = 156;
    public final static int NORMAL_DESCRIPTORS_DO_NOT_SUPPORT_NON_RELATIONAL_EXTENSIONS = 157;
    public final static int PARENT_CLASS_IS_SELF = 158;
    public final static int PROXY_INDIRECTION_NOT_AVAILABLE = 159;
    public final static int INVALID_ATTRIBUTE_TYPE_FOR_PROXY_INDIRECTION = 160;
    public final static int INVALID_GET_RETURN_TYPE_FOR_PROXY_INDIRECTION = 161;
    public final static int INVALID_SET_PARAMETER_TYPE_FOR_PROXY_INDIRECTION = 162;
    public final static int INCORRECT_COLLECTION_POLICY = 163;
    public final static int INVALID_AMENDMENT_METHOD = 164;
    public final static int ERROR_OCCURED_IN_AMENDMENT_METHOD = 165;
    public final static int VARIABLE_ONE_TO_ONE_MAPPING_IS_NOT_DEFINED = 166;
    public final static int NO_CONSTRUCTOR_INDIRECT_COLLECTION_CLASS = 167;
    public final static int TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION = 168;
    public final static int TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY = 169;
    public final static int ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY = 170;
    public final static int INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY = 171;
    public final static int NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY = 172;
    public final static int NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY = 173;
    public final static int ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION_OF_FACTORY = 174;
    public final static int TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION_OF_FACTORY = 175;
    public final static int NULL_POINTER_WHILE_METHOD_INSTANTIATION_OF_FACTORY = 176;
    public final static int NO_MAPPING_FOR_ATTRIBUTENAME = 177;
    public final static int NO_MAPPING_FOR_ATTRIBUTENAME_IN_ENTITY_BEAN = 178;
    public final static int UNSUPPORTED_TYPE_FOR_BIDIRECTIONAL_RELATIONSHIP_MAINTENANCE = 179;// Bug 2618982
    public final static int REFERENCE_DESCRIPTOR_CANNOT_BE_AGGREGATE = 180;
    public final static int ATTRIBUTE_TRANSFORMER_CLASS_NOT_FOUND = 181;
    public final static int FIELD_TRANSFORMER_CLASS_NOT_FOUND = 182;
    public final static int ATTRIBUTE_TRANSFORMER_CLASS_INVALID = 183;
    public final static int FIELD_TRANSFORMER_CLASS_INVALID = 184;
    public final static int RETURNING_POLICY_FIELD_TYPE_CONFLICT = 185;
    public final static int RETURNING_POLICY_FIELD_INSERT_CONFLICT = 186;
    public final static int RETURNING_POLICY_AND_DESCRIPTOR_FIELD_TYPE_CONFLICT = 187;
    public final static int RETURNING_POLICY_UNMAPPED_FIELD_TYPE_NOT_SET = 188;
    public final static int RETURNING_POLICY_MAPPED_FIELD_TYPE_NOT_SET = 189;
    public final static int RETURNING_POLICY_MAPPING_NOT_SUPPORTED = 190;
    public final static int RETURNING_POLICY_FIELD_NOT_SUPPORTED = 191;
    public final static int CUSTOM_QUERY_AND_RETURNING_POLICY_CONFLICT = 192;
    public final static int NO_CUSTOM_QUERY_FOR_RETURNING_POLICY = 193;
    public final static int CLASS_EXTRACTION_METHOD_MUST_BE_STATIC = 194;
    public final static int ISOLATED_DESCRIPTOR_REFERENCED_BY_SHARED_DESCRIPTOR = 195;
    public final static int UPDATE_ALL_FIELDS_NOT_SET = 196;
    public final static int INVALID_MAPPING_TYPE = 197;
    public final static int NEED_TO_IMPLEMENT_CHANGETRACKER = 198;
    public final static int NEED_TO_IMPLEMENT_FETCHGROUPTRACKER = 199;
    public final static int ATTEMPT_TO_REGISTER_DEAD_INDIRECTION = 200;
    public final static int UNIT_OF_WORK_ISOLATED_OBJECTS_ACCESSED_IN_SESSION = 201;
    public final static int INTERNAL_ERROR_ACCESSING_PKFIELD = 202;
    public final static int INTERNAL_ERROR_SET_METHOD = 203;
    public final static int INSERT_ORDER_CONFLICTS_WITH_MULTIPLE_TABLE_FOREIGN_KEYS = 204;
    public final static int INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_TWO_TABLES = 205;
    public final static int INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_THREE_OR_MORE_TABLES = 206;
    public final static int INSERT_ORDER_CHILD_BEFORE_PARENT = 207;
    public final static int CANNOT_SET_CONVERTER_FOR_NON_DIRECT_MAPPING = 208;
    public final static int DIRECT_KEY_NOT_SET = 209;
    public final static int LIST_ORDER_FIELD_REQUIRES_LIST = 210;
    public final static int LIST_ORDER_FIELD_REQUIRES_INDIRECT_LIST = 211;
    public final static int LIST_ORDER_FIELD_TABLE_IS_WRONG = 212;
    public final static int MULTIPLE_TARGET_FOREIGN_KEY_TABLES = 213;
    public final static int ONE_TO_ONE_MAPPING_CONFLICT = 214;
    public final static int NO_RELATION_TABLE_MECHANISM = 215;
    public final static int CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID = 216;
    public final static int INVALID_XPATH_FOR_DIRECT_MAPPING = 217;
    public final static int NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR_IN_MODULE_ORDER_BREAKS_WEAVING = 218;
    public final static int ADDITIONAL_CRITERIA_NOT_SUPPORTED_WITH_INHERITANCE_VIEWS = 219;
    public final static int MISSING_PARTITION_POLICY = 220;
    public final static int SERIALIZED_OBJECT_POLICY_FIELD_NOT_SET = 221;
    public final static int EXCEPTION_ACCESSING_PRIMARY_KEY_INSTANCE = 222;

    /**
     * INTERNAL:
     * TopLink exceptions should only be thrown by TopLink.
     */
    protected DescriptorException(String theMessage) {
        super(theMessage);
    }

    /**
     * INTERNAL:
     * TopLink exceptions should only be thrown by TopLink.
     */
    protected DescriptorException(String theMessage, DatabaseMapping mapping) {
        this(theMessage);
        if (mapping != null) {
            this.mapping = mapping;
            this.descriptor = mapping.getDescriptor();
        }
    }

    /**
     * INTERNAL:
     * TopLink exceptions should only be thrown by TopLink.
     */
    protected DescriptorException(String theMessage, ClassDescriptor descriptor) {
        this(theMessage);
        this.descriptor = descriptor;
    }

    protected DescriptorException(String theMessage, ClassDescriptor descriptor, Throwable exception) {
        this(theMessage, descriptor);
        setInternalException(exception);
    }

    public static DescriptorException additionalCriteriaNotSupportedWithInheritanceViews(ClassDescriptor descriptor) {
        Object[] args = { };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ADDITIONAL_CRITERIA_NOT_SUPPORTED_WITH_INHERITANCE_VIEWS, args), descriptor);
        exception.setErrorCode(ADDITIONAL_CRITERIA_NOT_SUPPORTED_WITH_INHERITANCE_VIEWS);
        return exception;
    }

    public static DescriptorException attemptToRegisterDeadIndirection(Object object, DatabaseMapping mapping) {
        Object[] args = { object };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTEMPT_TO_REGISTER_DEAD_INDIRECTION, args), mapping);
        exception.setErrorCode(ATTEMPT_TO_REGISTER_DEAD_INDIRECTION);
        return exception;
    }

    public static DescriptorException attributeAndMappingWithIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_AND_MAPPING_WITH_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(ATTRIBUTE_AND_MAPPING_WITH_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException attributeAndMappingWithoutIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(ATTRIBUTE_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException attributeAndMappingWithTransparentIndirectionMismatch(DatabaseMapping mapping, Class parameterType, String validTypeName) {
        Object[] args = { mapping.getAttributeName(), parameterType, validTypeName };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(ATTRIBUTE_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException attributeNameNotSpecified() {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_NAME_NOT_SPECIFIED, args));
        descriptorException.setErrorCode(ATTRIBUTE_NAME_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException attributeTransformerClassNotFound(String className, AbstractTransformationMapping mapping, Exception exception) {
        Object[] args = { className };
        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_TRANSFORMER_CLASS_NOT_FOUND, args));
        descriptorException.setErrorCode(ATTRIBUTE_TRANSFORMER_CLASS_NOT_FOUND);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException attributeTransformerClassInvalid(String className, AbstractTransformationMapping mapping, Exception exception) {
        Object[] args = { className };
        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_TRANSFORMER_CLASS_INVALID, args));
        descriptorException.setErrorCode(ATTRIBUTE_TRANSFORMER_CLASS_INVALID);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;

    }

    public static DescriptorException attributeTypeNotValid(CollectionMapping mapping, Class interfaceType) {
        Object[] args = { mapping.getAttributeName(), interfaceType };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ATTRIBUTE_TYPE_NOT_VALID, args), mapping);
        exception.setErrorCode(ATTRIBUTE_TYPE_NOT_VALID);
        return exception;
    }

    public static DescriptorException childDoesNotDefineAbstractQueryKeyOfParent(ClassDescriptor child, ClassDescriptor parent, String queryKeyName) {
        Object[] args = { queryKeyName, parent, child };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CHILD_DOES_NOT_DEFINE_ABSTRACT_QUERY_KEY, args));
        descriptorException.setErrorCode(CHILD_DOES_NOT_DEFINE_ABSTRACT_QUERY_KEY);
        return descriptorException;
    }

    public static DescriptorException classIndicatorFieldNotFound(ClassDescriptor parentDescriptor, ClassDescriptor descriptor) {
        Object[] args = { descriptor, parentDescriptor, CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CLASS_INDICATOR_FIELD_NOT_FOUND, args), descriptor);
        descriptorException.setErrorCode(CLASS_INDICATOR_FIELD_NOT_FOUND);
        return descriptorException;
    }

    public static DescriptorException couldNotInstantiateIndirectContainerClass(Class containerClass, Exception exception) {
        Object[] args = { containerClass, Helper.getShortClassName(containerClass) };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, COULD_NOT_INSTANTIATE_INDIRECT_CONTAINER_CLASS, args));
        descriptorException.setErrorCode(COULD_NOT_INSTANTIATE_INDIRECT_CONTAINER_CLASS);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException descriptorForInterfaceIsMissing(String interfaceName) {
        Object[] args = { interfaceName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, DESCRIPTOR_FOR_INTERFACE_IS_MISSING, args));
        descriptorException.setErrorCode(DESCRIPTOR_FOR_INTERFACE_IS_MISSING);
        return descriptorException;
    }

    public static DescriptorException descriptorIsMissing(String className, DatabaseMapping mapping) {
        Object[] args = { className };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, DESCRIPTOR_IS_MISSING, args), mapping);
        descriptorException.setErrorCode(DESCRIPTOR_IS_MISSING);
        return descriptorException;
    }

    public static DescriptorException directFieldNameNotSet(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, DIRECT_FIELD_NAME_NOT_SET, args), mapping);
        descriptorException.setErrorCode(DIRECT_FIELD_NAME_NOT_SET);
        return descriptorException;
    }


    public static DescriptorException errorAccessingSetMethodOfEntity(Class aClass, String methodName, ClassDescriptor descriptor, Exception underlying) {
        Object[] args = { aClass, methodName };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INTERNAL_ERROR_SET_METHOD, args), descriptor, underlying);
        return exception;
    }


    public static DescriptorException errorOccuredInAmendmentMethod(Class amendmentClass, String method, Exception exception, ClassDescriptor descriptor) {
        Object[] args = { amendmentClass, method };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ERROR_OCCURED_IN_AMENDMENT_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(ERROR_OCCURED_IN_AMENDMENT_METHOD);
        return descriptorException;
    }

    public static DescriptorException fieldIsNotPresentInDatabase(ClassDescriptor descriptor, String tableName, String fieldName) {
        Object[] args = { fieldName, tableName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, FIELD_IS_NOT_PRESENT_IN_DATABASE, args), descriptor);
        descriptorException.setErrorCode(FIELD_IS_NOT_PRESENT_IN_DATABASE);
        return descriptorException;
    }

    public static DescriptorException fieldNameNotSetInMapping(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, FIELD_NAME_NOT_SET_IN_MAPPING, args), mapping);
        descriptorException.setErrorCode(FIELD_NAME_NOT_SET_IN_MAPPING);
        return descriptorException;
    }

    public static DescriptorException fieldTransformerClassNotFound(String className, AbstractTransformationMapping mapping, Exception exception) {
        Object[] args = { className };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, FIELD_TRANSFORMER_CLASS_NOT_FOUND, args));
        descriptorException.setErrorCode(FIELD_TRANSFORMER_CLASS_NOT_FOUND);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException fieldTransformerClassInvalid(String className, AbstractTransformationMapping mapping, Exception exception) {
        Object[] args = { className };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, FIELD_TRANSFORMER_CLASS_INVALID, args));
        descriptorException.setErrorCode(FIELD_TRANSFORMER_CLASS_NOT_FOUND);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException foreignKeysDefinedIncorrectly(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, FOREIGN_KEYS_DEFINED_INCORRECTLY, args), mapping);
        descriptorException.setErrorCode(FOREIGN_KEYS_DEFINED_INCORRECTLY);
        return descriptorException;
    }

    /**
     * PUBLIC:
     * Return the descriptor that the problem was detected in.
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * PUBLIC:
     * Return the mapping that the problem was detected in.
     */
    public DatabaseMapping getMapping() {
        return mapping;
    }

    /**
     * PUBLIC:
     * Return the exception error message.
     * TopLink error messages are multi-line so that detail descriptions of the exception are given.
     */
    @Override
    public String getMessage() {
        if (getDescriptor() == null) {
            return super.getMessage();
        }

        if (getMapping() != null) {
            return super.getMessage() + cr() + getIndentationString() + ExceptionMessageGenerator.getHeader("MappingHeader") + getMapping().toString() + cr() + getIndentationString() + ExceptionMessageGenerator.getHeader("DescriptorHeader") + getDescriptor().toString();
        } else {
            return super.getMessage() + cr() + getIndentationString() + ExceptionMessageGenerator.getHeader("DescriptorHeader") + getDescriptor().toString();
        }
    }

    public static DescriptorException getMethodReturnTypeNotValid(CollectionMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, GET_METHOD_RETURN_TYPE_NOT_VALID, args), mapping);
        exception.setErrorCode(GET_METHOD_RETURN_TYPE_NOT_VALID);
        return exception;
    }

    public static DescriptorException identityMapNotSpecified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, IDENTITY_MAP_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(IDENTITY_MAP_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException illegalAccesstWhileGettingValueThruInstanceVaraibleAccessor(String attributeName, String objectName, Throwable exception) {
        Object[] args = { attributeName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileCloning(Object domainObject, String methodName, ClassDescriptor descriptor, Throwable exception) {
        Object[] args = { domainObject, methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_CLONING, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_CLONING);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileConstructorInstantiation(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileConstructorInstantiationOfFactory(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileEventExecution(String eventMethodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { eventMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_EVENT_EXECUTION, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_EVENT_EXECUTION);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileGettingValueThruMethodAccessor(String methodName, String objectName, Throwable exception) {
        Object[] args = { methodName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileInstantiatingMethodBasedProxy(Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_INSTANTIATING_METHOD_BASED_PROXY, args));
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_INSTANTIATING_METHOD_BASED_PROXY);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileInvokingAttributeMethod(DatabaseMapping mapping, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_INVOKING_ATTRIBUTE_METHOD, args));
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_INVOKING_ATTRIBUTE_METHOD);
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileInvokingFieldToMethod(String methodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_INVOKING_FIELD_TO_METHOD, args));
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_INVOKING_FIELD_TO_METHOD);
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileInvokingRowExtractionMethod(AbstractRecord row, Method method, ClassDescriptor descriptor, Throwable exception) {
        Object[] args = { row, method };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_INVOKING_ROW_EXTRACTION_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_INVOKING_ROW_EXTRACTION_METHOD);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileMethodInstantiation(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileMethodInstantiationOfFactory(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_METHOD_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileObsoleteEventExecute(String eventMethodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { eventMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_OBSOLETE_EVENT_EXECUTION, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_OBSOLETE_EVENT_EXECUTION);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileSettingValueThruInstanceVariableAccessor(String attributeName, String objectName, Object objectValue, Throwable exception) {
        Object[] args = { attributeName, objectName, String.valueOf(objectValue), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalAccessWhileSettingValueThruMethodAccessor(String setMethodName, Object value, Throwable exception) {
        Object[] args = { setMethodName, String.valueOf(value) };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ACCESS_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileGettingValueThruInstanceVariableAccessor(String attributeName, String typeName, String objectName, Throwable exception) {
        Object[] args = { attributeName, typeName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileGettingValueThruMethodAccessor(String methodName, String objectName, Throwable exception) {
        Object[] args = { methodName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileInstantiatingMethodBasedProxy(Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_INSTANTIATING_METHOD_BASED_PROXY, args));
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_INSTANTIATING_METHOD_BASED_PROXY);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileInvokingAttributeMethod(DatabaseMapping mapping, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_INVOKING_ATTRIBUTE_METHOD, args));
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_INVOKING_ATTRIBUTE_METHOD);
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileInvokingFieldToMethod(String methodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_INVOKING_FIELD_TO_METHOD, args));
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_INVOKING_FIELD_TO_METHOD);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileObsoleteEventExecute(String eventMethodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { eventMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_OBSOLETE_EVENT_EXECUTION, args), descriptor, exception);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_OBSOLETE_EVENT_EXECUTION);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileSettingValueThruInstanceVariableAccessor(String attributeName, String typeName, Object value, Throwable exception) {
        Object[] args = { String.valueOf(value), attributeName, typeName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalArgumentWhileSettingValueThruMethodAccessor(String setMethodName, Object value, Throwable exception) {
        Object[] args = { setMethodName, String.valueOf(value) };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(ILLEGAL_ARGUMENT_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException illegalTableNameInMultipleTableForeignKeyField(ClassDescriptor descriptor, DatabaseTable table) {
        Object[] args = { table };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ILLEGAL_TABLE_NAME_IN_MULTIPLE_TABLE_FOREIGN_KEY, args), descriptor);
        descriptorException.setErrorCode(ILLEGAL_TABLE_NAME_IN_MULTIPLE_TABLE_FOREIGN_KEY);
        return descriptorException;
    }

    public static DescriptorException incorrectCollectionPolicy(DatabaseMapping mapping, Class attributeClass, Class containerClass) {
        Object[] args = { attributeClass, containerClass };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INCORRECT_COLLECTION_POLICY, args), mapping);
        descriptorException.setErrorCode(INCORRECT_COLLECTION_POLICY);
        return descriptorException;
    }

    public static DescriptorException indirectContainerInstantiationMismatch(Object attributeValue, DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName(), attributeValue, CR };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INDIRECT_CONTAINER_INSTANTIATION_MISMATCH, args), mapping);
        exception.setErrorCode(INDIRECT_CONTAINER_INSTANTIATION_MISMATCH);
        return exception;
    }

    public static DescriptorException instantiationWhileConstructorInstantiation(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException instantiationWhileConstructorInstantiationOfFactory(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(INSTANTIATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException invalidAmendmentMethod(Class amendmentClass, String method, Exception exception, ClassDescriptor descriptor) {
        Object[] args = { amendmentClass, method, CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_AMENDMENT_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(INVALID_AMENDMENT_METHOD);
        return descriptorException;
    }

    public static DescriptorException invalidAttributeTypeForProxyIndirection(Class attributeType, Class[] targetInterfaces, DatabaseMapping mapping) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < targetInterfaces.length; i++) {
            buffer.append(targetInterfaces[i].getName());
            if (i != (targetInterfaces.length - 1)) {
                buffer.append(", ");
            }
        }

        Object[] args = { mapping.getAttributeName(), mapping.getDescriptor().getJavaClass().getName(), attributeType.getName(), buffer.toString(), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_ATTRIBUTE_TYPE_FOR_PROXY_INDIRECTION, args), mapping);
        descriptorException.setErrorCode(INVALID_ATTRIBUTE_TYPE_FOR_PROXY_INDIRECTION);
        return descriptorException;
    }

    public static DescriptorException invalidContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy containerPolicy, Class javaClass) {
        Object[] args = { containerPolicy, javaClass };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_CONTAINER_POLICY, args));
        exception.setErrorCode(INVALID_CONTAINER_POLICY);
        return exception;
    }

    public static DescriptorException invalidContainerPolicyWithTransparentIndirection(DatabaseMapping mapping, org.eclipse.persistence.internal.queries.ContainerPolicy containerPolicy) {
        Object[] args = { containerPolicy };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_CONTAINER_POLICY_WITH_TRANSPARENT_INDIRECTION, args), mapping);
        exception.setErrorCode(INVALID_CONTAINER_POLICY_WITH_TRANSPARENT_INDIRECTION);
        return exception;
    }

    public static DescriptorException invalidDataModificationEvent(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_DATA_MODIFICATION_EVENT, args), mapping);
        descriptorException.setErrorCode(INVALID_DATA_MODIFICATION_EVENT);
        return descriptorException;
    }

    public static DescriptorException invalidDataModificationEventCode(Object event, ForeignReferenceMapping mapping) {
        Object[] args = { event };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_DATA_MODIFICATION_EVENT_CODE, args), mapping);
        descriptorException.setErrorCode(INVALID_DATA_MODIFICATION_EVENT_CODE);
        return descriptorException;
    }

    public static DescriptorException invalidDescriptorEventCode(DescriptorEvent event, ClassDescriptor descriptor) {
        Object[] args = {event.getEventCode()};

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_DESCRIPTOR_EVENT_CODE, args), descriptor);
        descriptorException.setErrorCode(INVALID_DESCRIPTOR_EVENT_CODE);
        return descriptorException;
    }

    public static DescriptorException invalidGetMethodReturnTypeForProxyIndirection(Class attributeType, Class[] targetInterfaces, DatabaseMapping mapping) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < targetInterfaces.length; i++) {
            buffer.append(targetInterfaces[i].getName());
            if (i != (targetInterfaces.length - 1)) {
                buffer.append(", ");
            }
        }

        Object[] args = { mapping.getGetMethodName(), mapping.getDescriptor().getJavaClass().getName(), attributeType.getName(), buffer.toString(), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_GET_RETURN_TYPE_FOR_PROXY_INDIRECTION, args), mapping);
        descriptorException.setErrorCode(INVALID_GET_RETURN_TYPE_FOR_PROXY_INDIRECTION);
        return descriptorException;
    }

    public static DescriptorException invalidIdentityMap(ClassDescriptor descriptor, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_IDENTITY_MAP, args), descriptor, exception);
        descriptorException.setErrorCode(INVALID_IDENTITY_MAP);
        return descriptorException;
    }

    public static DescriptorException invalidIndirectionContainerClass(org.eclipse.persistence.internal.indirection.ContainerIndirectionPolicy policy, Class containerClass) {
        Object[] args = { containerClass };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_INDIRECTION_CONTAINER_CLASS, args), policy.getMapping());
        descriptorException.setErrorCode(INVALID_INDIRECTION_CONTAINER_CLASS);
        return descriptorException;
    }

    public static DescriptorException invalidIndirectionPolicyOperation(org.eclipse.persistence.internal.indirection.IndirectionPolicy policy, String operation) {
        Object[] args = { policy, operation };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_INDIRECTION_POLICY_OPERATION, args), policy.getMapping());
        descriptorException.setErrorCode(INVALID_INDIRECTION_POLICY_OPERATION);
        return descriptorException;
    }

    public static DescriptorException invalidMappingOperation(DatabaseMapping mapping, String operation) {
        Object[] args = { operation };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_MAPPING_OPERATION, args), mapping);
        descriptorException.setErrorCode(INVALID_MAPPING_OPERATION);
        return descriptorException;
    }

    public static DescriptorException invalidSetMethodParameterTypeForProxyIndirection(Class attributeType, Class[] targetInterfaces, DatabaseMapping mapping) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < targetInterfaces.length; i++) {
            buffer.append(targetInterfaces[i].getName());
            if (i != (targetInterfaces.length - 1)) {
                buffer.append(", ");
            }
        }

        Object[] args = { mapping.getSetMethodName(), mapping.getDescriptor().getJavaClass().getName(), attributeType.getName(), buffer.toString(), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_SET_PARAMETER_TYPE_FOR_PROXY_INDIRECTION, args), mapping);
        descriptorException.setErrorCode(INVALID_SET_PARAMETER_TYPE_FOR_PROXY_INDIRECTION);
        return descriptorException;
    }

    public static DescriptorException invalidUseOfNoIndirection(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_USE_OF_NO_INDIRECTION, args), mapping);
        exception.setErrorCode(INVALID_USE_OF_NO_INDIRECTION);
        return exception;
    }

    public static DescriptorException invalidUseOfTransparentIndirection(DatabaseMapping mapping) {
        Object[] args = {  };

        String message = org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_USE_OF_TRANSPARENT_INDIRECTION, args);
        DescriptorException exception = new DescriptorException(message, mapping);
        exception.setErrorCode(INVALID_USE_OF_TRANSPARENT_INDIRECTION);
        return exception;
    }

    public static DescriptorException isolateDescriptorReferencedBySharedDescriptor(String referenceClass, String sourceClass, DatabaseMapping mapping) {
        Object[] args = { referenceClass, sourceClass };

        String message = org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator.buildMessage(DescriptorException.class, ISOLATED_DESCRIPTOR_REFERENCED_BY_SHARED_DESCRIPTOR, args);
        DescriptorException exception = new DescriptorException(message, mapping);
        exception.setErrorCode(ISOLATED_DESCRIPTOR_REFERENCED_BY_SHARED_DESCRIPTOR);
        return exception;
    }

    public static DescriptorException javaClassNotSpecified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, JAVA_CLASS_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(JAVA_CLASS_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException mappingCanNotBeReadOnly(DatabaseMapping mapping) {
        Object[] args = { mapping.getDescriptor().getJavaClass() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, LOCK_MAPPING_CANNOT_BE_READONLY, args), mapping);
        descriptorException.setErrorCode(LOCK_MAPPING_CANNOT_BE_READONLY);
        return descriptorException;
    }

    public static DescriptorException mappingForSequenceNumberField(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MAPPING_FOR_SEQUENCE_NUMBER_FIELD, args));
        descriptorException.setErrorCode(MAPPING_FOR_SEQUENCE_NUMBER_FIELD);
        descriptorException.setDescriptor(descriptor);
        return descriptorException;
    }

    public static DescriptorException missingClassForIndicatorFieldValue(Object classFieldValue, ClassDescriptor descriptor) {
        Object[] args = { classFieldValue, classFieldValue.getClass() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_CLASS_FOR_INDICATOR_FIELD_VALUE, args), descriptor);
        descriptorException.setErrorCode(MISSING_CLASS_FOR_INDICATOR_FIELD_VALUE);
        return descriptorException;
    }

    public static DescriptorException missingClassIndicatorField(AbstractRecord row, ClassDescriptor descriptor) {
        Object[] args = { row };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_CLASS_INDICATOR_FIELD, args), descriptor);
        descriptorException.setErrorCode(MISSING_CLASS_INDICATOR_FIELD);
        return descriptorException;
    }

    /**
     * @since EclipseLink 2.5.0
     */
    public static DescriptorException missingClassIndicatorField(XMLRecord row, ClassDescriptor descriptor) {
        Object[] args = { row };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_CLASS_INDICATOR_FIELD, args), descriptor);
        descriptorException.setErrorCode(MISSING_CLASS_INDICATOR_FIELD);
        return descriptorException;
    }

    public static DescriptorException missingForeignKeyTranslation(ForeignReferenceMapping mapping, DatabaseField primaryKeyField) {
        Object[] args = { primaryKeyField };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_FOREIGN_KEY_TRANSLATION, args), mapping);
        exception.setErrorCode(MISSING_FOREIGN_KEY_TRANSLATION);
        return exception;
    }

    public static DescriptorException missingIndirectContainerConstructor(Class containerClass) {
        Object[] args = { containerClass.getName(), containerClass.getName() + "()" };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_INDIRECT_CONTAINER_CONSTRUCTOR, args));
        exception.setErrorCode(MISSING_INDIRECT_CONTAINER_CONSTRUCTOR);
        return exception;
    }

    public static DescriptorException missingMappingForField(DatabaseField field, ClassDescriptor descriptor) {
        Object[] args = { field };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_MAPPING_FOR_FIELD, args));
        descriptorException.setErrorCode(MISSING_MAPPING_FOR_FIELD);
        descriptorException.setDescriptor(descriptor);
        return descriptorException;
    }

    public static DescriptorException multipleTableInsertOrderMismatch(ClassDescriptor aDescriptor) {
        Object[] args = { aDescriptor.getMultipleTableInsertOrder(), aDescriptor.getTables(), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MULTIPLE_TABLE_INSERT_ORDER_MISMATCH, args));
        descriptorException.setErrorCode(MULTIPLE_TABLE_INSERT_ORDER_MISMATCH);
        descriptorException.setDescriptor(aDescriptor);
        return descriptorException;
    }

    public static DescriptorException multipleTablePrimaryKeyMustBeFullyQualified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MULTIPLE_TABLE_PRIMARY_KEY_MUST_BE_FULLY_QUALIFIED, args), descriptor);
        descriptorException.setErrorCode(MULTIPLE_TABLE_PRIMARY_KEY_MUST_BE_FULLY_QUALIFIED);
        return descriptorException;
    }

    public static DescriptorException multipleTablePrimaryKeyNotSpecified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MULTIPLE_TABLE_PRIMARY_KEY_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(MULTIPLE_TABLE_PRIMARY_KEY_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException multipleWriteMappingsForField(String fieldName, DatabaseMapping mapping) {
        Object[] args = { fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MULTIPLE_WRITE_MAPPINGS_FOR_FIELD, args), mapping);
        descriptorException.setErrorCode(MULTIPLE_WRITE_MAPPINGS_FOR_FIELD);
        return descriptorException;
    }

    public static DescriptorException mustBeReadOnlyMappingWhenStoredInCache(DatabaseMapping mapping) {
        Object[] args = { mapping.getDescriptor().getJavaClass() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, LOCK_MAPPING_MUST_BE_READONLY, args), mapping);
        descriptorException.setErrorCode(LOCK_MAPPING_MUST_BE_READONLY);
        return descriptorException;
    }

    public static DescriptorException noAttributeTransformationMethod(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_ATTRIBUTE_TRANSFORMATION_METHOD, args), mapping);
        descriptorException.setErrorCode(NO_ATTRIBUTE_TRANSFORMATION_METHOD);
        return descriptorException;
    }

    public static DescriptorException noAttributeValueConversionToFieldValueProvided(Object attributeValue, DatabaseMapping mapping) {
        Object[] args = { attributeValue };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_ATTRBUTE_VALUE_CONVERSION_TO_FIELD_VALUE_PROVIDED, args), mapping);
        descriptorException.setErrorCode(NO_ATTRBUTE_VALUE_CONVERSION_TO_FIELD_VALUE_PROVIDED);
        return descriptorException;
    }

    public static DescriptorException noConstructorIndirectionContainerClass(org.eclipse.persistence.internal.indirection.ContainerIndirectionPolicy policy, Class containerClass) {
        Object[] args = { containerClass };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_CONSTRUCTOR_INDIRECT_COLLECTION_CLASS, args), policy.getMapping());
        descriptorException.setErrorCode(NO_CONSTRUCTOR_INDIRECT_COLLECTION_CLASS);
        return descriptorException;
    }

    public static DescriptorException noFieldNameForMapping(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_FIELD_NAME_FOR_MAPPING, args), mapping);
        descriptorException.setErrorCode(NO_FIELD_NAME_FOR_MAPPING);
        return descriptorException;
    }

    // CR#3779 - Added field as an argument
    public static DescriptorException noFieldValueConversionToAttributeValueProvided(Object fieldValue, DatabaseField field, DatabaseMapping mapping) {
        Object[] args = { fieldValue, field };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_FIELD_VALUE_CONVERSION_TO_ATTRIBUTE_VALUE_PROVIDED, args), mapping);
        descriptorException.setErrorCode(NO_FIELD_VALUE_CONVERSION_TO_ATTRIBUTE_VALUE_PROVIDED);
        return descriptorException;
    }

    public static DescriptorException noForeignKeysAreSpecified(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_FOREIGN_KEYS_ARE_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(NO_FOREIGN_KEYS_ARE_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException noMappingForPrimaryKey(DatabaseField field, ClassDescriptor descriptor) {
        Object[] args = { field };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_MAPPING_FOR_PRIMARY_KEY, args), descriptor);
        descriptorException.setErrorCode(NO_MAPPING_FOR_PRIMARY_KEY);
        return descriptorException;
    }

    public static DescriptorException noReferenceKeyIsSpecified(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_REFERENCE_KEY_IS_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(NO_REFERENCE_KEY_IS_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException noRelationTable(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_RELATION_TABLE, args), mapping);
        descriptorException.setErrorCode(NO_RELATION_TABLE);
        return descriptorException;
    }

    public static DescriptorException normalDescriptorsDoNotSupportNonRelationalExtensions(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NORMAL_DESCRIPTORS_DO_NOT_SUPPORT_NON_RELATIONAL_EXTENSIONS, args), descriptor);
        descriptorException.setErrorCode(NORMAL_DESCRIPTORS_DO_NOT_SUPPORT_NON_RELATIONAL_EXTENSIONS);
        return descriptorException;
    }

    public static DescriptorException noSourceRelationKeysSpecified(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SOURCE_RELATION_KEYS_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(NO_SOURCE_RELATION_KEYS_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException noSubClassMatch(Class theClass, DatabaseMapping mapping) {
        Object[] args = { theClass };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUB_CLASS_MATCH, args), mapping);

        descriptorException.setErrorCode(NO_SUB_CLASS_MATCH);
        return descriptorException;
    }

    public static DescriptorException noSuchFieldWhileInitializingAttributesInInstanceVariableAccessor(String attributeName, String javaClassName, Throwable exception) {
        Object[] args = { attributeName, javaClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_FIELD_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NO_SUCH_FIELD_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodOnFindObsoleteMethod(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_ON_FIND_OBSOLETE_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_ON_FIND_OBSOLETE_METHOD);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodOnInitializingAttributeMethod(String attributeMethodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { attributeMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_ON_INITIALIZING_ATTRIBUTE_METHOD, args));
        descriptorException.setErrorCode(NO_SUCH_METHOD_ON_INITIALIZING_ATTRIBUTE_METHOD);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileConstructorInstantiation(ClassDescriptor descriptor, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileConstructorInstantiationOfFactory(ClassDescriptor descriptor, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileConvertingToMethod(String methodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_CONVERTING_TO_METHOD, args));
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_CONVERTING_TO_METHOD);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileInitializingAttributesInMethodAccessor(String setMethodName, String getMethodName, String javaClassName) {
        Object[] args = { setMethodName, getMethodName, javaClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR, args));
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileInitializingClassExtractionMethod(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileInitializingCopyPolicy(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_INITIALIZING_COPY_POLICY, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_INITIALIZING_COPY_POLICY);
        return descriptorException;
    }

    public static DescriptorException noSuchMethodWhileInitializingInstantiationPolicy(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_SUCH_METHOD_WHILE_INITIALIZING_INSTANTIATION_POLICY, args), descriptor, exception);
        descriptorException.setErrorCode(NO_SUCH_METHOD_WHILE_INITIALIZING_INSTANTIATION_POLICY);
        return descriptorException;
    }

    public static DescriptorException noTargetForeignKeysSpecified(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_TARGET_FOREIGN_KEYS_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(NO_TARGET_FOREIGN_KEYS_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException noTargetRelationKeysSpecified(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_TARGET_RELATION_KEYS_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(NO_TARGET_RELATION_KEYS_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException notDeserializable(DatabaseMapping mapping, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NOT_DESERIALIZABLE, args));
        descriptorException.setErrorCode(NOT_DESERIALIZABLE);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException notSerializable(DatabaseMapping mapping, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NOT_SERIALIZABLE, args));
        descriptorException.setErrorCode(NOT_SERIALIZABLE);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);

        return descriptorException;
    }

    public static DescriptorException nullForNonNullAggregate(Object object, DatabaseMapping mapping) {
        Object[] args = { object };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_FOR_NON_NULL_AGGREGATE, args), mapping);
        exception.setErrorCode(NULL_FOR_NON_NULL_AGGREGATE);
        return exception;
    }

    public static DescriptorException nullPointerWhileConstructorInstantiation(ClassDescriptor descriptor, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileConstructorInstantiationOfFactory(ClassDescriptor descriptor, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileGettingValueThruInstanceVariableAccessor(String attributeName, String objectName, Throwable exception) {
        Object[] args = { attributeName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_GETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileGettingValueThruMethodAccessor(String methodName, String objectName, Throwable exception) {
        Object[] args = { methodName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    // 323403: Handle NPE because of module order issue that stops weaving from occurring
    public static DescriptorException nullPointerWhileGettingValueThruMethodAccessorCausedByWeavingNotOccurringBecauseOfModuleOrder(String methodName, String objectName, Throwable exception) {
        Object[] args = { methodName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR_IN_MODULE_ORDER_BREAKS_WEAVING, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR_IN_MODULE_ORDER_BREAKS_WEAVING);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileMethodInstantiation(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_METHOD_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_METHOD_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileMethodInstantiationOfFactory(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_METHOD_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_METHOD_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileSettingValueThruInstanceVariableAccessor(String attributeName, Object objectValue, Throwable exception) {
        Object[] args = { attributeName, String.valueOf(objectValue) };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_SETTING_VALUE_THRU_INSTANCE_VARIABLE_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException nullPointerWhileSettingValueThruMethodAccessor(String setMethodName, Object value, Throwable exception) {
        Object[] args = { setMethodName, String.valueOf(value) };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NULL_POINTER_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(NULL_POINTER_WHILE_SETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException onlyOneTableCanBeAddedWithThisMethod(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ONLY_ONE_TABLE_CAN_BE_ADDED_WITH_THIS_METHOD, args), descriptor);
        descriptorException.setErrorCode(ONLY_ONE_TABLE_CAN_BE_ADDED_WITH_THIS_METHOD);
        return descriptorException;
    }

    public static DescriptorException parameterAndMappingWithIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PARAMETER_AND_MAPPING_WITH_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(PARAMETER_AND_MAPPING_WITH_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException parameterAndMappingWithoutIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PARAMETER_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(PARAMETER_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException parameterAndMappingWithTransparentIndirectionMismatch(DatabaseMapping mapping, Class parameterType, String validTypeName) {
        Object[] args = { mapping.getAttributeName(), parameterType, validTypeName };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PARAMETER_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(PARAMETER_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException parentClassIsSelf(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PARENT_CLASS_IS_SELF, args), descriptor);
        exception.setErrorCode(PARENT_CLASS_IS_SELF);
        return exception;
    }

    public static DescriptorException parentDescriptorNotSpecified(String parentClassName, ClassDescriptor descriptor) {
        Object[] args = { parentClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PARENT_DESCRIPTOR_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(PARENT_DESCRIPTOR_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException primaryKeyFieldsNotSepcified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PRIMARY_KEY_FIELDS_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(PRIMARY_KEY_FIELDS_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException proxyIndirectionNotAvailable(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, PROXY_INDIRECTION_NOT_AVAILABLE, args), mapping);
        descriptorException.setErrorCode(PROXY_INDIRECTION_NOT_AVAILABLE);
        return descriptorException;
    }

    public static DescriptorException referenceClassNotSpecified(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, REFERENCE_CLASS_NOT_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(REFERENCE_CLASS_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException referenceDescriptorIsNotAggregate(String className, DatabaseMapping mapping) {
        Object[] args = { className };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATE, args), mapping);
        descriptorException.setErrorCode(REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATE);
        return descriptorException;
    }

    public static DescriptorException referenceDescriptorCannotBeAggregate(DatabaseMapping mapping) {
        DescriptorException descriptorException = new DescriptorException("Reference descriptor cannot be aggregate.", mapping);
        descriptorException.setErrorCode(REFERENCE_DESCRIPTOR_CANNOT_BE_AGGREGATE);
        return descriptorException;
    }

    public static DescriptorException referenceDescriptorIsNotAggregateCollection(String className, DatabaseMapping mapping) {
        Object[] args = { className };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATECOLLECTION, args), mapping);
        descriptorException.setErrorCode(REFERENCE_DESCRIPTOR_IS_NOT_AGGREGATECOLLECTION);
        return descriptorException;
    }

    public static DescriptorException referenceKeyFieldNotProperlySpecified(DatabaseField field, ForeignReferenceMapping mapping) {
        Object[] args = { field };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, REFERENCE_KEY_FIELD_NOT_PROPERLY_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(REFERENCE_KEY_FIELD_NOT_PROPERLY_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException referenceTableNotSpecified(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, REFERENCE_TABLE_NOT_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(REFERENCE_TABLE_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException relationKeyFieldNotProperlySpecified(DatabaseField field, ForeignReferenceMapping mapping) {
        Object[] args = { field };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RELATION_KEY_FIELD_NOT_PROPERLY_SPECIFIED, args), mapping);
        descriptorException.setErrorCode(RELATION_KEY_FIELD_NOT_PROPERLY_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException returnAndMappingWithIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURN_AND_MAPPING_WITH_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(RETURN_AND_MAPPING_WITH_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException returnAndMappingWithoutIndirectionMismatch(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURN_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(RETURN_AND_MAPPING_WITHOUT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException returnAndMappingWithTransparentIndirectionMismatch(DatabaseMapping mapping, Class parameterType, String validTypeName) {
        Object[] args = { mapping.getAttributeName(), parameterType, validTypeName };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURN_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH, args), mapping);
        exception.setErrorCode(RETURN_AND_MAPPING_WITH_TRANSPARENT_INDIRECTION_MISMATCH);
        return exception;
    }

    public static DescriptorException returnTypeInGetAttributeAccessor(String attributeMethodName, DatabaseMapping mapping) {
        Object[] args = { attributeMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURN_TYPE_IN_GET_ATTRIBUTE_ACCESSOR, args));
        descriptorException.setErrorCode(RETURN_TYPE_IN_GET_ATTRIBUTE_ACCESSOR);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException securityOnFindMethod(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_ON_FIND_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(SECURITY_ON_FIND_METHOD);
        return descriptorException;
    }

    public static DescriptorException securityOnFindObsoleteMethod(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_ON_FIND_OBSOLETE_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(SECURITY_ON_FIND_OBSOLETE_METHOD);
        return descriptorException;
    }

    public static DescriptorException securityOnInitializingAttributeMethod(String attributeMethodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { attributeMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_ON_INITIALIZING_ATTRIBUTE_METHOD, args));
        descriptorException.setErrorCode(SECURITY_ON_INITIALIZING_ATTRIBUTE_METHOD);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException securityWhileConvertingToMethod(String methodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_CONVERTING_TO_METHOD, args));
        descriptorException.setErrorCode(SECURITY_WHILE_CONVERTING_TO_METHOD);
        descriptorException.setMapping(mapping);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException securityWhileInitializingAttributesInInstanceVariableAccessor(String attributeName, String javaClassName, Throwable exception) {
        Object[] args = { attributeName, javaClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR, args));
        descriptorException.setErrorCode(SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_INSTANCE_VARIABLE_ACCESSOR);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException securityWhileInitializingAttributesInMethodAccessor(String setMethodName, String getMethodName, String javaClassName) {
        Object[] args = { setMethodName, getMethodName, javaClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR, args));
        descriptorException.setErrorCode(SECURITY_WHILE_INITIALIZING_ATTRIBUTES_IN_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException securityWhileInitializingClassExtractionMethod(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(SECURITY_WHILE_INITIALIZING_CLASS_EXTRACTION_METHOD);
        return descriptorException;
    }

    public static DescriptorException classExtractionMethodMustBeStatic(String methodName, ClassDescriptor descriptor) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CLASS_EXTRACTION_METHOD_MUST_BE_STATIC, args), descriptor);
        descriptorException.setErrorCode(CLASS_EXTRACTION_METHOD_MUST_BE_STATIC);
        return descriptorException;
    }

    public static DescriptorException securityWhileInitializingCopyPolicy(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_INITIALIZING_COPY_POLICY, args), descriptor, exception);
        descriptorException.setErrorCode(SECURITY_WHILE_INITIALIZING_COPY_POLICY);
        return descriptorException;
    }

    public static DescriptorException securityWhileInitializingInstantiationPolicy(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SECURITY_WHILE_INITIALIZING_INSTANTIATION_POLICY, args), descriptor, exception);
        descriptorException.setErrorCode(SECURITY_WHILE_INITIALIZING_INSTANTIATION_POLICY);
        return descriptorException;
    }

    public static DescriptorException sequenceNumberPropertyNotSpecified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SEQUENCE_NUMBER_PROPERTY_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(SEQUENCE_NUMBER_PROPERTY_NOT_SPECIFIED);
        return descriptorException;
    }

    /**
     * INTERNAL:
     * Set the mapping.
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    public static DescriptorException setExistenceCheckingNotUnderstood(String token, ClassDescriptor descriptor) {
        Object[] args = { token };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SET_EXISTENCE_CHECKING_NOT_UNDERSTOOD, args), descriptor);
        descriptorException.setErrorCode(SET_EXISTENCE_CHECKING_NOT_UNDERSTOOD);
        return descriptorException;
    }

    /**
     * INTERNAL:
     * Set the mapping.
     */
    public void setMapping(DatabaseMapping mapping) {
        if (mapping != null) {
            this.mapping = mapping;
            setDescriptor(mapping.getDescriptor());
        }
    }

    public static DescriptorException setMethodParameterTypeNotValid(CollectionMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SET_METHOD_PARAMETER_TYPE_NOT_VALID, args), mapping);
        exception.setErrorCode(SET_METHOD_PARAMETER_TYPE_NOT_VALID);
        return exception;
    }

    public static DescriptorException sizeMismatchOfForeignKeys(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SIZE_MISMATCH_OF_FOREIGN_KEYS, args), mapping);
        descriptorException.setErrorCode(SIZE_MISMATCH_OF_FOREIGN_KEYS);
        return descriptorException;
    }

    public static DescriptorException structureNameNotSetInMapping(DatabaseMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, STRUCTURE_NAME_NOT_SET_IN_MAPPING, args), mapping);
        descriptorException.setErrorCode(STRUCTURE_NAME_NOT_SET_IN_MAPPING);
        return descriptorException;
    }

    public static DescriptorException tableIsNotPresentInDatabase(ClassDescriptor descriptor) {
        Object[] args = { descriptor.getTableName() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TABLE_IS_NOT_PRESENT_IN_DATABASE, args), descriptor);
        descriptorException.setErrorCode(TABLE_IS_NOT_PRESENT_IN_DATABASE);
        return descriptorException;
    }

    public static DescriptorException tableNotPresent(String tableName, ClassDescriptor descriptor) {
        Object[] args = { tableName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TABLE_NOT_PRESENT, args), descriptor);
        descriptorException.setErrorCode(TABLE_NOT_PRESENT);
        return descriptorException;
    }

    public static DescriptorException tableNotSpecified(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TABLE_NOT_SPECIFIED, args), descriptor);
        descriptorException.setErrorCode(TABLE_NOT_SPECIFIED);
        return descriptorException;
    }

    public static DescriptorException targetForeignKeysSizeMismatch(ForeignReferenceMapping mapping) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_FOREIGN_KEYS_SIZE_MISMATCH, args), mapping);
        descriptorException.setErrorCode(TARGET_FOREIGN_KEYS_SIZE_MISMATCH);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileCloning(Object domainObject, String methodName, ClassDescriptor descriptor, Throwable exception) {
        Object[] args = { domainObject, methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_CLONING, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_CLONING);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileConstructorInstantiation(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileConstructorInstantiationOfFactory(ClassDescriptor descriptor, Exception exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_CONSTRUCTOR_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileEventExecution(String eventMethodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { eventMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_EVENT_EXECUTION, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_EVENT_EXECUTION);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileGettingValueThruMethodAccessor(String methodName, String objectName, Throwable exception) {
        Object[] args = { methodName, objectName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_GETTING_VALUE_THRU_METHOD_ACCESSOR);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileInstantiatingMethodBasedProxy(Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_INSTANTIATING_METHOD_BASED_PROXY, args));
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_INSTANTIATING_METHOD_BASED_PROXY);
        descriptorException.setInternalException(exception);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileInvokingAttributeMethod(DatabaseMapping mapping, Throwable exception) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_INVOKING_ATTRIBUTE_METHOD, args));
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_INVOKING_ATTRIBUTE_METHOD);
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileInvokingFieldToMethod(String methodName, DatabaseMapping mapping, Throwable exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_INVOKING_FIELD_TO_METHOD, args));
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_INVOKING_FIELD_TO_METHOD);
        descriptorException.setInternalException(exception);
        descriptorException.setMapping(mapping);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileInvokingRowExtractionMethod(AbstractRecord row, Method method, ClassDescriptor descriptor, Throwable exception) {
        Object[] args = { row, method };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_INVOKING_ROW_EXTRACTION_METHOD, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_INVOKING_ROW_EXTRACTION_METHOD);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileMethodInstantiation(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileMethodInstantiationOfFactory(String methodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { methodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION_OF_FACTORY, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_METHOD_INSTANTIATION_OF_FACTORY);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileObsoleteEventExecute(String eventMethodName, ClassDescriptor descriptor, Exception exception) {
        Object[] args = { eventMethodName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_OBSOLETE_EVENT_EXECUTION, args), descriptor, exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_OBSOLETE_EVENT_EXECUTION);
        return descriptorException;
    }

    public static DescriptorException targetInvocationWhileSettingValueThruMethodAccessor(String setMethodName, Object value, Throwable exception) {
        Object[] args = { setMethodName, String.valueOf(value), CR };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, TARGET_INVOCATION_WHILE_SETTING_VALUE_THRU_METHOD_ACESSOR, args));
        descriptorException.setInternalException(exception);
        descriptorException.setErrorCode(TARGET_INVOCATION_WHILE_SETTING_VALUE_THRU_METHOD_ACESSOR);
        return descriptorException;
    }

    // Bug 2618982
    public static DescriptorException unsupportedTypeForBidirectionalRelationshipMaintenance(DatabaseMapping mapping, org.eclipse.persistence.internal.queries.ContainerPolicy containerPolicy) {
        Object[] args = { mapping.getAttributeName(), containerPolicy };
        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, UNSUPPORTED_TYPE_FOR_BIDIRECTIONAL_RELATIONSHIP_MAINTENANCE, args), mapping);
        exception.setErrorCode(UNSUPPORTED_TYPE_FOR_BIDIRECTIONAL_RELATIONSHIP_MAINTENANCE);
        return exception;
    }

    public static DescriptorException valueHolderInstantiationMismatch(Object attributeValue, DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName(), attributeValue };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, VALUE_HOLDER_INSTANTIATION_MISMATCH, args), mapping);
        exception.setErrorCode(VALUE_HOLDER_INSTANTIATION_MISMATCH);
        return exception;
    }

    public static DescriptorException valueNotFoundInClassIndicatorMapping(ClassDescriptor parentDescriptor, ClassDescriptor descriptor) {
        Object[] args = { parentDescriptor };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, VALUE_NOT_FOUND_IN_CLASS_INDICATOR_MAPPING, args), descriptor);
        descriptorException.setErrorCode(VALUE_NOT_FOUND_IN_CLASS_INDICATOR_MAPPING);
        return descriptorException;
    }

    public static DescriptorException variableOneToOneMappingIsNotDefinedProperly(DatabaseMapping mapping, ClassDescriptor descriptor, String targetKeyName) {
        Object[] args = { targetKeyName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, VARIABLE_ONE_TO_ONE_MAPPING_IS_NOT_DEFINED, args), mapping);
        descriptorException.setErrorCode(VARIABLE_ONE_TO_ONE_MAPPING_IS_NOT_DEFINED);
        return descriptorException;
    }

    public static DescriptorException writeLockFieldInChildDescriptor(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, WRITE_LOCK_FIELD_IN_CHILD_DESCRIPTOR, args), descriptor);
        descriptorException.setErrorCode(WRITE_LOCK_FIELD_IN_CHILD_DESCRIPTOR);
        return descriptorException;
    }

    public static DescriptorException mappingForAttributeIsMissing(String attributeName, ClassDescriptor descriptor) {
        Object[] args = { attributeName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_MAPPING_FOR_ATTRIBUTENAME, args), descriptor);
        descriptorException.setErrorCode(NO_MAPPING_FOR_ATTRIBUTENAME);
        return descriptorException;
    }

    public static DescriptorException attributeMappingIsMissingForEntityBean(String attributeName, String beanName) {
        Object[] args = { attributeName, beanName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_MAPPING_FOR_ATTRIBUTENAME_IN_ENTITY_BEAN, args));
        descriptorException.setErrorCode(NO_MAPPING_FOR_ATTRIBUTENAME_IN_ENTITY_BEAN);
        return descriptorException;
    }

    public static DescriptorException returningPolicyFieldTypeConflict(String fieldName, String type1Name, String type2Name, ClassDescriptor descriptor) {
        Object[] args = { fieldName, type1Name, type2Name };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_FIELD_TYPE_CONFLICT, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_FIELD_TYPE_CONFLICT);
        return descriptorException;
    }

    public static DescriptorException returningPolicyFieldInsertConflict(String fieldName, ClassDescriptor descriptor) {
        Object[] args = { fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_FIELD_INSERT_CONFLICT, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_FIELD_INSERT_CONFLICT);
        return descriptorException;
    }

    public static DescriptorException returningPolicyAndDescriptorFieldTypeConflict(String fieldName, String returningPolicyFieldTypeName, String descriptorFieldTypeName, ClassDescriptor descriptor) {
        Object[] args = { fieldName, returningPolicyFieldTypeName, descriptorFieldTypeName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_AND_DESCRIPTOR_FIELD_TYPE_CONFLICT, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_AND_DESCRIPTOR_FIELD_TYPE_CONFLICT);
        return descriptorException;
    }

    public static DescriptorException returningPolicyUnmappedFieldTypeNotSet(String fieldName, ClassDescriptor descriptor) {
        Object[] args = { fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_UNMAPPED_FIELD_TYPE_NOT_SET, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_UNMAPPED_FIELD_TYPE_NOT_SET);
        return descriptorException;
    }

    public static DescriptorException returningPolicyMappedFieldTypeNotSet(String fieldName, ClassDescriptor descriptor) {
        Object[] args = { fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_MAPPED_FIELD_TYPE_NOT_SET, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_MAPPED_FIELD_TYPE_NOT_SET);
        return descriptorException;
    }

    public static DescriptorException returningPolicyMappingNotSupported(String fieldName, String mappingClassName, DatabaseMapping mapping) {
        Object[] args = { fieldName, mappingClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_MAPPING_NOT_SUPPORTED, args), mapping);
        descriptorException.setErrorCode(RETURNING_POLICY_MAPPING_NOT_SUPPORTED);
        return descriptorException;
    }

    public static DescriptorException returningPolicyFieldNotSupported(String fieldName, ClassDescriptor descriptor) {
        Object[] args = { fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, RETURNING_POLICY_FIELD_NOT_SUPPORTED, args), descriptor);
        descriptorException.setErrorCode(RETURNING_POLICY_FIELD_NOT_SUPPORTED);
        return descriptorException;
    }

    public static DescriptorException customQueryAndReturningPolicyFieldConflict(String queryTypeName, String fieldName, ClassDescriptor descriptor) {
        Object[] args = { queryTypeName, fieldName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CUSTOM_QUERY_AND_RETURNING_POLICY_CONFLICT, args), descriptor);
        descriptorException.setErrorCode(CUSTOM_QUERY_AND_RETURNING_POLICY_CONFLICT);
        return descriptorException;
    }

    public static DescriptorException noCustomQueryForReturningPolicy(String queryTypeName, String platformTypeName, ClassDescriptor descriptor) {
        Object[] args = { queryTypeName, platformTypeName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_CUSTOM_QUERY_FOR_RETURNING_POLICY, args), descriptor);
        descriptorException.setErrorCode(NO_CUSTOM_QUERY_FOR_RETURNING_POLICY);
        return descriptorException;
    }

    public static DescriptorException updateAllFieldsNotSet(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, UPDATE_ALL_FIELDS_NOT_SET, args), descriptor);
        descriptorException.setErrorCode(UPDATE_ALL_FIELDS_NOT_SET);
        return descriptorException;
    }

    public static DescriptorException invalidMappingType(DatabaseMapping mapping) {
        Object[] args = { mapping.getAttributeName() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_MAPPING_TYPE, args), mapping);
        descriptorException.setErrorCode(INVALID_MAPPING_TYPE);
        return descriptorException;
    }

    public static DescriptorException needToImplementChangeTracker(ClassDescriptor descriptor) {
        Object[] args = { descriptor.getJavaClass() };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NEED_TO_IMPLEMENT_CHANGETRACKER, args), descriptor);
        descriptorException.setErrorCode(NEED_TO_IMPLEMENT_CHANGETRACKER);
        return descriptorException;
    }

    public static DescriptorException needToImplementFetchGroupTracker(Class aClass, ClassDescriptor descriptor) {
        Object[] args = { aClass };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NEED_TO_IMPLEMENT_FETCHGROUPTRACKER, args), descriptor);
        descriptorException.setErrorCode(NEED_TO_IMPLEMENT_FETCHGROUPTRACKER);
        return descriptorException;
    }

    public static DescriptorException errorUsingPrimaryKey(Object primaryKey, ClassDescriptor descriptor, Exception underlying) {
        Object[] args = { primaryKey };

        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INTERNAL_ERROR_ACCESSING_PKFIELD, args), descriptor, underlying);
        exception.setErrorCode(INTERNAL_ERROR_ACCESSING_PKFIELD);
        return exception;
    }

    public static DescriptorException unitOfWorkIsolatedObjectsAccessedInSession(ClassDescriptor descriptor) {
        Object[] args = { };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, UNIT_OF_WORK_ISOLATED_OBJECTS_ACCESSED_IN_SESSION, args), descriptor);
        descriptorException.setErrorCode(UNIT_OF_WORK_ISOLATED_OBJECTS_ACCESSED_IN_SESSION);
        return descriptorException;
    }

    public static DescriptorException insertOrderConflictsWithMultipleTableForeignKeys(ClassDescriptor descriptor, DatabaseTable table1, DatabaseTable table2) {
        Object[] args = { table1, table2 };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSERT_ORDER_CONFLICTS_WITH_MULTIPLE_TABLE_FOREIGN_KEYS, args), descriptor);
        descriptorException.setErrorCode(INSERT_ORDER_CONFLICTS_WITH_MULTIPLE_TABLE_FOREIGN_KEYS);
        return descriptorException;
    }

    public static DescriptorException insertOrderCyclicalDependencyBetweenTwoTables(ClassDescriptor descriptor, DatabaseTable table1, DatabaseTable table2) {
        Object[] args = { table1, table2 };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_TWO_TABLES, args), descriptor);
        descriptorException.setErrorCode(INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_TWO_TABLES);
        return descriptorException;
    }

    public static DescriptorException insertOrderCyclicalDependencyBetweenThreeOrMoreTables(ClassDescriptor descriptor) {
        Object[] args = { };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_THREE_OR_MORE_TABLES, args), descriptor);
        descriptorException.setErrorCode(INSERT_ORDER_CYCLICAL_DEPENDENCY_BETWEEN_THREE_OR_MORE_TABLES);
        return descriptorException;
    }

    public static DescriptorException insertOrderChildBeforeParent(ClassDescriptor descriptor, DatabaseTable table1, DatabaseTable table2) {
        Object[] args = { table1, table2 };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INSERT_ORDER_CHILD_BEFORE_PARENT, args), descriptor);
        descriptorException.setErrorCode(INSERT_ORDER_CHILD_BEFORE_PARENT);
        return descriptorException;
    }

    public static DescriptorException cannotSetConverterForNonDirectMapping(ClassDescriptor descriptor, DatabaseMapping mapping, String keyConverterClassName) {
        Object[] args = { mapping, keyConverterClassName };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CANNOT_SET_CONVERTER_FOR_NON_DIRECT_MAPPING, args), descriptor);
        descriptorException.setErrorCode(CANNOT_SET_CONVERTER_FOR_NON_DIRECT_MAPPING);
        return descriptorException;
    }

    public static DescriptorException directKeyNotSet(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, DIRECT_KEY_NOT_SET, args), descriptor);
        descriptorException.setErrorCode(DIRECT_KEY_NOT_SET);
        return descriptorException;
    }

    public static DescriptorException listOrderFieldRequiersList(ClassDescriptor descriptor, DatabaseMapping mapping) {
        Object[] args = { mapping };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, LIST_ORDER_FIELD_REQUIRES_LIST, args), descriptor);
        descriptorException.setErrorCode(LIST_ORDER_FIELD_REQUIRES_LIST);
        return descriptorException;
    }

    public static DescriptorException listOrderFieldRequiersIndirectList(ClassDescriptor descriptor, DatabaseMapping mapping) {
        Object[] args = { mapping };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, LIST_ORDER_FIELD_REQUIRES_INDIRECT_LIST, args), descriptor);
        descriptorException.setErrorCode(LIST_ORDER_FIELD_REQUIRES_INDIRECT_LIST);
        return descriptorException;
    }

    public static DescriptorException listOrderFieldTableIsWrong(ClassDescriptor descriptor, DatabaseMapping mapping, DatabaseTable wrongTable, DatabaseTable correctTable) {
        Object[] args = { mapping, wrongTable, correctTable };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, LIST_ORDER_FIELD_TABLE_IS_WRONG, args), descriptor);
        descriptorException.setErrorCode(LIST_ORDER_FIELD_TABLE_IS_WRONG);
        return descriptorException;
    }

    public static DescriptorException multipleTargetForeignKeyTables(ClassDescriptor descriptor, DatabaseMapping mapping, Collection tables) {
        Object[] args = { mapping, tables };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MULTIPLE_TARGET_FOREIGN_KEY_TABLES, args), descriptor);
        descriptorException.setErrorCode(MULTIPLE_TARGET_FOREIGN_KEY_TABLES);
        return descriptorException;
    }

    public static DescriptorException oneToOneMappingConflict(ClassDescriptor descriptor, DatabaseMapping mapping) {
        Object[] args = { mapping };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, ONE_TO_ONE_MAPPING_CONFLICT, args), descriptor);
        descriptorException.setErrorCode(ONE_TO_ONE_MAPPING_CONFLICT);
        return descriptorException;
    }

    public static DescriptorException noRelationTableMechanism(DatabaseMapping mapping) {
        Object[] args = { mapping };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_RELATION_TABLE_MECHANISM, args), mapping);
        descriptorException.setErrorCode(NO_RELATION_TABLE_MECHANISM);
        return descriptorException;
    }


    public static DescriptorException cannotUseIdValueForCompositeId(ClassDescriptor descriptor) {
        Object[] args = {  };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID, args), descriptor);
        descriptorException.setErrorCode(CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID);
        return descriptorException;
    }

    public static DescriptorException invalidXpathForXMLDirectMapping(DatabaseMapping mapping) {
        Object[] args = {};

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, INVALID_XPATH_FOR_DIRECT_MAPPING, args), mapping);
        descriptorException.setErrorCode(INVALID_XPATH_FOR_DIRECT_MAPPING);
        return descriptorException;
    }

    public static DescriptorException missingPartitioningPolicy(String name, ClassDescriptor descriptor, DatabaseMapping mapping) {
        Object[] args = { name };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, MISSING_PARTITION_POLICY, args), descriptor);
        if (mapping != null) {
            descriptorException.setMapping(mapping);
        }
        descriptorException.setErrorCode(MISSING_PARTITION_POLICY);
        return descriptorException;
    }

    public static DescriptorException serializedObjectPolicyFieldNotSet(ClassDescriptor descriptor) {
        Object[] args = { };

        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, SERIALIZED_OBJECT_POLICY_FIELD_NOT_SET, args), descriptor);
        descriptorException.setErrorCode(SERIALIZED_OBJECT_POLICY_FIELD_NOT_SET);
        return descriptorException;
    }

    public static DescriptorException exceptionAccessingPrimaryKeyInstance(ClassDescriptor descriptor, Exception underlying) {
        Object[] args = { };
        DescriptorException exception = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, EXCEPTION_ACCESSING_PRIMARY_KEY_INSTANCE, args), descriptor, underlying);
        exception.setErrorCode(EXCEPTION_ACCESSING_PRIMARY_KEY_INSTANCE);
        return exception;
    }
}
