/*
 * 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
//     dclarke Bug 244124: Enhanced weaving to support extended FetchGroup functionality
//     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.
//     19/04/2014-2.6 Lukas Jungmann
//       - 429992: JavaSE 8/ASM 5.0.1 support (EclipseLink silently ignores Entity classes with lambda expressions)
package org.eclipse.persistence.internal.jpa.weaving;

import java.util.Iterator;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.libraries.asm.ClassVisitor;
import org.eclipse.persistence.internal.libraries.asm.EclipseLinkClassVisitor;
import org.eclipse.persistence.internal.libraries.asm.FieldVisitor;
import org.eclipse.persistence.internal.libraries.asm.Label;
import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
import org.eclipse.persistence.internal.libraries.asm.Opcodes;
import org.eclipse.persistence.internal.libraries.asm.Type;

/**
 * INTERNAL: Weaves classes to allow them to support EclipseLink indirection.
 * Classes are weaved to add a variable of type ValueHolderInterface for each
 * attribute that uses indirection. In addition, access methods are added for
 * the new variable. Also, triggers the process of weaving the methods of the
 * class.
 *
 * @see org.eclipse.persistence.internal.jpa.weaving.MethodWeaver
 */

public class ClassWeaver extends EclipseLinkClassVisitor implements Opcodes {

    // PersistenceWeaved
    public static final String PERSISTENCE_WEAVED_SHORT_SIGNATURE = "org/eclipse/persistence/internal/weaving/PersistenceWeaved";

    // ValueHolders
    public static final String TW_LAZY_SHORT_SIGNATURE = "org/eclipse/persistence/internal/weaving/PersistenceWeavedLazy";
    public static final String VHI_CLASSNAME = "org.eclipse.persistence.indirection.WeavedAttributeValueHolderInterface";
    public static final String VH_SHORT_SIGNATURE = "org/eclipse/persistence/indirection/ValueHolder";
    public static final String VHI_SHORT_SIGNATURE = "org/eclipse/persistence/indirection/WeavedAttributeValueHolderInterface";
    public static final String VHI_SIGNATURE = "L" + VHI_SHORT_SIGNATURE + ";";

    // Change tracking
    public static final String TW_CT_SHORT_SIGNATURE = "org/eclipse/persistence/internal/weaving/PersistenceWeavedChangeTracking";
    public static final String PCL_SHORT_SIGNATURE = "java/beans/PropertyChangeListener";
    public static final String PCL_SIGNATURE = "L" + PCL_SHORT_SIGNATURE + ";";
    public static final String CT_SHORT_SIGNATURE = "org/eclipse/persistence/descriptors/changetracking/ChangeTracker";
    public static final String PCE_SHORT_SIGNATURE = "java/beans/PropertyChangeEvent";
    public static final String PCE_SIGNATURE = "L" + PCE_SHORT_SIGNATURE + ";";

    // PersistenceEntity
    public static final String PERSISTENCE_ENTITY_SHORT_SIGNATURE = "org/eclipse/persistence/internal/descriptors/PersistenceEntity";
    public static final String PERSISTENCE_OBJECT_SHORT_SIGNATURE = "org/eclipse/persistence/internal/descriptors/PersistenceObject";
    public static final String PERSISTENCE_OBJECT_SIGNATURE = "L" + PERSISTENCE_OBJECT_SHORT_SIGNATURE + ";";
    public static final String VECTOR_SIGNATURE = "Ljava/util/Vector;";
    public static final String OBJECT_SIGNATURE = "Ljava/lang/Object;";
    public static final String STRING_SIGNATURE = "Ljava/lang/String;";
    public static final String CACHEKEY_SIGNATURE = "Lorg/eclipse/persistence/internal/identitymaps/CacheKey;";

    // Fetch groups
    public static final String WEAVED_FETCHGROUPS_SHORT_SIGNATURE = "org/eclipse/persistence/internal/weaving/PersistenceWeavedFetchGroups";
    public static final String FETCHGROUP_TRACKER_SIGNATURE = "Lorg/eclipse/persistence/queries/FetchGroupTracker;";
    public static final String FETCHGROUP_TRACKER_SHORT_SIGNATURE = "org/eclipse/persistence/queries/FetchGroupTracker";
    public static final String FETCHGROUP_SHORT_SIGNATURE = "org/eclipse/persistence/queries/FetchGroup";
    public static final String FETCHGROUP_SIGNATURE = "Lorg/eclipse/persistence/queries/FetchGroup;";
    public static final String SESSION_SIGNATURE = "Lorg/eclipse/persistence/sessions/Session;";
    public static final String ENTITY_MANAGER_IMPL_SHORT_SIGNATURE = "org/eclipse/persistence/internal/jpa/EntityManagerImpl";
    public static final String PBOOLEAN_SIGNATURE = "Z";
    public static final String LONG_SIGNATURE = "J";

    // REST
    public static final String WEAVED_REST_LAZY_SHORT_SIGNATURE = "org/eclipse/persistence/internal/jpa/rs/weaving/PersistenceWeavedRest";
    public static final String LIST_RELATIONSHIP_INFO_SIGNATURE = "Ljava/util/List;";
    public static final String LIST_RELATIONSHIP_INFO_GENERIC_SIGNATURE = "Ljava/util/List<Lorg/eclipse/persistence/internal/jpa/rs/weaving/RelationshipInfo;>;";
    public static final String LINK_SIGNATURE = "Lorg/eclipse/persistence/internal/jpa/rs/metadata/model/Link;";
    public static final String ITEM_LINKS_SIGNATURE = "Lorg/eclipse/persistence/internal/jpa/rs/metadata/model/ItemLinks;";

    // Cloneable
    public static final String CLONEABLE_SHORT_SIGNATURE = "java/lang/Cloneable";

    // Transient
    public static final String JPA_TRANSIENT_DESCRIPTION = "Ljakarta/persistence/Transient;";
    public static final String XML_TRANSIENT_DESCRIPTION = "Ljakarta/xml/bind/annotation/XmlTransient;";

    public static final String PERSISTENCE_SET = Helper.PERSISTENCE_SET;
    public static final String PERSISTENCE_GET = Helper.PERSISTENCE_GET;

    // 323403: These constants are used to search for missing weaved functions -
    // a copy is in the foundation project under internal.Helper
    public static final String PERSISTENCE_FIELDNAME_PREFIX = "_persistence_";
    public static final String PERSISTENCE_FIELDNAME_POSTFIX = "_vh";

    public static final String VIRTUAL_GETTER_SIGNATURE = "(" + ClassWeaver.STRING_SIGNATURE + ")" + ClassWeaver.OBJECT_SIGNATURE;
    public static final String VIRTUAL_SETTER_SIGNATURE = "(" + ClassWeaver.STRING_SIGNATURE + ClassWeaver.OBJECT_SIGNATURE + ")" + ClassWeaver.OBJECT_SIGNATURE;

    /** Store if JAXB is on the classpath, true in Java SE 6 - 8, maybe true from 9 */
    private static Boolean isJAXBOnPath = null;

    /**
     * Stores information on the class gathered from the temp class loader and
     * descriptor.
     */
    protected ClassDetails classDetails;

    // Keep track of what was weaved.
    protected boolean alreadyWeaved = false;
    public boolean weaved = false;
    public boolean weavedLazy = false;
    public boolean weavedPersistenceEntity = false;
    public boolean weavedChangeTracker = false;
    public boolean weavedFetchGroups = false;
    public boolean weavedRest = false;

    /**
     * Used for primitive conversion. Returns the name of the class that wraps a
     * given type.
     */
    public static String wrapperFor(int sort) {
        switch (sort) {
            case Type.BOOLEAN:
                return "java/lang/Boolean";
            case Type.BYTE:
                return "java/lang/Byte";
            case Type.CHAR:
                return "java/lang/Character";
            case Type.SHORT:
                return "java/lang/Short";
            case Type.INT:
                return "java/lang/Integer";
            case Type.FLOAT:
                return "java/lang/Float";
            case Type.LONG:
                return "java/lang/Long";
            case Type.DOUBLE:
                return "java/lang/Double";
        }
        return null;
    }

    /**
     * Used for primitive conversion. Returns the name conversion method for the
     * given type.
     */
    public static void unwrapPrimitive(AttributeDetails attribute, MethodVisitor visitor) {
        String wrapper = wrapperFor(attribute.getReferenceClassType().getSort());
        switch (attribute.getReferenceClassType().getSort()) {
            case Type.BOOLEAN:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "booleanValue", "()Z", false);
                return;
            case Type.BYTE:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "byteValue", "()B", false);
                return;
            case Type.CHAR:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "charValue", "()C", false);
                return;
            case Type.SHORT:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "shortValue", "()S", false);
                return;
            case Type.INT:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "intValue", "()I", false);
                return;
            case Type.FLOAT:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "floatValue", "()F", false);
                return;
            case Type.LONG:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "longValue", "()J", false);
                return;
            case Type.DOUBLE:
                visitor.visitMethodInsn(INVOKEVIRTUAL, wrapper, "doubleValue", "()D", false);
                return;
        }
    }

    /**
     * Return the get method name weaved for a value-holder attribute.
     */
    public static String getWeavedValueHolderGetMethodName(String attributeName) {
        return Helper.getWeavedValueHolderGetMethodName(attributeName);
    }

    /**
     * Return the set method name weaved for a value-holder attribute.
     */
    public static String getWeavedValueHolderSetMethodName(String attributeName) {
        return Helper.getWeavedValueHolderSetMethodName(attributeName);
    }

    /**
     * Return if the JAXB classes are on the classpath (if they are the
     * XmlTransient annotation is added).
     */
    public static boolean isJAXBOnPath() {
        if (isJAXBOnPath == null) {
            try {
                Class.forName("jakarta.xml.bind.annotation.XmlTransient");
                isJAXBOnPath = true;
            } catch (Exception notThere) {
                isJAXBOnPath = false;
            }
        }
        return isJAXBOnPath;
    }

    public ClassWeaver(ClassVisitor classWriter, ClassDetails classDetails) {
        super(classWriter);
        this.classDetails = classDetails;
    }

    /**
     * Add a variable of type ValueHolderInterface to the class. When this
     * method has been run, the class will contain a variable declaration
     * similar to the following:
     *
     * private ValueHolderInterface _persistence_variableName_vh;
     */
    public void addValueHolder(AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();
        FieldVisitor fv = cv.visitField(ACC_PROTECTED, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE, null, null);

        // only mark @Transient if this is property access. Otherwise, the
        // @Transient annotation could mistakenly
        // cause the class to use attribute access.
        if (attributeDetails.getGetterMethodName() == null || attributeDetails.getGetterMethodName().equals("") || attributeDetails.weaveTransientFieldValueHolders()) {
            fv.visitAnnotation(JPA_TRANSIENT_DESCRIPTION, true).visitEnd();
            if (isJAXBOnPath()) {
                fv.visitAnnotation(XML_TRANSIENT_DESCRIPTION, true).visitEnd();
            }
        }
        fv.visitEnd();
    }

    /**
     * Add a variable of type PropertyChangeListener to the class. When this
     * method has been run, the class will contain a variable declaration
     * similar to the following
     *
     * private transient _persistence_listener;
     */
    public void addPropertyChangeListener(boolean attributeAccess) {
        cv.visitField(ACC_PROTECTED + ACC_TRANSIENT, "_persistence_listener", PCL_SIGNATURE, null, null);
    }

    /**
     * Add the implementation of the changeTracker_getPropertyChangeListener
     * method to the class. The result is a method that looks as follows:
     *
     * public PropertyChangeListener _persistence_getPropertyChangeListener() {
     * return _persistence_listener; }
     */
    public void addGetPropertyChangeListener(ClassDetails classDetails) {
        MethodVisitor cv_getPCL = cv.visitMethod(ACC_PUBLIC, "_persistence_getPropertyChangeListener", "()" + PCL_SIGNATURE, null, null);
        cv_getPCL.visitVarInsn(ALOAD, 0);
        cv_getPCL.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_listener", PCL_SIGNATURE);
        cv_getPCL.visitInsn(ARETURN);
        cv_getPCL.visitMaxs(0, 0);
    }

    /**
     * Add the implementation of the changeTracker_setPropertyChangeListener
     * method to the class. The result is a method that looks as follows:
     *
     * public void _persistence_setPropertyChangeListener(PropertyChangeListener
     * propertychangelistener){ _persistence_listener = propertychangelistener;
     * }
     */
    public void addSetPropertyChangeListener(ClassDetails classDetails) {
        MethodVisitor cv_setPCL = cv.visitMethod(ACC_PUBLIC, "_persistence_setPropertyChangeListener", "(" + PCL_SIGNATURE + ")V", null, null);
        cv_setPCL.visitVarInsn(ALOAD, 0);
        cv_setPCL.visitVarInsn(ALOAD, 1);
        cv_setPCL.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_listener", PCL_SIGNATURE);
        cv_setPCL.visitInsn(RETURN);
        cv_setPCL.visitMaxs(0, 0);
    }

    /**
     * Add a method to track property changes. The method will look as follows:
     *
     * public void _toplink_propertyChange(String s, Object obj, Object obj1){
     * if(_persistence_listener != null {@literal &&} obj != obj1){
     * _persistence_listener.propertyChange(new PropertyChangeEvent(this, s,
     * obj, obj1)); } }
     */
    public void addPropertyChange(ClassDetails classDetails) {
        // create the _toplink_propertyChange() method
        MethodVisitor cv_addPC = cv.visitMethod(ACC_PUBLIC, "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", null, null);

        // if (_toplink_Listener != null)
        cv_addPC.visitVarInsn(ALOAD, 0);
        cv_addPC.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_listener", PCL_SIGNATURE);
        Label l0 = new Label();
        cv_addPC.visitJumpInsn(IFNULL, l0);

        // if (obj != obj1)
        cv_addPC.visitVarInsn(ALOAD, 2);
        cv_addPC.visitVarInsn(ALOAD, 3);
        cv_addPC.visitJumpInsn(IF_ACMPEQ, l0);

        // _toplink_listener.propertyChange(...);
        cv_addPC.visitVarInsn(ALOAD, 0);
        cv_addPC.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_listener", PCL_SIGNATURE);
        cv_addPC.visitTypeInsn(NEW, PCE_SHORT_SIGNATURE);
        cv_addPC.visitInsn(DUP);

        // new PropertyChangeEvent(this, s, obj, obj1)
        cv_addPC.visitVarInsn(ALOAD, 0);
        cv_addPC.visitVarInsn(ALOAD, 1);
        cv_addPC.visitVarInsn(ALOAD, 2);
        cv_addPC.visitVarInsn(ALOAD, 3);
        cv_addPC.visitMethodInsn(INVOKESPECIAL, PCE_SHORT_SIGNATURE, "<init>", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
        cv_addPC.visitMethodInsn(INVOKEINTERFACE, PCL_SHORT_SIGNATURE, "propertyChange", "(" + PCE_SIGNATURE + ")V", true);

        // }
        cv_addPC.visitLabel(l0);

        cv_addPC.visitInsn(RETURN);
        cv_addPC.visitMaxs(0, 0);
    }

    /**
     * Add a method that allows us to lazily initialize a valueholder we have
     * woven in This allows us to avoid initializing valueholders in the
     * constructor.
     *
     * protected void _persistence_initialize_attribute_vh(){
     * if(_persistence_attribute_vh == null){ _persistence_attribute_vh = new
     * ValueHolder(this.attribute); // or new ValueHolder() if property access.
     * _persistence_attribute_vh.setIsNewlyWeavedValueHolder(true); } }
     */
    public void addInitializerForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();
        String className = classDetails.getClassName();

        // Create a getter method for the new valueholder
        // protected void _persistence_initialize_attribute_vh(){
        MethodVisitor cv_init_VH = cv.visitMethod(ACC_PROTECTED, "_persistence_initialize_" + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "()V", null, null);

        // if(_persistence_attribute_vh == null){
        cv_init_VH.visitVarInsn(ALOAD, 0);
        cv_init_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        Label l0 = new Label();
        cv_init_VH.visitJumpInsn(IFNONNULL, l0);

        // _persistence_attribute_vh = new ValueHolder(this.attribute);
        cv_init_VH.visitVarInsn(ALOAD, 0);
        cv_init_VH.visitTypeInsn(NEW, VH_SHORT_SIGNATURE);
        cv_init_VH.visitInsn(DUP);
        if (attributeDetails.hasField()) {
            cv_init_VH.visitVarInsn(ALOAD, 0);
            cv_init_VH.visitFieldInsn(GETFIELD, className, attribute, attributeDetails.getReferenceClassType().getDescriptor());
            cv_init_VH.visitMethodInsn(INVOKESPECIAL, VH_SHORT_SIGNATURE, "<init>", "(Ljava/lang/Object;)V", false);
        } else {
            cv_init_VH.visitMethodInsn(INVOKESPECIAL, VH_SHORT_SIGNATURE, "<init>", "()V", false);
        }
        cv_init_VH.visitFieldInsn(PUTFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);

        // _persistence_attribute_vh.setIsNewlyWeavedValueHolder(true);
        cv_init_VH.visitVarInsn(ALOAD, 0);
        cv_init_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        cv_init_VH.visitInsn(ICONST_1);
        cv_init_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "setIsNewlyWeavedValueHolder", "(Z)V", true);

        // }
        cv_init_VH.visitLabel(l0);

        cv_init_VH.visitInsn(RETURN);
        cv_init_VH.visitMaxs(0, 0);
    }

    /**
     * Add a get method for the newly added valueholder. Adds a method of the
     * following form:
     *
     * public WeavedAttributeValueHolderInterface _persistence_getfoo_vh(){
     * _persistence_initialize_attributeName_vh(); if
     * (_persistence_vh.isCoordinatedWithProperty() ||
     * _persistence_foo_vh.isNewlyWeavedValueHolder()){ EntityC object =
     * (EntityC)getFoo(); if (object != _persistence_foo_vh.getValue()){
     * setFoo(object); } } return _persistence_foo_vh; }
     */
    public void addGetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();
        String className = classDetails.getClassName();
        // Create a getter method for the new valueholder
        MethodVisitor cv_get_VH = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_GET + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "()" + VHI_SIGNATURE, null, null);

        // _persistence_initialize_attributeName_vh();
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);

        // if (_toplink_foo_vh.isCoordinatedWithProperty() ||
        // _toplink_foo_vh.isNewlyWeavedValueHolder()){
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isCoordinatedWithProperty", "()Z", true);
        Label l0 = new Label();
        cv_get_VH.visitJumpInsn(IFNE, l0);
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isNewlyWeavedValueHolder", "()Z", true);
        Label l1 = new Label();
        cv_get_VH.visitJumpInsn(IFEQ, l1);
        cv_get_VH.visitLabel(l0);
        cv_get_VH.visitVarInsn(ALOAD, 0);

        // EntityC object = (EntityC)getFoo();
        if (attributeDetails.getGetterMethodName() != null) {
            cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), attributeDetails.getGetterMethodName(), "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
            cv_get_VH.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
        } else {
            cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), PERSISTENCE_GET + attributeDetails.attributeName, "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
        }
        cv_get_VH.visitVarInsn(ASTORE, 1);

        // if (object != _toplink_foo_vh.getValue()){
        cv_get_VH.visitVarInsn(ALOAD, 1);
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
        cv_get_VH.visitJumpInsn(IF_ACMPEQ, l1);

        // setFoo(object);
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitVarInsn(ALOAD, 1);
        if (attributeDetails.getSetterMethodName() != null) {
            cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
        } else {
            cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), PERSISTENCE_SET + attributeDetails.getAttributeName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
        }

        // }
        cv_get_VH.visitLabel(l1);

        // return _toplink_foo_vh;
        cv_get_VH.visitVarInsn(ALOAD, 0);
        cv_get_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
        cv_get_VH.visitInsn(ARETURN);

        cv_get_VH.visitMaxs(0, 0);
    }

    /**
     * Add a set method for the newly added ValueHolder. Adds a method of this
     * form:
     *
     * public void _persistence_setfoo_vh(WeavedAttributeValueHolderInterface
     * valueholderinterface){ _persistence_foo_vh = valueholderinterface; if
     * (valueholderinterface.isInstantiated()){ Object object = getFoo(); Object
     * value = valueholderinterface.getValue(); if (object != value){
     * setFoo((EntityC)value); } } else { foo = null; } }
     */
    public void addSetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();
        String className = classDetails.getClassName();
        // create a setter method for the new valueholder
        MethodVisitor cv_set_value = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_SET + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "(" + VHI_SIGNATURE + ")V", null, null);

        // _toplink_foo_vh = valueholderinterface;
        cv_set_value.visitVarInsn(ALOAD, 0);
        cv_set_value.visitVarInsn(ALOAD, 1);
        cv_set_value.visitFieldInsn(PUTFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);

        // if (valueholderinterface.isInstantiated()){
        cv_set_value.visitVarInsn(ALOAD, 1);
        cv_set_value.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isInstantiated", "()Z", true);
        Label l0 = new Label();
        cv_set_value.visitJumpInsn(IFEQ, l0);

        // Object object = getFoo();
        cv_set_value.visitVarInsn(ALOAD, 0);
        if (attributeDetails.getGetterMethodName() != null) {
            cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, attributeDetails.getGetterMethodName(), "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
        } else {
            cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, PERSISTENCE_GET + attributeDetails.attributeName, "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
        }
        cv_set_value.visitVarInsn(ASTORE, 2);

        // Object value = valueholderinterface.getValue();
        cv_set_value.visitVarInsn(ALOAD, 1);
        cv_set_value.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
        cv_set_value.visitVarInsn(ASTORE, 3);

        // if (object != value){
        cv_set_value.visitVarInsn(ALOAD, 2);
        cv_set_value.visitVarInsn(ALOAD, 3);
        if (attributeDetails.getSetterMethodName() != null) {
            cv_set_value.visitJumpInsn(IF_ACMPEQ, l0);
            // setFoo((EntityC)value);
            cv_set_value.visitVarInsn(ALOAD, 0);
            cv_set_value.visitVarInsn(ALOAD, 3);
            cv_set_value.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
            cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
            //}
            cv_set_value.visitLabel(l0);
        } else {
            Label l1 = new Label();
            cv_set_value.visitJumpInsn(IF_ACMPEQ, l1);
            // _persistence_setFoo((EntityC)value);
            cv_set_value.visitVarInsn(ALOAD, 0);
            cv_set_value.visitVarInsn(ALOAD, 3);
            cv_set_value.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
            cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, PERSISTENCE_SET + attributeDetails.getAttributeName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
            // }
            cv_set_value.visitLabel(l1);
            cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
            Label l2 = new Label();
            cv_set_value.visitJumpInsn(GOTO, l2);
            // }
            cv_set_value.visitLabel(l0);
            // else {
            cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
            // foo = null;
            cv_set_value.visitVarInsn(ALOAD, 0);
            cv_set_value.visitInsn(ACONST_NULL);
            cv_set_value.visitFieldInsn(PUTFIELD, className, attributeDetails.attributeName, attributeDetails.getReferenceClassType().getDescriptor());
            //}
            cv_set_value.visitLabel(l2);
            cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
        }

        cv_set_value.visitInsn(RETURN);
        cv_set_value.visitMaxs(0, 0);
    }

    /**
     * Adds a convenience method used to replace a PUTFIELD when field access is
     * used. The method follows the following form:
     *
     * public void _persistence_set_variableName((VariableClas) argument) {
     * _persistence_checkFetchedForSet("variableName");
     * _persistence_initialize_variableName_vh();
     * _persistence_propertyChange("variableName", this.variableName, argument);
     * // if change tracking enabled, wrapping primitives, i.e. Long.valueOf(item)
     * this.variableName = argument;
     * _persistence_variableName_vh.setValue(variableName); // if lazy enabled }
     */
    public void addSetterMethodForFieldAccess(ClassDetails classDetails, AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();

        // create _persistence_set_variableName
        MethodVisitor cv_set = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_SET + attribute, "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", null, null);

        // Get the opcode for the load instruction. This may be different
        // depending on the type
        int opcode = attributeDetails.getReferenceClassType().getOpcode(ILOAD);

        if (classDetails.shouldWeaveFetchGroups()) {
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitLdcInsn(attribute);
            // _persistence_checkFetchedForSet("variableName");
            cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", false);
        }

        if (classDetails.shouldWeaveChangeTracking()) {
            if (attributeDetails.weaveValueHolders()) {
                // _persistence_initialize_variableName_vh();
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);

                // _persistenc_variableName_vh.getValue();
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
                cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);

                // Add the cast:
                // (<VariableClass>)_persistenc_variableName_vh.getValue()
                cv_set.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));

                // add the assignment: this.variableName =
                // (<VariableClass>)_persistenc_variableName_vh.getValue();
                cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
            }

            // load the string attribute name as the first argument of the
            // property change call
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitLdcInsn(attribute);

            // if the attribute is a primitive, wrap it
            // e.g. if it is an integer: Integer.valueOf(attribute)
            // This is the first part of the wrapping
            String wrapper = ClassWeaver.wrapperFor(attributeDetails.getReferenceClassType().getSort());
            if (wrapper != null) {
                cv_set.visitTypeInsn(NEW, wrapper);
                cv_set.visitInsn(DUP);
            }

            // load the method argument
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());

            if (wrapper != null) {
                // invoke the constructor for wrapping
                // e.g. Integer.valueOf(variableName)
                cv_set.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", false);

                // wrap the method argument
                // e.g. Integer.valueOf(argument)
                cv_set.visitTypeInsn(NEW, wrapper);
                cv_set.visitInsn(DUP);
                cv_set.visitVarInsn(opcode, 1);
                cv_set.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", false);
            } else {
                // if we are not wrapping the argument, just load it
                cv_set.visitVarInsn(ALOAD, 1);
            }
            // _persistence_propertyChange("variableName", variableName,
            // argument);
            cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
        } else {
            if (attributeDetails.weaveValueHolders()) {
                // _persistence_initialize_variableName_vh();
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);

                // _persistenc_variableName_vh.getValue();
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
                cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);

                // Add the cast:
                // (<VariableClass>)_persistenc_variableName_vh.getValue()
                cv_set.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));

                // add the assignment: this.variableName =
                // (<VariableClass>)_persistenc_variableName_vh.getValue();
                cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
            }
        }

        // Must set variable after raising change event, so event has old and
        // new value.
        // variableName = argument
        cv_set.visitVarInsn(ALOAD, 0);
        cv_set.visitVarInsn(opcode, 1);
        cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());

        if (attributeDetails.weaveValueHolders()) {
            // _persistence_variableName_vh.setValue(argument);
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
            cv_set.visitVarInsn(ALOAD, 1);
            cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "setValue", "(Ljava/lang/Object;)V", true);
        }

        cv_set.visitInsn(RETURN);
        cv_set.visitMaxs(0, 0);
    }

    /**
     * Adds a convenience method used to replace a GETFIELD when field access is
     * used. The method follows the following form:
     *
     * public (VariableClass) _persistence_get_variableName() {
     * _persistence_checkFetched("variableName");
     * _persistence_initialize_variableName_vh(); this.variableName =
     * ((VariableClass))_persistence_variableName_vh.getValue(); return
     * this.variableName; }
     */
    public void addGetterMethodForFieldAccess(ClassDetails classDetails, AttributeDetails attributeDetails) {
        String attribute = attributeDetails.getAttributeName();

        // create the _persistenc_getvariableName method
        MethodVisitor cv_get = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_GET + attribute, "()" + attributeDetails.getReferenceClassType().getDescriptor(), null, null);

        if (classDetails.shouldWeaveFetchGroups()) {
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitLdcInsn(attribute);
            // _persistence_checkFetched("variableName");
            cv_get.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_checkFetched", "(Ljava/lang/String;)V", false);
        }

        if (attributeDetails.weaveValueHolders()) {
            // _persistence_initialize_variableName_vh();
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);

            // _persistenc_variableName_vh.getValue();
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
            cv_get.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);

            // Add the cast:
            // (<VariableClass>)_persistenc_variableName_vh.getValue()
            cv_get.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));

            // add the assignment: this.variableName =
            // (<VariableClass>)_persistenc_variableName_vh.getValue();
            cv_get.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
        }

        // return this.variableName;
        cv_get.visitVarInsn(ALOAD, 0);
        cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
        // Get the opcode for the return insturction. This may be different
        // depending on the type.
        int opcode = attributeDetails.getReferenceClassType().getOpcode(IRETURN);
        cv_get.visitInsn(opcode);
        cv_get.visitMaxs(0, 0);
    }

    /**
     * Add a variable of type Object to the class. When this method has been
     * run, the class will contain a variable declarations similar to the
     * following:
     *
     * private Object _persistence_primaryKey;
     */
    public void addPersistenceEntityVariables() {
        cv.visitField(ACC_PROTECTED + ACC_TRANSIENT, "_persistence_primaryKey", OBJECT_SIGNATURE, null, null);
        cv.visitField(ACC_PROTECTED + ACC_TRANSIENT, "_persistence_cacheKey", CACHEKEY_SIGNATURE, null, null);
    }

    /**
     * Add an internal post clone method. This will clone value holders to avoid
     * change original/clone to effect the other.
     *
     * public Object _persistence_post_clone() { this._attribute_vh =
     * this._attribute_vh.clone(); ... this._persistence_listener = null; return
     * this; }
     */
    public void addPersistencePostClone(ClassDetails classDetails) {
        // create the _persistence_post_clone() method
        MethodVisitor cv_clone = cv.visitMethod(ACC_PUBLIC, "_persistence_post_clone", "()Ljava/lang/Object;", null, null);

        // if there is a weaved superclass, it will implement
        // _persistence_post_clone. Call that method
        // super._persistence_post_clone()
        if (classDetails.getSuperClassDetails() != null && classDetails.getSuperClassDetails().shouldWeaveInternal()) {
            cv_clone.visitVarInsn(ALOAD, 0);
            cv_clone.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "_persistence_post_clone", "()Ljava/lang/Object;", false);
        }

        if (classDetails.shouldWeaveValueHolders()) {
            for (Iterator<AttributeDetails> iterator = classDetails.getAttributesMap().values().iterator(); iterator.hasNext();) {
                AttributeDetails attributeDetails = iterator.next();
                if (attributeDetails.weaveValueHolders()) { // &&
                                                            // !attributeDetails.isAttributeOnSuperClass())
                                                            // {
                    // clone._attribute_vh = this._attribute_vh.clone();
                    cv_clone.visitVarInsn(ALOAD, 0);
                    cv_clone.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
                    Label label = new Label();
                    cv_clone.visitJumpInsn(IFNULL, label);
                    cv_clone.visitVarInsn(ALOAD, 0);
                    cv_clone.visitVarInsn(ALOAD, 0);
                    cv_clone.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
                    cv_clone.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "clone", "()Ljava/lang/Object;", true);
                    cv_clone.visitTypeInsn(CHECKCAST, ClassWeaver.VHI_SHORT_SIGNATURE);
                    cv_clone.visitFieldInsn(PUTFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
                    cv_clone.visitLabel(label);
                }
            }
        }
        if (classDetails.shouldWeaveChangeTracking()) {
            // clone._persistence_listener = null;
            cv_clone.visitVarInsn(ALOAD, 0);
            cv_clone.visitInsn(ACONST_NULL);
            cv_clone.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_listener", PCL_SIGNATURE);
        }
        if (classDetails.shouldWeaveFetchGroups()) {
            // clone._persistence_fetchGroup = null;
            // clone._persistence_session = null;
            cv_clone.visitVarInsn(ALOAD, 0);
            cv_clone.visitInsn(ACONST_NULL);
            cv_clone.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_fetchGroup", FETCHGROUP_SIGNATURE);
            cv_clone.visitVarInsn(ALOAD, 0);
            cv_clone.visitInsn(ACONST_NULL);
            cv_clone.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_session", SESSION_SIGNATURE);
        }

        if (!classDetails.isEmbedable()) {
            // clone._persistence_primaryKey = null;
            cv_clone.visitVarInsn(ALOAD, 0);
            cv_clone.visitInsn(ACONST_NULL);
            cv_clone.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_primaryKey", OBJECT_SIGNATURE);
        }

        // return clone;
        cv_clone.visitVarInsn(ALOAD, 0);
        cv_clone.visitInsn(ARETURN);
        cv_clone.visitMaxs(0, 0);
    }

    public void addPersistenceRestMethods(ClassDetails classDetails) {
        // public List<RelationshipInfo> _persistence_getRelationships() {
        //   return this._persistence_relationshipInfo;
        // }
        MethodVisitor cv_getPKVector = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "getRelationships", "()" + LIST_RELATIONSHIP_INFO_SIGNATURE, "()" + LIST_RELATIONSHIP_INFO_GENERIC_SIGNATURE, null);
        cv_getPKVector.visitVarInsn(ALOAD, 0);
        cv_getPKVector.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_relationshipInfo", LIST_RELATIONSHIP_INFO_SIGNATURE);
        cv_getPKVector.visitInsn(ARETURN);
        cv_getPKVector.visitMaxs(0, 0);

        // public void _persistence_setRelationships(List<RelationshipInfo> paramList) {
        //   this._persistence_relationshipInfo = paramList;
        // }
        MethodVisitor cv_setPKVector = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "setRelationships", "(" + LIST_RELATIONSHIP_INFO_SIGNATURE + ")V", "(" + LIST_RELATIONSHIP_INFO_GENERIC_SIGNATURE + ")V", null);
        cv_setPKVector.visitVarInsn(ALOAD, 0);
        cv_setPKVector.visitVarInsn(ALOAD, 1);
        cv_setPKVector.visitFieldInsn(PUTFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + "relationshipInfo", LIST_RELATIONSHIP_INFO_SIGNATURE);
        cv_setPKVector.visitInsn(RETURN);
        cv_setPKVector.visitMaxs(0, 0);

        // public Link _persistence_getHref() {
        //   return this._persistence_href;
        // }
        MethodVisitor cv_getHref = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "getHref", "()" + LINK_SIGNATURE, null, null);
        cv_getHref.visitVarInsn(ALOAD, 0);
        cv_getHref.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + "href", LINK_SIGNATURE);
        cv_getHref.visitInsn(ARETURN);
        cv_getHref.visitMaxs(0, 0);

        // public void _persistence_setHref(Link paramLink)
        //   this._persistence_href = paramLink;
        // }
        MethodVisitor cv_setHref = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "setHref", "(" + LINK_SIGNATURE + ")V", null, null);
        cv_setHref.visitVarInsn(ALOAD, 0);
        cv_setHref.visitVarInsn(ALOAD, 1);
        cv_setHref.visitFieldInsn(PUTFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + "href", LINK_SIGNATURE);
        cv_setHref.visitInsn(RETURN);
        cv_setHref.visitMaxs(0, 0);

        // public ItemLinks _persistence_getLinks() {
        //   return this._persistence_links;
        // }
        MethodVisitor cv_getLinks = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "getLinks", "()" + ITEM_LINKS_SIGNATURE, null, null);
        cv_getLinks.visitVarInsn(ALOAD, 0);
        cv_getLinks.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + "links", ITEM_LINKS_SIGNATURE);
        cv_getLinks.visitInsn(ARETURN);
        cv_getLinks.visitMaxs(0, 0);

        // public void _persistence_setLinks(ItemLinks paramItemLinks) {
        //   this._persistence_links = paramItemLinks;
        // }
        MethodVisitor cv_setLinks = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_FIELDNAME_PREFIX + "setLinks", "(" + ITEM_LINKS_SIGNATURE + ")V", null, null);
        cv_setLinks.visitVarInsn(ALOAD, 0);
        cv_setLinks.visitVarInsn(ALOAD, 1);
        cv_setLinks.visitFieldInsn(PUTFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + "links", ITEM_LINKS_SIGNATURE);
        cv_setLinks.visitInsn(RETURN);
        cv_setLinks.visitMaxs(0, 0);

    }

    public void addPersistenceRestVariables() {
        // protected transient List<RelationshipInfo> _persistence_relationshipInfo;
        cv.visitField(ACC_PROTECTED | ACC_TRANSIENT, PERSISTENCE_FIELDNAME_PREFIX + "relationshipInfo", LIST_RELATIONSHIP_INFO_SIGNATURE, LIST_RELATIONSHIP_INFO_GENERIC_SIGNATURE, null);
        // protected transient Link _persistence_href;
        cv.visitField(ACC_PROTECTED | ACC_TRANSIENT, PERSISTENCE_FIELDNAME_PREFIX + "href", LINK_SIGNATURE, null, null);
        // protected transient ItemLinks _persistence_links;
        cv.visitField(ACC_PROTECTED | ACC_TRANSIENT, PERSISTENCE_FIELDNAME_PREFIX + "links", ITEM_LINKS_SIGNATURE, null, null);
    }

    /**
     * Add an internal shallow clone method. This can be used to optimize uow
     * cloning.
     *
     * public Object _persistence_shallow_clone() { return super.clone(); }
     */
    public void addShallowClone(ClassDetails classDetails) {
        // create the _persistence_shallow_clone() method
        MethodVisitor cv_clone = cv.visitMethod(ACC_PUBLIC, "_persistence_shallow_clone", "()Ljava/lang/Object;", null, null);

        // return super.clone();
        cv_clone.visitVarInsn(ALOAD, 0);
        cv_clone.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "clone", "()Ljava/lang/Object;", false);

        cv_clone.visitInsn(ARETURN);
        cv_clone.visitMaxs(0, 0);
    }

    /**
     * Add an internal empty constructor, and new method. This is used to avoid
     * unnecessary initialization and avoid reflection.
     *
     * public void _persistence_new(PersistenceObject factory) { return new
     * ClassType(factory); }
     *
     * public ClassType(PersistenceObject factory) { super(); }
     */
    public void addPersistenceNew(ClassDetails classDetails) {
        // create the _persistence_new() method
        MethodVisitor cv_new = cv.visitMethod(ACC_PUBLIC, "_persistence_new", "(" + PERSISTENCE_OBJECT_SIGNATURE + ")Ljava/lang/Object;", null, null);

        // return new ClassType(factory);
        cv_new.visitTypeInsn(NEW, classDetails.getClassName());
        cv_new.visitInsn(DUP);
        if (!classDetails.canWeaveConstructorOptimization()) {
            cv_new.visitMethodInsn(INVOKESPECIAL, classDetails.getClassName(), "<init>", "()V", false);
            cv_new.visitInsn(ARETURN);
            cv_new.visitMaxs(0, 0);
            return;
        } else {
            cv_new.visitVarInsn(ALOAD, 1);
            cv_new.visitMethodInsn(INVOKESPECIAL, classDetails.getClassName(), "<init>", "(" + PERSISTENCE_OBJECT_SIGNATURE + ")V", false);
        }
        cv_new.visitInsn(ARETURN);
        cv_new.visitMaxs(0, 0);

        // create the ClassType() method
        MethodVisitor cv_constructor = cv.visitMethod(ACC_PUBLIC, "<init>", "(" + PERSISTENCE_OBJECT_SIGNATURE + ")V", null, null);

        cv_constructor.visitVarInsn(ALOAD, 0);
        if (classDetails.getSuperClassDetails() == null) {
            // super();
            cv_constructor.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "<init>", "()V", false);
        } else {
            // super(factory);
            cv_constructor.visitVarInsn(ALOAD, 1);
            cv_constructor.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "<init>", "(" + PERSISTENCE_OBJECT_SIGNATURE + ")V", false);
        }
        cv_constructor.visitInsn(RETURN);
        cv_constructor.visitMaxs(0, 0);
    }

    /**
     * Add an internal generic get and set method. This is used to avoid
     * reflection.
     *
     * public Object _persistence_get(String attribute) { if (attribute ==
     * "address") { return this.address; } if (attribute == "city") { return
     * this.city; } return null; }
     *
     * public void _persistence_set(int index, Object value) { if (attribute ==
     * "address") { this.address = (String)value; } else if (attribute ==
     * "city") { this.city = (String)city; } }
     */
    public void addPersistenceGetSet(ClassDetails classDetails) {
        // create the _persistence_get() method
        MethodVisitor cv_get = cv.visitMethod(ACC_PUBLIC, "_persistence_get", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);

        Label label = null;
        for (AttributeDetails attributeDetails : classDetails.getAttributesMap().values()) {
            if (!attributeDetails.isAttributeOnSuperClass() && !attributeDetails.isVirtualProperty()) {
                if (label != null) {
                    cv_get.visitLabel(label);
                }
                // else if (attribute == "address")
                cv_get.visitVarInsn(ALOAD, 1);
                cv_get.visitLdcInsn(attributeDetails.getAttributeName().intern());
                label = new Label();
                cv_get.visitJumpInsn(IF_ACMPNE, label);
                // return this.address
                cv_get.visitVarInsn(ALOAD, 0);
                cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), attributeDetails.getAttributeName(), attributeDetails.getReferenceClassType().getDescriptor());
                // if this is a primitive, get the wrapper class
                String wrapper = ClassWeaver.wrapperFor(attributeDetails.getReferenceClassType().getSort());
                if (wrapper != null) {
                    // Call valueOf on the wrapper (more optimal than
                    // constructor).
                    cv_get.visitMethodInsn(INVOKESTATIC, wrapper, "valueOf", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")L" + wrapper + ";", false);
                }

                cv_get.visitInsn(ARETURN);
            }
        }
        if (label != null) {
            cv_get.visitLabel(label);
        }
        // call super, or return null
        if (classDetails.getSuperClassDetails() == null) {
            // return null;
            cv_get.visitInsn(ACONST_NULL);
        } else {
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitVarInsn(ALOAD, 1);
            cv_get.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "_persistence_get", "(Ljava/lang/String;)Ljava/lang/Object;", false);
        }

        cv_get.visitInsn(ARETURN);
        cv_get.visitMaxs(0, 0);

        // create the _persistence_set() method
        MethodVisitor cv_set = cv.visitMethod(ACC_PUBLIC, "_persistence_set", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);

        label = null;
        for (AttributeDetails attribute : classDetails.getAttributesMap().values()) {
            if (!attribute.isAttributeOnSuperClass() && !attribute.isVirtualProperty()) {
                if (label != null) {
                    cv_set.visitLabel(label);
                }
                // else if (attribute == "address")
                cv_set.visitVarInsn(ALOAD, 1);
                cv_set.visitLdcInsn(attribute.getAttributeName().intern());
                label = new Label();
                cv_set.visitJumpInsn(IF_ACMPNE, label);
                // this.address = (String)value;
                cv_set.visitVarInsn(ALOAD, 0);
                cv_set.visitVarInsn(ALOAD, 2);
                String wrapper = wrapperFor(attribute.getReferenceClassType().getSort());
                if (wrapper == null) {
                    wrapper = attribute.getReferenceClassName().replace('.', '/');
                }
                cv_set.visitTypeInsn(CHECKCAST, wrapper);
                // Unwrap any primitive wrapper to its value.
                unwrapPrimitive(attribute, cv_set);
                cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute.getAttributeName(), attribute.getReferenceClassType().getDescriptor());
                // return;
                cv_set.visitInsn(RETURN);
            }
        }
        if (label != null) {
            cv_set.visitLabel(label);
        }
        // call super, or return null
        if (classDetails.getSuperClassDetails() != null) {
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitVarInsn(ALOAD, 1);
            cv_set.visitVarInsn(ALOAD, 2);
            cv_set.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "_persistence_set", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
        }

        cv_set.visitInsn(RETURN);
        cv_set.visitMaxs(0, 0);
    }

    /**
     * Adds get/set method for PersistenceEntity interface. This adds the
     * following methods:
     *
     * public Object _persistence_getId() { return _persistence_primaryKey; }
     * public void _persistence_setId(Object primaryKey) {
     * this._persistence_primaryKey = primaryKey; }
     */
    public void addPersistenceEntityMethods(ClassDetails classDetails) {
        MethodVisitor cv_getPKVector = cv.visitMethod(ACC_PUBLIC, "_persistence_getId", "()" + OBJECT_SIGNATURE, null, null);
        cv_getPKVector.visitVarInsn(ALOAD, 0);
        cv_getPKVector.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_primaryKey", OBJECT_SIGNATURE);
        cv_getPKVector.visitInsn(ARETURN);
        cv_getPKVector.visitMaxs(0, 0);

        MethodVisitor cv_setPKVector = cv.visitMethod(ACC_PUBLIC, "_persistence_setId", "(" + OBJECT_SIGNATURE + ")V", null, null);
        cv_setPKVector.visitVarInsn(ALOAD, 0);
        cv_setPKVector.visitVarInsn(ALOAD, 1);
        cv_setPKVector.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_primaryKey", OBJECT_SIGNATURE);
        cv_setPKVector.visitInsn(RETURN);
        cv_setPKVector.visitMaxs(0, 0);

        MethodVisitor cv_getCacheKey = cv.visitMethod(ACC_PUBLIC, "_persistence_getCacheKey", "()" + CACHEKEY_SIGNATURE, null, null);
        cv_getCacheKey.visitVarInsn(ALOAD, 0);
        cv_getCacheKey.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_cacheKey", CACHEKEY_SIGNATURE);
        cv_getCacheKey.visitInsn(ARETURN);
        cv_getCacheKey.visitMaxs(0, 0);

        MethodVisitor cv_setCacheKey = cv.visitMethod(ACC_PUBLIC, "_persistence_setCacheKey", "(" + CACHEKEY_SIGNATURE + ")V", null, null);
        cv_setCacheKey.visitVarInsn(ALOAD, 0);
        cv_setCacheKey.visitVarInsn(ALOAD, 1);
        cv_setCacheKey.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_cacheKey", CACHEKEY_SIGNATURE);
        cv_setCacheKey.visitInsn(RETURN);
        cv_setCacheKey.visitMaxs(0, 0);
    }

    /**
     * Add a variable of type FetchGroup, Session to the class. When this method
     * has been run, the class will contain a variable declarations similar to
     * the following:
     *
     * private FetchGroup _persistence_fetchGroup; private boolean
     * _persistence_shouldRefreshFetchGroup; private Session
     * _persistence_session;
     */
    public void addFetchGroupVariables() {
        FieldVisitor fv = cv.visitField(ACC_PROTECTED, "_persistence_fetchGroup", FETCHGROUP_SIGNATURE, null, null);
        // Only add jakarta.persistence.Transient annotation if attribute access
        // is being used
        if (classDetails.usesAttributeAccess()) {
            fv.visitAnnotation(JPA_TRANSIENT_DESCRIPTION, true).visitEnd();
        }
        if (isJAXBOnPath()) {
            fv.visitAnnotation(XML_TRANSIENT_DESCRIPTION, true).visitEnd();
        }
        fv.visitEnd();

        cv.visitField(ACC_PROTECTED + ACC_TRANSIENT, "_persistence_shouldRefreshFetchGroup", PBOOLEAN_SIGNATURE, null, null).visitEnd();
        cv.visitField(ACC_PROTECTED + ACC_TRANSIENT, "_persistence_session", SESSION_SIGNATURE, null, null).visitEnd();
    }

    /**
     * Adds get/set method for FetchGroupTracker interface. This adds the
     * following methods:
     *
     * public Session _persistence_getSession() { return _persistence_session; }
     * public void _persistence_setSession(Session session) {
     * this._persistence_session = session; }
     *
     * public FetchGroup _persistence_getFetchGroup() { return
     * _persistence_fetchGroup; } public void
     * _persistence_setFetchGroup(FetchGroup fetchGroup) {
     * this._persistence_fetchGroup = fetchGroup; }
     *
     * public boolean _persistence_shouldRefreshFetchGroup() { return
     * _persistence_shouldRefreshFetchGroup; } public void
     * _persistence_setShouldRefreshFetchGroup(boolean shouldRefreshFetchGroup)
     * { this._persistence_shouldRefreshFetchGroup = shouldRefreshFetchGroup; }
     *
     * public void _persistence_resetFetchGroup() { }
     *
     * public void _persistence_isAttributeFetched(String attribute) { return
     * this._persistence_fetchGroup == null ||
     * _persistence_fetchGroup.containsAttribute(attribute); }
     *
     * public void _persistence_checkFetched(String attribute) { if
     * (this._persistence_fetchGroup != null) {
     * EntityManagerImpl.processUnfetchedAttribute(this, attribute); } }
     *
     *
     * public void _persistence_checkSetFetched(String attribute) { if
     * (this._persistence_fetchGroup != null) {
     * EntityManagerImpl.processUnfetchedAttributeForSet(this, attribute); } }
     */
    public void addFetchGroupMethods(ClassDetails classDetails) {
        MethodVisitor cv_getSession = cv.visitMethod(ACC_PUBLIC, "_persistence_getSession", "()" + SESSION_SIGNATURE, null, null);
        cv_getSession.visitVarInsn(ALOAD, 0);
        cv_getSession.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_session", SESSION_SIGNATURE);
        cv_getSession.visitInsn(ARETURN);
        cv_getSession.visitMaxs(0, 0);

        MethodVisitor cv_setSession = cv.visitMethod(ACC_PUBLIC, "_persistence_setSession", "(" + SESSION_SIGNATURE + ")V", null, null);
        cv_setSession.visitVarInsn(ALOAD, 0);
        cv_setSession.visitVarInsn(ALOAD, 1);
        cv_setSession.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_session", SESSION_SIGNATURE);
        cv_setSession.visitInsn(RETURN);
        cv_setSession.visitMaxs(0, 0);

        MethodVisitor cv_getFetchGroup = cv.visitMethod(ACC_PUBLIC, "_persistence_getFetchGroup", "()" + FETCHGROUP_SIGNATURE, null, null);
        cv_getFetchGroup.visitVarInsn(ALOAD, 0);
        cv_getFetchGroup.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_fetchGroup", FETCHGROUP_SIGNATURE);
        cv_getFetchGroup.visitInsn(ARETURN);
        cv_getFetchGroup.visitMaxs(0, 0);

        MethodVisitor cv_setFetchGroup = cv.visitMethod(ACC_PUBLIC, "_persistence_setFetchGroup", "(" + FETCHGROUP_SIGNATURE + ")V", null, null);
        cv_setFetchGroup.visitVarInsn(ALOAD, 0);
        cv_setFetchGroup.visitVarInsn(ALOAD, 1);
        cv_setFetchGroup.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_fetchGroup", FETCHGROUP_SIGNATURE);
        cv_setFetchGroup.visitInsn(RETURN);
        cv_setFetchGroup.visitMaxs(0, 0);

        MethodVisitor cv_shouldRefreshFetchGroup = cv.visitMethod(ACC_PUBLIC, "_persistence_shouldRefreshFetchGroup", "()" + PBOOLEAN_SIGNATURE, null, null);
        cv_shouldRefreshFetchGroup.visitVarInsn(ALOAD, 0);
        cv_shouldRefreshFetchGroup.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_shouldRefreshFetchGroup", PBOOLEAN_SIGNATURE);
        cv_shouldRefreshFetchGroup.visitInsn(IRETURN);
        cv_shouldRefreshFetchGroup.visitMaxs(0, 0);

        MethodVisitor cv_setShouldRefreshFetchGroup = cv.visitMethod(ACC_PUBLIC, "_persistence_setShouldRefreshFetchGroup", "(" + PBOOLEAN_SIGNATURE + ")V", null, null);
        cv_setShouldRefreshFetchGroup.visitVarInsn(ALOAD, 0);
        cv_setShouldRefreshFetchGroup.visitVarInsn(ILOAD, 1);
        cv_setShouldRefreshFetchGroup.visitFieldInsn(PUTFIELD, classDetails.getClassName(), "_persistence_shouldRefreshFetchGroup", PBOOLEAN_SIGNATURE);
        cv_setShouldRefreshFetchGroup.visitInsn(RETURN);
        cv_setShouldRefreshFetchGroup.visitMaxs(0, 0);

        MethodVisitor cv_resetFetchGroup = cv.visitMethod(ACC_PUBLIC, "_persistence_resetFetchGroup", "()V", null, null);
        cv_resetFetchGroup.visitInsn(RETURN);
        cv_resetFetchGroup.visitMaxs(0, 0);

        MethodVisitor cv_isAttributeFetched = cv.visitMethod(ACC_PUBLIC, "_persistence_isAttributeFetched", "(Ljava/lang/String;)Z", null, null);
        cv_isAttributeFetched.visitVarInsn(ALOAD, 0);
        cv_isAttributeFetched.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_fetchGroup", FETCHGROUP_SIGNATURE);
        Label gotoTrue = new Label();
        cv_isAttributeFetched.visitJumpInsn(IFNULL, gotoTrue);
        cv_isAttributeFetched.visitVarInsn(ALOAD, 0);
        cv_isAttributeFetched.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_persistence_fetchGroup", FETCHGROUP_SIGNATURE);
        cv_isAttributeFetched.visitVarInsn(ALOAD, 1);
        cv_isAttributeFetched.visitMethodInsn(INVOKEVIRTUAL, FETCHGROUP_SHORT_SIGNATURE, "containsAttributeInternal", "(Ljava/lang/String;)Z", false);
        Label gotoFalse = new Label();
        cv_isAttributeFetched.visitJumpInsn(IFEQ, gotoFalse);
        cv_isAttributeFetched.visitLabel(gotoTrue);
        cv_isAttributeFetched.visitInsn(ICONST_1);
        Label gotoReturn = new Label();
        cv_isAttributeFetched.visitJumpInsn(GOTO, gotoReturn);
        cv_isAttributeFetched.visitLabel(gotoFalse);
        cv_isAttributeFetched.visitInsn(ICONST_0);
        cv_isAttributeFetched.visitLabel(gotoReturn);
        cv_isAttributeFetched.visitInsn(IRETURN);
        cv_isAttributeFetched.visitMaxs(0, 0);

        MethodVisitor cv_checkFetched = cv.visitMethod(ACC_PUBLIC, "_persistence_checkFetched", "(Ljava/lang/String;)V", null, null);
        cv_checkFetched.visitVarInsn(ALOAD, 0);
        cv_checkFetched.visitVarInsn(ALOAD, 1);
        cv_checkFetched.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_isAttributeFetched", "(Ljava/lang/String;)Z", false);
        gotoReturn = new Label();
        cv_checkFetched.visitJumpInsn(IFNE, gotoReturn);
        cv_checkFetched.visitVarInsn(ALOAD, 0);
        cv_checkFetched.visitTypeInsn(CHECKCAST, FETCHGROUP_TRACKER_SHORT_SIGNATURE);
        cv_checkFetched.visitVarInsn(ALOAD, 1);
        cv_checkFetched.visitMethodInsn(INVOKESTATIC, ENTITY_MANAGER_IMPL_SHORT_SIGNATURE, "processUnfetchedAttribute", "(" + FETCHGROUP_TRACKER_SIGNATURE + "Ljava/lang/String;)V", false);
        cv_checkFetched.visitLabel(gotoReturn);
        cv_checkFetched.visitInsn(RETURN);
        cv_checkFetched.visitMaxs(0, 0);

        MethodVisitor cv_checkFetchedForSet = cv.visitMethod(ACC_PUBLIC, "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", null, null);
        cv_checkFetchedForSet.visitVarInsn(ALOAD, 0);
        cv_checkFetchedForSet.visitVarInsn(ALOAD, 1);
        cv_checkFetchedForSet.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_isAttributeFetched", "(Ljava/lang/String;)Z", false);
        gotoReturn = new Label();
        cv_checkFetchedForSet.visitJumpInsn(IFNE, gotoReturn);
        cv_checkFetchedForSet.visitVarInsn(ALOAD, 0);
        cv_checkFetchedForSet.visitTypeInsn(CHECKCAST, FETCHGROUP_TRACKER_SHORT_SIGNATURE);
        cv_checkFetchedForSet.visitVarInsn(ALOAD, 1);
        cv_checkFetchedForSet.visitMethodInsn(INVOKESTATIC, ENTITY_MANAGER_IMPL_SHORT_SIGNATURE, "processUnfetchedAttributeForSet", "(" + FETCHGROUP_TRACKER_SIGNATURE + "Ljava/lang/String;)V", false);
        cv_checkFetchedForSet.visitLabel(gotoReturn);
        cv_checkFetchedForSet.visitInsn(RETURN);
        cv_checkFetchedForSet.visitMaxs(0, 0);
    }

    /**
     * Visit the class byte-codes and modify to weave Persistence interfaces.
     * This add PersistenceWeaved, PersistenceWeavedLazy,
     * PersistenceWeavedChangeTracking, PersistenceEntity, ChangeTracker. The
     * new interfaces are pass to the super weaver.
     */
    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        boolean weaveCloneable = true;
        // To prevent 'double' weaving: scan for PersistenceWeaved interface.
        for (int index = 0; index < interfaces.length; index++) {
            String existingInterface = interfaces[index];
            if (PERSISTENCE_WEAVED_SHORT_SIGNATURE.equals(existingInterface)) {
                this.alreadyWeaved = true;
                super.visit(version, access, name, signature, superName, interfaces);
                return;
            } else if (CT_SHORT_SIGNATURE.equals(existingInterface)) {
                // Disable weaving of change tracking if already implemented
                // (such as by user).
                classDetails.setShouldWeaveChangeTracking(false);
            } else if (CLONEABLE_SHORT_SIGNATURE.equals(existingInterface)) {
                weaveCloneable = false;
            }
        }
        int newInterfacesLength = interfaces.length;
        // Cloneable
        int cloneableIndex = 0;
        weaveCloneable = classDetails.shouldWeaveInternal() && weaveCloneable && (classDetails.getSuperClassDetails() == null);
        if (weaveCloneable) {
            cloneableIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        // PersistenceWeaved
        int persistenceWeavedIndex = newInterfacesLength;
        newInterfacesLength++;
        // PersistenceEntity
        int persistenceEntityIndex = 0;
        boolean persistenceEntity = classDetails.shouldWeaveInternal() && (classDetails.getSuperClassDetails() == null) && (!classDetails.isEmbedable());
        if (persistenceEntity) {
            persistenceEntityIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        // PersistenceObject
        int persistenceObjectIndex = 0;
        boolean persistenceObject = classDetails.shouldWeaveInternal();
        if (persistenceObject) {
            persistenceObjectIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        // FetchGroupTracker
        int fetchGroupTrackerIndex = 0;
        boolean fetchGroupTracker = classDetails.shouldWeaveFetchGroups() && (classDetails.getSuperClassDetails() == null);
        if (fetchGroupTracker) {
            fetchGroupTrackerIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        int persistenceWeavedFetchGroupsIndex = 0;
        if (classDetails.shouldWeaveFetchGroups()) {
            persistenceWeavedFetchGroupsIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        // PersistenceWeavedLazy
        int persistenceWeavedLazyIndex = 0;
        if (classDetails.shouldWeaveValueHolders()) {
            persistenceWeavedLazyIndex = newInterfacesLength;
            newInterfacesLength++;
        }

        // ChangeTracker
        boolean changeTracker = !classDetails.doesSuperclassWeaveChangeTracking() && classDetails.shouldWeaveChangeTracking();
        int persistenceWeavedChangeTrackingIndex = 0;
        int changeTrackerIndex = 0;
        if (changeTracker) {
            changeTrackerIndex = newInterfacesLength;
            newInterfacesLength++;
        }
        if (classDetails.shouldWeaveChangeTracking()) {
            persistenceWeavedChangeTrackingIndex = newInterfacesLength;
            newInterfacesLength++;
        }

        int persistenceWeavedRestIndex = 0;
        boolean weaveRest = classDetails.shouldWeaveREST() && classDetails.getSuperClassDetails() == null;
        if (weaveRest) {
            persistenceWeavedRestIndex = newInterfacesLength;
            newInterfacesLength++;
        }

        String[] newInterfaces = new String[newInterfacesLength];
        System.arraycopy(interfaces, 0, newInterfaces, 0, interfaces.length);
        // Add 'marker'
        // org.eclipse.persistence.internal.weaving.PersistenceWeaved interface.
        newInterfaces[persistenceWeavedIndex] = PERSISTENCE_WEAVED_SHORT_SIGNATURE;
        weaved = true;
        // Add Cloneable interface.
        if (weaveCloneable) {
            newInterfaces[cloneableIndex] = CLONEABLE_SHORT_SIGNATURE;
        }
        // Add org.eclipse.persistence.internal.descriptors.PersistenceEntity
        // interface.
        if (persistenceEntity) {
            newInterfaces[persistenceEntityIndex] = PERSISTENCE_ENTITY_SHORT_SIGNATURE;
        }
        // Add org.eclipse.persistence.internal.descriptors.PersistenceObject
        // interface.
        if (persistenceObject) {
            newInterfaces[persistenceObjectIndex] = PERSISTENCE_OBJECT_SHORT_SIGNATURE;
        }
        // Add org.eclipse.persistence.queries.FetchGroupTracker interface.
        if (fetchGroupTracker) {
            newInterfaces[fetchGroupTrackerIndex] = FETCHGROUP_TRACKER_SHORT_SIGNATURE;
        }
        if (classDetails.shouldWeaveFetchGroups()) {
            newInterfaces[persistenceWeavedFetchGroupsIndex] = WEAVED_FETCHGROUPS_SHORT_SIGNATURE;
        }
        // Add marker interface for LAZY.
        if (classDetails.shouldWeaveValueHolders()) {
            newInterfaces[persistenceWeavedLazyIndex] = TW_LAZY_SHORT_SIGNATURE;
        }
        // Add marker interface and change tracker interface for change
        // tracking.
        if (changeTracker) {
            newInterfaces[changeTrackerIndex] = CT_SHORT_SIGNATURE;
        }
        if (classDetails.shouldWeaveChangeTracking()) {
            newInterfaces[persistenceWeavedChangeTrackingIndex] = TW_CT_SHORT_SIGNATURE;
        }

        if (weaveRest) {
            newInterfaces[persistenceWeavedRestIndex] = WEAVED_REST_LAZY_SHORT_SIGNATURE;
        }

        String newSignature = null;
        // fix the signature to include any new methods we weave
        if (signature != null) {
            StringBuffer newSignatureBuf = new StringBuffer();
            newSignatureBuf.append(signature);

            for (int i = interfaces.length; i < newInterfaces.length; i++) {
                newSignatureBuf.append("L" + newInterfaces[i] + ";");
            }
            newSignature = newSignatureBuf.toString();
        }

        cv.visit(version, access, name, newSignature, superName, newInterfaces);
    }

    /**
     * Construct a MethodWeaver and allow it to process the method.
     */
    @Override
    public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, methodName, desc, signature, exceptions);
        if (!alreadyWeaved) {
            // skip constructors, they will not changed
            if (!"<init>".equals(methodName) && !"<cinit>".equals(methodName)) {
                // remaining modifications to the 'body' of the class are
                // delegated to MethodWeaver
                mv = new MethodWeaver(this, methodName, desc, mv);
            }
        }
        return mv;
    }

    /**
     * Visit the end of the class byte codes. Add any new methods or variables to the end.
     */
    @Override
    public void visitEnd() {
        if (!alreadyWeaved) {
            if (this.classDetails.shouldWeaveInternal()) {

                // Add a persistence and shallow clone method.
                addPersistencePostClone(this.classDetails);
                if (this.classDetails.getSuperClassDetails() == null) {
                    addShallowClone(this.classDetails);
                    if (!this.classDetails.isEmbedable()) {
                        // Add PersistenceEntity variables and methods.
                        addPersistenceEntityVariables();
                        addPersistenceEntityMethods(this.classDetails);
                        this.weavedPersistenceEntity = true;
                    }
                }
                // Add empty new method and generic get/set methods.
                addPersistenceNew(this.classDetails);
                addPersistenceGetSet(this.classDetails);
            }

            boolean attributeAccess = false;
            // For each attribute we need to check what methods and variables to
            // add.
            for (Iterator<AttributeDetails> iterator = this.classDetails.getAttributesMap().values().iterator(); iterator.hasNext();) {
                AttributeDetails attributeDetails = iterator.next();
                // Only add to classes that actually contain the attribute we
                // are
                // processing
                // an attribute could be in the classDetails but not actually in
                // the
                // class
                // if it is owned by a MappedSuperClass.
                if (!attributeDetails.isAttributeOnSuperClass()) {
                    if (attributeDetails.weaveValueHolders()) {
                        // We will add valueholders and methods to classes that
                        // have
                        // not already been weaved
                        // and classes that actually contain the attribute we
                        // are
                        // processing
                        // an attribute could be in the classDetails but not
                        // actually in the class
                        // if it is owned by a MappedSuperClass.
                        if (!attributeDetails.isAttributeOnSuperClass()) {
                            weaved = true;
                            weavedLazy = true;
                            addValueHolder(attributeDetails);
                            addInitializerForValueHolder(classDetails, attributeDetails);
                            addGetterMethodForValueHolder(classDetails, attributeDetails);
                            addSetterMethodForValueHolder(classDetails, attributeDetails);
                        }
                    }
                    if (classDetails.shouldWeaveChangeTracking() || classDetails.shouldWeaveFetchGroups() || attributeDetails.weaveValueHolders()) {
                        if (attributeDetails.hasField()) {
                            weaved = true;
                            addGetterMethodForFieldAccess(classDetails, attributeDetails);
                            addSetterMethodForFieldAccess(classDetails, attributeDetails);
                            attributeAccess = true;
                        }
                    }
                }
            }
            if (classDetails.shouldWeaveChangeTracking()) {
                weaved = true;
                weavedChangeTracker = true;
                if ((classDetails.getSuperClassDetails() == null) || (!classDetails.doesSuperclassWeaveChangeTracking())) {
                    addPropertyChangeListener(attributeAccess);
                    addGetPropertyChangeListener(classDetails);
                    addSetPropertyChangeListener(classDetails);
                    addPropertyChange(classDetails);
                }
            }
            if (classDetails.shouldWeaveFetchGroups()) {
                weaved = true;
                weavedFetchGroups = true;
                if (classDetails.getSuperClassDetails() == null) {
                    addFetchGroupVariables();
                    addFetchGroupMethods(this.classDetails);
                }
            }
        }
        if (classDetails.shouldWeaveREST() && classDetails.getSuperClassDetails() == null) {
            weavedRest = true;
            addPersistenceRestVariables();
            addPersistenceRestMethods(classDetails);
        }
        cv.visitEnd();
    }
}
