/*
 * 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;
    }
}
