/*
 * 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
package org.eclipse.persistence.internal.sessions;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.FetchGroup;

/**
 * <p>
 * <b>Purpose</b>: This is the overall collection of changes.
 * </p>
 * <p>
 * <b>Description</b>: It holds all of the object changes and
 * all ObjectChanges, with the same classType and primary keys, referenced in a changeSet should be
 * the same object.
 * </p>
 */
public class UnitOfWorkChangeSet implements Serializable, org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet {

    /** This is the collection of ObjectChanges held by this ChangeSet */
    // *** TODO fix transients *** */
    protected Map<Class, Map<ObjectChangeSet, ObjectChangeSet>> objectChanges;

    // This collection holds the new objects which will have no real identity until inserted.
    protected Map<Class, Map<ObjectChangeSet, ObjectChangeSet>> newObjectChangeSets;
    protected Map<Object, ObjectChangeSet> cloneToObjectChangeSet;
    protected Map<ObjectChangeSet, Object> objectChangeSetToUOWClone;
    protected Map<ObjectChangeSet, ObjectChangeSet> aggregateChangeSets;
    protected Map<ObjectChangeSet, ObjectChangeSet> allChangeSets;
    protected Map<ObjectChangeSet, ObjectChangeSet> deletedObjects;

    /** This attribute is set to true if a changeSet with changes has been added */
    protected boolean hasChanges;
    protected boolean hasForcedChanges;

    /**
     * Flag set when calling commitToDatabaseWithPreBuiltChangeSet
     * so we are aware the UOW does not contain the changes from this change set.
     */
    protected boolean isChangeSetFromOutsideUOW;

    /** Stores unit of work before it is serialized. */
    protected transient AbstractSession session;

    /**
     * INTERNAL:
     * Create a ChangeSet
     */
    public UnitOfWorkChangeSet() {
    }

    /**
     * INTERNAL:
     * Create a ChangeSet
     */
    public UnitOfWorkChangeSet(AbstractSession session) {
        this.session = session;
    }

    /**
     * Return the session.
     * This only exists before serialization.
     */
    public AbstractSession getSession() {
        return session;
    }

    /**
     * INTERNAL:
     * Set the session.
     * This only exists before serialization.
     */
    public void setSession(AbstractSession session) {
        this.session = session;
    }

    /**
     * INTERNAL:
     * Add the Deleted objects to the changeSet.
     */
    public void addDeletedObjects(Map deletedObjects, AbstractSession session) {
        Iterator enumtr = deletedObjects.keySet().iterator();
        while (enumtr.hasNext()) {
            Object object = enumtr.next();
            this.addDeletedObject(object, session);
        }
    }

    /**
     * INTERNAL:
     * Add the Deleted object to the changeSet.
     */
    public void addDeletedObject(Object object, AbstractSession session) {
        //CR 4080 - must prevent aggregate objects added to DeletedObjects list
        ClassDescriptor descriptor = session.getDescriptor(object);
        if (!descriptor.isAggregateCollectionDescriptor()) {
            ObjectChangeSet set = descriptor.getObjectBuilder().createObjectChangeSet(object, this, false, session);

            // needed for xml change set
            set.setShouldBeDeleted(true);
            getDeletedObjects().put(set, set);
        }
    }

    /**
     * INTERNAL:
     * Add to the changes for 'object' object to this changeSet. This method
     * will not add to the lists that are used for identity lookups.
     * The passed change set *must* either have changes or forced changes.
     * @see #addObjectChangeSetForIdentity(ObjectChangeSet, Object)
     * @param forceToNewObjectList - Any pre commit actions should pass in true
     * since new objects have extra-handling. Anything post commit, pass in
     * false.
     */
    public void addObjectChangeSet(ObjectChangeSet objectChanges, AbstractSession session, boolean forceToNewObjectList) {
        if (objectChanges != null) {
             if (objectChanges.isNew() && forceToNewObjectList) {
                // Add it to the new list (unless there is no force, that is,
                // we are in a post commit and we can trust the cache key then)
                // so we do not loose it as it may not have a valid primary key
                // it will be moved to the standard list once it is inserted.
                addNewObjectChangeSet(objectChanges, session);
                getAllChangeSets().put(objectChanges, objectChanges);
            } else {
                // If this object change set has changes or forced changes then
                // record this. Must be done for each change set added because
                // some may not contain 'real' changes.  This is the case for
                // opt. read lock and forceUdpate.  Keep the flags separate
                // because we don't want to cache sync. a change set with no
                // 'real' changes.
                boolean objectChangeSetHasChanges = objectChanges.hasChanges();
                if (objectChangeSetHasChanges) {
                    this.setHasChanges(true);
                    this.hasForcedChanges = this.hasForcedChanges || objectChanges.hasForcedChanges();
                } else {
                    // Object change set doesn't have changes so it has to have
                    // forced changes.
                    this.hasForcedChanges = true;
                }

                if (!objectChanges.isAggregate()) {
                    if (objectChangeSetHasChanges) {
                        // Each time I create a changeSet it is added to this
                        // list and when I compute a changeSet for this object
                        // I again add it to these lists so that before this
                        // UOWChangeSet is Serialized there is a copy of every
                        // changeSet which has changes affecting cache in
                        // allChangeSets.
                        getAllChangeSets().put(objectChanges, objectChanges);
                    }

                    if (objectChanges.getId() != null) {
                        Map<ObjectChangeSet, ObjectChangeSet> map = getObjectChanges().get(objectChanges.getClassType());

                        if (map == null) {
                            map = new HashMap<>();
                            getObjectChanges().put(objectChanges.getClassType(), map);
                            map.put(objectChanges, objectChanges);
                        } else {
                            map.put(objectChanges, objectChanges);
                        }
                    }
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Add to the changes for 'object' object to this changeSet.  This method will not
     * add to the lists that are used for identity lookups.  It is called specifically
     * for new objects, and new object will be moved to the standard changes list by
     * the QueryMechanism after insert.
     * @see #addObjectChangeSetForIdentity(ObjectChangeSet, Object)
     * @param objectChanges the new object change set
     */
    protected void addNewObjectChangeSet(ObjectChangeSet objectChanges, AbstractSession session) {
        Map<ObjectChangeSet, ObjectChangeSet> changeSetTable = getNewObjectChangeSets().get(objectChanges.getClassType(session));
        if (changeSetTable == null) {
            // 2612538 - the default size of Map (32) is appropriate
            changeSetTable = new IdentityHashMap<>();
            getNewObjectChangeSets().put(objectChanges.getClassType(session), changeSetTable);
        }
        changeSetTable.put(objectChanges, objectChanges);
        this.hasChanges = true;
    }

    /**
     * INTERNAL:
     * This method can be used find the equivalent changeset within this UnitOfWorkChangeSet
     * Aggregates, and new objects without primaryKeys from serialized ChangeSets will not be found
     * Which may result in duplicates, in the UnitOfWorkChangeSet.
     */
    public ObjectChangeSet findObjectChangeSet(ObjectChangeSet changeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
        Map<ObjectChangeSet, ObjectChangeSet> changes = getObjectChanges().get(changeSet.getClassType());
        ObjectChangeSet potential = null;
        if (changes != null) {
            potential = changes.get(changeSet);
        }
        if (potential == null) {
            potential = (ObjectChangeSet)getObjectChangeSetForClone(changeSet.getUnitOfWorkClone());
        }
        return potential;
    }

    /**
     * INTERNAL:
     * This method will be used during the merge process to either find an equivalent change set
     * within this UnitOfWorkChangeSet or integrate that changeset into this UOW ChangeSet
     */
    public ObjectChangeSet findOrIntegrateObjectChangeSet(ObjectChangeSet tofind, UnitOfWorkChangeSet mergeFromChangeSet) {
        if (tofind == null) {
            return tofind;
        }
        ObjectChangeSet localChangeSet = this.findObjectChangeSet(tofind, mergeFromChangeSet);
        if (localChangeSet == null) {//not found locally then replace it with the one from the merging changeset
            if (tofind.getDescriptor() == null) {
                tofind.getClassType(this.session);
                tofind.setDescriptor(this.session.getDescriptor(tofind.getClassType()));
            }
            localChangeSet = new ObjectChangeSet(tofind.getId(), tofind.getDescriptor(), tofind.getUnitOfWorkClone(), this, tofind.isNew());
            this.addObjectChangeSetForIdentity(localChangeSet, localChangeSet.getUnitOfWorkClone());
        }
        return localChangeSet;
    }

    /**
     * INTERNAL"
     * This method is used during the merge process to either find the existing ChangeSet or create a new one.
     */
    public ObjectChangeSet findOrCreateLocalObjectChangeSet(Object entityClone, ClassDescriptor descriptor, boolean isNew){
        ObjectChangeSet changes = (ObjectChangeSet)this.getObjectChangeSetForClone(entityClone);
        if (changes == null) {
            if (descriptor.hasInheritance() && descriptor.getJavaClass() != entityClone.getClass()) {
                descriptor = descriptor.getInheritancePolicy().getSubclassDescriptor(entityClone.getClass());
            }
            if (descriptor.isAggregateDescriptor()) {
                changes = new AggregateObjectChangeSet(CacheId.EMPTY, descriptor, entityClone, this, isNew);
            } else {
                changes = new ObjectChangeSet(descriptor.getObjectBuilder().extractPrimaryKeyFromObject(entityClone, session), descriptor, entityClone, this, isNew);
            }
            changes.setIsAggregate(descriptor.isDescriptorTypeAggregate());
            this.addObjectChangeSetForIdentity(changes, entityClone);
        }
        return changes;
    }

    /**
     * INTERNAL:
     * Add change records to the lists used to maintain identity.  This will not actually
     * add the changes to 'object' to the change set.
     * @see #addObjectChangeSet(ObjectChangeSet, AbstractSession, boolean)
     * @param objectChanges prototype.changeset.ObjectChanges
     */
    public void addObjectChangeSetForIdentity(ObjectChangeSet objectChanges, Object object) {
        if ((objectChanges == null) || (object == null)) {
            return;
        }

        if (objectChanges.isAggregate()) {
            getAggregateChangeSets().put(objectChanges, objectChanges);
        }

        getObjectChangeSetToUOWClone().put(objectChanges, object);
        getCloneToObjectChangeSet().put(object, objectChanges);

    }

    /**
     * INTERNAL:
     * Get the Aggregate list.  Lazy initializes the map if required.
     */
    public Map<ObjectChangeSet, ObjectChangeSet> getAggregateChangeSets() {
        if (this.aggregateChangeSets == null) {
            this.aggregateChangeSets = new IdentityHashMap<>();
        }
        return this.aggregateChangeSets;
    }

    /**
     * INTERNAL:
     * This method returns a reference to the collection.
     */
    @Override
    public Map<ObjectChangeSet, ObjectChangeSet> getAllChangeSets() {
        if (this.allChangeSets == null) {
            // 2612538 - the default size of Map (32) is appropriate
            this.allChangeSets = new IdentityHashMap<>();
        }
        return this.allChangeSets;
    }

    /**
     * INTERNAL:
     * Return a new UnitOfWorkChangeSet that only includes data require for the remote merge,
     * for cache coordination.
     *
     * @param session current database session
     */
    public UnitOfWorkChangeSet buildCacheCoordinationMergeChangeSet(AbstractSession session) {
        //bug 4416412: Map sent instead of Vector
        Map writableChangeSets = new IdentityHashMap();
        for (ObjectChangeSet changeSet : getAllChangeSets().values()) {
            // navigate through the related change sets here and set their cache synchronization type as well
            ClassDescriptor descriptor = changeSet.getDescriptor();
            int syncType = descriptor.getCachePolicy().getCacheSynchronizationType();

            // Bug 486845 - ensure that any existing protected foreign keys are set 
            // in the changeSet for objects with protected cache isolation
            if (descriptor.isProtectedIsolation()) {
                CacheKey activeCacheKey = changeSet.getActiveCacheKey();
                if (activeCacheKey != null && activeCacheKey.hasProtectedForeignKeys()) {
                    changeSet.setProtectedForeignKeys(activeCacheKey.getProtectedForeignKeys().clone());
                }
            }
            
            // Change sets for new objects will only be sent as part of the UnitOfWorkChangeSet
            // if they are meant to be merged into the distributed cache.
            // Note: New objects could still be sent if the are referred to by a change record.
            if ((syncType != ClassDescriptor.DO_NOT_SEND_CHANGES)
                    && (!changeSet.isNew() || (syncType == ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES))) {
                changeSet.unitOfWorkChangeSet.setSession(null);
                writableChangeSets.put(changeSet, changeSet);
            }
            // bug 530681: ensureChanges(AbstractSession, ObjectChangeSet, ClassDescriptor) from ObjectChangeSet was moved here
            if (changeSet.isNew() && ((changeSet.changes == null) || changeSet.changes.isEmpty()
                    || syncType != ClassDescriptor.SEND_NEW_OBJECTS_WITH_CHANGES)) {
                ensureChanges(session, changeSet, descriptor);
            }
        }
        Map sendableDeletedObjects = new IdentityHashMap();
        for (ObjectChangeSet changeSet : getDeletedObjects().keySet()) {
            // navigate through the related change sets here and set their cache synchronization type as well
            ClassDescriptor descriptor = changeSet.getDescriptor();
            int syncType = descriptor.getCacheSynchronizationType();

            // Change sets for new objects will only be sent as part of the UnitOfWorkChangeSet
            // if they are meant to be merged into the distributed cache.
            // Note: New objects could still be sent if the are referred to by a change record.
            if (syncType != ClassDescriptor.DO_NOT_SEND_CHANGES) {
                changeSet.unitOfWorkChangeSet.setSession(null);
                sendableDeletedObjects.put(changeSet, changeSet);
            }
        }

        // Do not write if nothing to write i.e. only does inserts
        if (writableChangeSets.isEmpty() && sendableDeletedObjects.isEmpty()) {
            return null;
        }
        UnitOfWorkChangeSet remoteChangeSet = new UnitOfWorkChangeSet();
        if (!writableChangeSets.isEmpty()) {
            remoteChangeSet.allChangeSets = writableChangeSets;
        }
        if (!sendableDeletedObjects.isEmpty()) {
            remoteChangeSet.deletedObjects = sendableDeletedObjects;
        }
        return remoteChangeSet;
    }

    /**
     * Ensure the change set is populated for cache coordination.
     *
     * @param session current database session
     * @param changeSet change set to populate
     * @param descriptor class (relational) descriptor related to the change set
     */
    private void ensureChanges(final AbstractSession session, final ObjectChangeSet changeSet, final ClassDescriptor descriptor) {
        FetchGroup fetchGroup = null;
        if (descriptor.hasFetchGroupManager()) {
            fetchGroup = descriptor.getFetchGroupManager().getObjectFetchGroup(changeSet.cloneObject);
        }
        for (DatabaseMapping mapping : descriptor.getMappings()) {
            if (fetchGroup == null || fetchGroup.containsAttributeInternal(mapping.getAttributeName())) {
                changeSet.addChange(mapping.compareForChange(changeSet.cloneObject, changeSet.cloneObject, changeSet, session));
            }
        }
    }

    /**
     * INTERNAL:
     * Get the clone to object change hash table.  Lazy initializes the map if required.
     */
    public Map<Object, ObjectChangeSet> getCloneToObjectChangeSet() {
        if (cloneToObjectChangeSet == null) {
            cloneToObjectChangeSet = new IdentityHashMap();
        }
        return cloneToObjectChangeSet;
    }

    /**
     * INTERNAL:
     * This method returns the reference to the deleted objects from the changeSet.
     */
    @Override
    public Map<ObjectChangeSet, ObjectChangeSet> getDeletedObjects() {
        if (this.deletedObjects == null) {
            // 2612538 - the default size of Map (32) is appropriate
            this.deletedObjects = new IdentityHashMap();
        }
        return deletedObjects;
    }

    /**
     * INTERNAL:
     * Returns the ObjectChanges held by this ChangeSet.
     */
    public Map<Class, Map<ObjectChangeSet, ObjectChangeSet>> getObjectChanges() {
        if (objectChanges == null) {
            objectChanges = new HashMap<>();
        }
        return objectChanges;
    }

    /**
     * INTERNAL:
     * Returns the set of classes corresponding to updated objects in objectChanges.
     */
    public Set<ClassDescriptor> findUpdatedObjectsClasses() {
        if (this.objectChanges == null || this.objectChanges.isEmpty()) {
            return null;
        }
        HashSet<ClassDescriptor> updatedObjectsClasses = new HashSet<>(getObjectChanges().size());
        for (Map<ObjectChangeSet, ObjectChangeSet> objectChanges : getObjectChanges().values()) {
            for (ObjectChangeSet changeSet : objectChanges.values()) {
                // any change set will do
                if(!changeSet.isNew()) {
                    // found updated object - add its class to the set
                    updatedObjectsClasses.add(changeSet.getDescriptor());
                    // and go to the table corresponding to the next class
                    break;
                }
            }
        }
        return updatedObjectsClasses;
    }

    /**
     * ADVANCED:
     * Get ChangeSet for a particular clone
     * @return ObjectChangeSet the changeSet that represents a particular clone
     */
    @Override
    public org.eclipse.persistence.sessions.changesets.ObjectChangeSet getObjectChangeSetForClone(Object clone) {
        if ((clone == null) || (this.cloneToObjectChangeSet == null)) {
            return null;
        }
        return this.cloneToObjectChangeSet.get(clone);
    }

    /**
     * INTERNAL:
     * This method returns a reference to the collection
     * @return Map
     */
    protected Map<ObjectChangeSet, Object> getObjectChangeSetToUOWClone() {
        if (this.objectChangeSetToUOWClone == null) {
            // 2612538 - the default size of Map (32) is appropriate
            this.objectChangeSetToUOWClone = new IdentityHashMap<>();
        }
        return objectChangeSetToUOWClone;
    }

    /**
     * ADVANCED:
     * This method returns the Clone for a particular changeSet
     * @return Object the clone represented by the changeSet
     */
    @Override
    public Object getUOWCloneForObjectChangeSet(org.eclipse.persistence.sessions.changesets.ObjectChangeSet changeSet) {
        if ((changeSet == null) || (this.objectChangeSetToUOWClone == null)) {
            return null;
        }
        return this.objectChangeSetToUOWClone.get(changeSet);
    }

    /**
     * INTERNAL:
     * Returns true if the Unit Of Work change Set has changes
     */
    @Override
    public boolean hasChanges() {
        // All of the object change sets were empty (none contained changes)
        // The this.hasChanges variable is set in addObjectChangeSet
        return (this.hasChanges || (this.deletedObjects != null) && (!this.deletedObjects.isEmpty()));
    }

    /**
     * INTERNAL:
     * Returns true if any deleted objects.
     * This should be used before accessing deleted object to avoid creation of map.
     */
    public boolean hasDeletedObjects() {
        return (this.deletedObjects != null) && (!this.deletedObjects.isEmpty());
    }

    /**
     * INTERNAL:
     * Set whether the Unit Of Work change Set has changes
     */
    public void setHasChanges(boolean flag) {
        this.hasChanges = flag;
    }

    /**
     * INTERNAL:
     * Returns true if this uowChangeSet contains an objectChangeSet that has forced
     * SQL changes.  This is true whenever CMPPolicy.getForceUpdate() == true.
     * @return boolean
     */
    public boolean hasForcedChanges() {
        return this.hasForcedChanges;
    }

    /**
     * INTERNAL:
     * This method will be used to merge a change set into an UnitOfWorkChangeSet
     * This method returns the local instance of the changeset
     */
    public ObjectChangeSet mergeObjectChanges(ObjectChangeSet objectChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
        ObjectChangeSet localChangeSet = this.findOrIntegrateObjectChangeSet(objectChangeSet, mergeFromChangeSet);
        if (localChangeSet != null) {
            localChangeSet.mergeObjectChanges(objectChangeSet, this, mergeFromChangeSet);
        }
        return localChangeSet;
    }

    /**
    * INTERNAL:
    * THis method will be used to merge another changeset into this changeset.  The
    * Main use of this method is for non-deferred writes and checkpointing so that
    * the accumulated changes are collected and merged at the end of the transaction.
    */
    public void mergeUnitOfWorkChangeSet(UnitOfWorkChangeSet mergeFromChangeSet, AbstractSession session, boolean postCommit) {
        if (mergeFromChangeSet == null) {
            return;
        }
        for (Map<ObjectChangeSet, ObjectChangeSet> objectChanges : mergeFromChangeSet.getObjectChanges().values()) {
            for (ObjectChangeSet objectChangeSet : objectChanges.values()) {
                objectChangeSet = mergeObjectChanges(objectChangeSet, mergeFromChangeSet);
                addObjectChangeSet(objectChangeSet, session, !postCommit);
            }
        }

        //merging a serialized UnitOfWorkChangeSet can result in duplicate deletes
        //if a delete for the same object already exists in this UOWChangeSet.
        if (mergeFromChangeSet.hasDeletedObjects()) {
            for (ObjectChangeSet objectChangeSet : mergeFromChangeSet.getDeletedObjects().values()) {
                ObjectChangeSet localObjectChangeSet = findObjectChangeSet(objectChangeSet, mergeFromChangeSet);
                if (localObjectChangeSet == null) {
                    localObjectChangeSet = objectChangeSet;
                }
                getDeletedObjects().put(localObjectChangeSet, localObjectChangeSet);
            }
        }
    }

    /**
     * INTERNAL:
     * Used to rehash the new objects back into the objectChanges list for serialization
     * Assumes the transaction in in post commit stage.
     */
    public void putNewObjectInChangesList(ObjectChangeSet objectChangeSet, AbstractSession session) {
        // Must reset the cache key for new objects assigned in insert.
        if (objectChangeSet.getId() == null) {
            Object clone = objectChangeSet.getUnitOfWorkClone();
            objectChangeSet.setId(session.getDescriptor(clone.getClass()).getObjectBuilder().extractPrimaryKeyFromObject(clone, session, false));
        }
        addObjectChangeSet(objectChangeSet, session, false);
        removeObjectChangeSetFromNewList(objectChangeSet, session);
    }

    /**
     * INTERNAL:
     * Used to remove a new object from the new objects list once it has been
     * inserted and added to the objectChangesList
     */
    public void removeObjectChangeSetFromNewList(ObjectChangeSet objectChangeSet, AbstractSession session) {
        Map table = getNewObjectChangeSets().get(objectChangeSet.getClassType(session));
        if (table != null) {
            table.remove(objectChangeSet);
        }
    }

    /**
     * INTERNAL:
     * Add the changed Object's records to the ChangeSet.
     */
    public void removeObjectChangeSet(ObjectChangeSet changeSet) {
        if (changeSet == null) {
            return;
        }
        Object object = getObjectChangeSetToUOWClone().get(changeSet);
        if (changeSet.isAggregate()) {
            getAggregateChangeSets().remove(changeSet);
        } else {
            Map classChanges = getObjectChanges().get(object.getClass());
            if (classChanges != null) {
                classChanges.remove(changeSet);
            }
        }
        getObjectChangeSetToUOWClone().remove(changeSet);
        if (object != null) {
            getCloneToObjectChangeSet().remove(object);
        }
        getAllChangeSets().remove(changeSet);
    }

    /**
     * INTERNAL:
     * Set the internal flag that tells that this change set was built outside this
     * UOW and the changes it contains cannot be calculated from the contents of this UOW
     */
    public void setIsChangeSetFromOutsideUOW(boolean isChangeSetFromOutsideUOW){
        this.isChangeSetFromOutsideUOW = isChangeSetFromOutsideUOW;
    }

    /**
     * INTERNAL:
     * Get the internal flag that tells that this change set was built outside this
     * UOW and the changes it contains cannot be calculated from the contents of this UOW
     */
    public boolean isChangeSetFromOutsideUOW(){
        return isChangeSetFromOutsideUOW;
    }

    /**
     * INTERNAL:
     * This method is used to set the map for cloneToObject reference.
     */
    public void setCloneToObjectChangeSet(Map<Object, ObjectChangeSet> cloneToObjectChangeSet) {
        this.cloneToObjectChangeSet = cloneToObjectChangeSet;
    }

    /**
     * INTERNAL:
     * Sets the collection of ObjectChanges in the change Set.
     */
    protected void setObjectChanges(Map objectChanges) {
        this.objectChanges = objectChanges;
    }

    /**
     * INTERNAL:
     * Sets the collection of ObjectChanges in the change Set.
     */
    public void setAllChangeSets(Map allChangeSets) {
        this.allChangeSets = allChangeSets;
    }

    /**
     * INTERNAL:
     * Sets the collection of deleted objects.
     */
    public void setDeletedObjects(Map deletedObjects) {
        this.deletedObjects = deletedObjects;
    }

    /**
     * INTERNAL:
     * This method is used to insert a new collection into the UOWChangeSet.
     */
    public void setObjectChangeSetToUOWClone(Map<ObjectChangeSet, Object> objectChangeSetToUOWClone) {
        this.objectChangeSetToUOWClone = objectChangeSetToUOWClone;
    }

    /**
     * INTERNAL:
     * This method will return a reference to the new object change set collections.
     */
    public Map<Class, Map<ObjectChangeSet, ObjectChangeSet>> getNewObjectChangeSets() {
        if (this.newObjectChangeSets == null) {
            this.newObjectChangeSets = new HashMap<>();
        }
        return this.newObjectChangeSets;
    }

}
