/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     08/15/2008-1.0.1 Chris Delahunt
//       - 237545: List attribute types on OneToMany using @OrderBy does not work with attribute change tracking
package org.eclipse.persistence.internal.queries;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.ListIterator;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.IndexedObject;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.OrderedChangeObject;
import org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet;
import org.eclipse.persistence.internal.sessions.CollectionChangeRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.annotations.OrderCorrectionType;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent;
import org.eclipse.persistence.indirection.IndirectCollection;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;

/**
 * <p><b>Purpose</b>: A OrderedListContainerPolicy is ContainerPolicy whose
 * container class implements the List interface and is ordered by an @OrderBy.
 * </p>
 * <p><b>Responsibilities</b>:
 * Provide the functionality to operate on an instance of a List.</p>
 *
 * @see ContainerPolicy
 * @see CollectionContainerPolicy
 * @see ListContainerPolicy
 */
public class OrderedListContainerPolicy extends ListContainerPolicy {
    protected static final String NOT_SET = "NOT_SET";
    protected DatabaseField listOrderField;
    protected OrderCorrectionType orderCorrectionType;

    /**
     * INTERNAL:
     * Construct a new policy.
     */
    public OrderedListContainerPolicy() {
        super();
    }

    /**
     * INTERNAL:
     * Construct a new policy for the specified class.
     */
    public OrderedListContainerPolicy(Class containerClass) {
        super(containerClass);
    }

    /**
     * INTERNAL:
     * Construct a new policy for the specified class name.
     */
    public OrderedListContainerPolicy(String containerClassName) {
        super(containerClassName);
    }

    /**
     * INTERNAL:
     * Add a list of elements to container.
     * This is used to add to a collection independent of JDK 1.1 and 1.2.
     * The session may be required to wrap for the wrapper policy.
     * The row may be required by subclasses
     * Return whether the container changed
     */
    @Override
    public boolean addAll(List elements, Object container, AbstractSession session, List<AbstractRecord> dbRows, ObjectBuildingQuery query, CacheKey parentCacheKey, boolean isTargetProtected) {
        if(this.listOrderField == null) {
            return super.addAll(elements, container, session, dbRows, query, parentCacheKey, isTargetProtected);
        } else {
            return addAll(elements, container, session, dbRows, query, parentCacheKey);
        }
    }

    /**
     * INTERNAL:
     * Add a list of elements to container.
     * This is used to add to a collection independent of JDK 1.1 and 1.2.
     * The session may be required to wrap for the wrapper policy.
     * The row may be required by subclasses
     * Return whether the container changed
     */
    @Override
    public boolean addAll(List elements, Object container, AbstractSession session, List<AbstractRecord> dbRows, DataReadQuery query, CacheKey parentCacheKey, boolean isTargetProtected) {
        if(this.listOrderField == null) {
            return super.addAll(elements, container, session, dbRows, query, parentCacheKey, isTargetProtected);
        } else {
            return addAll(elements, container, session, dbRows, query, parentCacheKey);
        }
    }

    protected boolean addAll(List elements, Object container, AbstractSession session, List<AbstractRecord> dbRows, ReadQuery query, CacheKey parentCacheKey) {
        int size = dbRows.size();

        if(this.elementDescriptor != null && this.elementDescriptor.getObjectBuilder().hasWrapperPolicy()) {
            ObjectBuilder objectBuilder = this.elementDescriptor.getObjectBuilder();
            List wrappedElements = new ArrayList(size);
            for(int i=0; i < size; i++) {
                wrappedElements.add(objectBuilder.wrapObject(elements.get(i), session));
            }
            elements = wrappedElements;
        }

        ConversionManager conversionManager = session.getDatasourcePlatform().getConversionManager();

        // populate container with a dummy so the container.set(i, obj) could be used later.
        for(int i=0; i < size; i++) {
            ((List)container).add(NOT_SET);
        }
        // insert the elements into container
        boolean failed = false;
        for(int i=0; i < size; i++) {
            AbstractRecord row = dbRows.get(i);
            Object orderValue = row.get(this.listOrderField);
            // order value is null
            if(orderValue == null) {
                failed = true;
                break;
            }
            int intOrderValue = (Integer) conversionManager.convertObject(orderValue, Integer.class);
            try {
                // one or more elements have the same order value
                if(NOT_SET != ((List)container).set(intOrderValue, elements.get(i))) {
                    failed = true;
                    break;
                }
            } catch(IndexOutOfBoundsException indexException) {
                // order value negative or greater/equal to size
                failed = true;
                break;
            }
        }

        if(failed) {
            ((List)container).clear();

            // extract order list - it will be set into exception or used by order correction.
            List<Integer> orderList = new ArrayList(size);
            for(int i=0; i < size; i++) {
                AbstractRecord row = dbRows.get(i);
                Object orderValue = row.get(this.listOrderField);
                if(orderValue == null) {
                    orderList.add(null);
                } else {
                    orderList.add((Integer)conversionManager.convertObject(orderValue, Integer.class));
                }
            }

            if(this.orderCorrectionType == OrderCorrectionType.READ || this.orderCorrectionType == OrderCorrectionType.READ_WRITE) {
                // pair each element with its order index
                List<IndexedObject> indexedElements = new ArrayList(size);
                for(int i=0; i < size; i++) {
                    indexedElements.add(new IndexedObject(orderList.get(i), elements.get(i)));
                }

                // put elements in order and add to container
                ((List)container).addAll(correctOrderList(indexedElements));

                if(this.orderCorrectionType == OrderCorrectionType.READ_WRITE) {
                    // mark IndirectList to have broken order
                    ((IndirectList)container).setIsListOrderBrokenInDb(true);
                }
            } else {
                // this.orderCorrectionType == OrderCorrectionType.EXCEPTION
                throw QueryException.listOrderFieldWrongValue(query, this.listOrderField, orderList);
            }
        }
        return size > 0;
    }

    /**
     * INTERNAL:
     * Add element into a container which implements the List interface.
     * Add at a particular index.
     */
    protected void addIntoAtIndex(Integer index, Object object, Object container, AbstractSession session) {
        if (hasElementDescriptor()) {
            object = getElementDescriptor().getObjectBuilder().wrapObject(object, session);
        }

        try {
            if (index == null || (index > sizeFor(container))) {
                // The index can be larger than the size on a merge,
                // so should be added to the end, it may also be null if the
                // index was unknown, such as an event using the add API.
                ((List)container).add(object);
            } else {
                ((List)container).add(index, object);
            }
        } catch (ClassCastException ex1) {
            throw QueryException.cannotAddElement(object, container, ex1);
        } catch (IllegalArgumentException ex2) {
            throw QueryException.cannotAddElement(object, container, ex2);
        } catch (UnsupportedOperationException ex3) {
            throw QueryException.cannotAddElement(object, container, ex3);
        }
    }

    /**
     * INTERNAL:
     * This method is used to calculate the differences between two collections.
     * This algorithm is a work in progress. It works great and all, but like
     * anything, you can always make it better.
     */
    @Override
    public void compareCollectionsForChange(Object oldList, Object newList, CollectionChangeRecord changeRecord, AbstractSession session, ClassDescriptor referenceDescriptor) {
        List orderedObjectsToAdd = new ArrayList();
        Map indicesToRemove = new HashMap();
        Map oldListIndexValue = new HashMap();
        IdentityHashMap oldListValueIndex = new IdentityHashMap();
        IdentityHashMap objectsToAdd = new IdentityHashMap();
        Map<Object, Integer> newListValueIndex = new IdentityHashMap();

        // Step 1 - Go through the old list.
        if (oldList != null) {
            ListIterator iterator = (ListIterator)iteratorFor(oldList);

            while (iterator.hasNext()) {
                Integer index = iterator.nextIndex();
                Object value = iterator.next();
                oldListValueIndex.put(value, index);
                oldListIndexValue.put(index, value);
                indicesToRemove.put(index, index);
            }
        }

        // Step 2 - Go though the new list.
        if (newList != null) {
            // Step i - Gather the list info.
            ListIterator iterator = (ListIterator)iteratorFor(newList);
            while (iterator.hasNext()) {
                newListValueIndex.put(iterator.next(), iterator.previousIndex());
            }

            // Step ii - Go through the new list again.
            int index = 0;
            int offset = 0;
            iterator = (ListIterator)iteratorFor(newList);
            while (iterator.hasNext()) {
                index = iterator.nextIndex();
                Object currentObject = iterator.next();

                // If value is null then nothing can be done with it.
                if (currentObject != null) {
                    if (oldListValueIndex.containsKey(currentObject)) {
                        int oldIndex = (Integer) oldListValueIndex.get(currentObject);
                        oldListValueIndex.remove(currentObject);

                        if (index == oldIndex) {
                            indicesToRemove.remove(oldIndex);
                            offset = 0; // Reset the offset, assume we're back on track.
                        } else if (index == (oldIndex + offset)) {
                            // We're in the right spot according to the offset.
                            indicesToRemove.remove(oldIndex);
                        } else {
                            // Time to be clever and figure out why we're not in the right spot!
                            int movedObjects = 0;
                            int deletedObjects = 0;
                            boolean moved = true;

                            if (oldIndex < index) {
                                ++offset;
                            } else {
                                for (int i = oldIndex - 1; i >= index; i--) {
                                    Object oldObject = oldListIndexValue.get(i);
                                    if (newListValueIndex.containsKey(oldObject)) {
                                        ++movedObjects;
                                    } else {
                                        ++deletedObjects;
                                    }
                                }

                                if (index == ((oldIndex + offset) - deletedObjects)) {
                                    // We fell into place because of deleted objects.
                                    offset = offset - deletedObjects;
                                    moved = false;
                                } else if (movedObjects > 1) {
                                    // Assume we moved down, bumping everyone by one.
                                    ++offset;
                                } else {
                                    // Assume we moved down unless the object that was
                                    // here before is directly beside us.
                                    Object oldObject = oldListIndexValue.get(index);

                                    if (newListValueIndex.containsKey(oldObject)) {
                                        if ((newListValueIndex.get(oldObject) - index) > 1) {
                                            moved = false; // Assume the old object moved up.
                                            --offset;
                                        }
                                    }
                                }
                            }

                            if (moved) {
                                // Add ourselves to the ordered add list.
                                orderedObjectsToAdd.add(currentObject);
                            } else {
                                // Take us off the removed list.
                                indicesToRemove.remove(oldIndex);
                            }
                        }
                    } else {
                        ++offset;
                        objectsToAdd.put(currentObject, currentObject);
                        orderedObjectsToAdd.add(currentObject);
                    }
                } else {
                    // If we find nulls we need decrease our offset.
                    offset--;
                }
            }
        }

        // Sort the remove indices that are left and set the data on the collection change
        // record to be processed on the merge.
        List orderedIndicesToRemove = new ArrayList(indicesToRemove.values());
        Collections.sort(orderedIndicesToRemove);
        changeRecord.addAdditionChange(objectsToAdd, this, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session);
        changeRecord.addRemoveChange(oldListValueIndex, this, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session);
        changeRecord.addOrderedAdditionChange(orderedObjectsToAdd, newListValueIndex, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session);
        changeRecord.addOrderedRemoveChange(orderedIndicesToRemove, oldListIndexValue, (UnitOfWorkChangeSet) changeRecord.getOwner().getUOWChangeSet(), session);
    }

    /**
     * PUBLIC:
     * Correct object's order in the list.
     * The method is called only in one case - when the list of order indexes read from db is invalid
     * (contains nulls, duplicates, negative values, values greater/equal list size).
     * Each element of the indexedObjects is a pair of the order index and the corresponding object.
     * The goal of the method is to return back the list of objects (not indexed objects!) in the correct order.
     * The objects should not be altered.
     *
     * The default implementation of the method sorts indexedObjects according to their indexes (null less than any non-null).
     * For example:
     *   indexedObjects = {{2, objectA}, {5, ObjectB}}  returns {objectA, objectB};
     *   indexedObjects = {{2, objectA}, {-1, ObjectB}}  returns {objectB, objectA};
     *   indexedObjects = {{2, objectA}, {null, ObjectB}}  returns {objectB, objectA};
     *
     * This method could be overridden by the user.
     */
    public List correctOrderList(List<IndexedObject> indexedObjects) {
        Collections.sort(indexedObjects);
        int size = indexedObjects.size();
        List objects = new ArrayList(size);
        for(int i=0; i < size; i++) {
            objects.add(indexedObjects.get(i).getObject());
        }
        return objects;
    }

    /**
     * INTERNAL:
     * Used to create an iterator on a the Map object passed to CollectionChangeRecord.addRemoveChange()
     * to access the values to be removed.  In the case of some container policies the values will actually
     * be the keys.
     */
    @Override
    public Iterator getChangeValuesFrom(Map map) {
        return map.keySet().iterator();
    }

    public DatabaseField getListOrderField() {
        return this.listOrderField;
    }

    public void setListOrderField(DatabaseField field) {
        this.listOrderField = field;
    }

    public OrderCorrectionType getOrderCorrectionType() {
        return this.orderCorrectionType;
    }

    public void setOrderCorrectionType(OrderCorrectionType orderCorrectionType) {
        if(this.orderCorrectionType == orderCorrectionType) {
            return;
        }
        if(orderCorrectionType == OrderCorrectionType.READ_WRITE) {
            if(getContainerClass() == null || !IndirectList.class.isAssignableFrom(getContainerClass())) {
                setContainerClass(IndirectList.class);
            }
        }
        this.orderCorrectionType = orderCorrectionType;
    }

    /**
     * INTERNAL:
     * Return an list iterator for the given container.
     */
    @Override
    public Object iteratorFor(Object container) {
        return ((List)container).listIterator();
    }

    @Override
    public boolean isOrderedListPolicy() {
        return true;
    }

    /**
     * INTERNAL:
     * Merge changes from the source to the target object. Because this is a
     * collection mapping, values are added to or removed from the collection
     * based on the change set.
     * Synchronize if system property is specified. If not, default to clone the
     * target collection. No need to synchronize if the collection is new.
     */
    @Override
    public void mergeChanges(CollectionChangeRecord changeRecord, Object valueOfTarget, boolean shouldMergeCascadeParts, MergeManager mergeManager, AbstractSession targetSession, boolean isSynchronizeOnMerge) {
        if (isSynchronizeOnMerge && !changeRecord.getOwner().isNew()) {
            // Ensure the collection is synchronized while changes are being made,
            // clone also synchronizes on collection (does not have cache key read-lock for indirection).
            // Must synchronize of the real collection as the clone does so.
            Object synchronizedValueOfTarget = valueOfTarget;
            if (valueOfTarget instanceof IndirectCollection) {
                synchronizedValueOfTarget = ((IndirectCollection)valueOfTarget).getDelegateObject();
            }
            synchronized(synchronizedValueOfTarget) {
                mergeChanges(changeRecord, valueOfTarget, shouldMergeCascadeParts, mergeManager, targetSession);
            }
        } else {
            mergeChanges(changeRecord, valueOfTarget, shouldMergeCascadeParts, mergeManager, targetSession);
        }
    }

    /**
     * INTERNAL:
     * Merge changes from the source to the target object. Because this is a
     * collection mapping, values are added to or removed from the collection
     * based on the change set.
     */
    @Override
    protected void mergeChanges(CollectionChangeRecord changeRecord, Object valueOfTarget, boolean shouldMergeCascadeParts, MergeManager mergeManager, AbstractSession targetSession) {
        ObjectChangeSet objectChanges;
        if(changeRecord.orderHasBeenRepaired() && valueOfTarget instanceof IndirectList) {
            ((IndirectList)valueOfTarget).setIsListOrderBrokenInDb(false);
        }
        if (!changeRecord.getOrderedChangeObjectList().isEmpty()) {
            Iterator objects =changeRecord.getOrderedChangeObjectList().iterator();
            while (objects.hasNext()){
                OrderedChangeObject changeObject = (OrderedChangeObject)objects.next();
                objectChanges = changeObject.getChangeSet();
                if (changeObject.getChangeType() == CollectionChangeEvent.REMOVE){
                    boolean objectRemoved = changeRecord.getRemoveObjectList().containsKey(objectChanges);
                    Object objectToRemove = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);

                    //if objectToRemove is null, we can't look it up in the collection.
                    // This should not happen unless identity is lost.
                    if (objectToRemove != null) {
                        Integer index = changeObject.getIndex();
                        if (index!=null){
                            if (objectToRemove.equals(get(index, valueOfTarget, mergeManager.getSession()))) {
                                removeFromAtIndex(index, valueOfTarget);
                            } else {
                                // Object is in the cache, but the collection doesn't have it at the location we expect
                                // Collection is invalid with respect to these changes, so invalidate the parent and abort
                                Object key = changeRecord.getOwner().getId();
                                targetSession.getIdentityMapAccessor().invalidateObject(key, changeRecord.getOwner().getClassType(targetSession));
                                return;
                            }
                        } else {
                            removeFrom(objectToRemove, valueOfTarget, targetSession);
                        }

                        if ((! mergeManager.shouldMergeChangesIntoDistributedCache()) && changeRecord.getMapping().isPrivateOwned()) {
                            // Check that the object was actually removed and not moved.
                            if (objectRemoved) {
                                mergeManager.registerRemovedNewObjectIfRequired(objectChanges.getUnitOfWorkClone());
                            }
                        }
                    }


                } else { //getChangeType == add
                    boolean objectAdded = changeRecord.getAddObjectList().containsKey(objectChanges);
                    Object object = null;
                    // The object was actually added and not moved.
                    if (objectAdded && shouldMergeCascadeParts) {
                        object = mergeCascadeParts(objectChanges, mergeManager, targetSession);
                    }

                    if (object == null) {
                        // Retrieve the object to be added to the collection.
                        object = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                    }

                    // Assume at this point the above merge will have created a new
                    // object if required and that the object was actually added and
                    // not moved.
                    if (objectAdded && mergeManager.shouldMergeChangesIntoDistributedCache()) {
                        // Bugs 4458089 & 4454532 - check if collection contains new item before adding
                        // during merge into distributed cache
                        if (! contains(object, valueOfTarget, mergeManager.getSession())) {
                            addIntoAtIndex(changeObject.getIndex(), object, valueOfTarget, mergeManager.getSession());
                        }
                    } else {
                        addIntoAtIndex(changeObject.getIndex(), object, valueOfTarget, targetSession);
                    }
                }
            }
        } else {
            //Deferred change tracking merge behavior
            // Step 1 - iterate over the removed changes and remove them from the container.
            List<Integer> removedIndices = changeRecord.getOrderedRemoveObjectIndices();

            if (removedIndices.isEmpty()) {
                // Check if we have removed objects via a
                // simpleRemoveFromCollectionChangeRecord API call.
                Iterator removedObjects = changeRecord.getRemoveObjectList().keySet().iterator();

                while (removedObjects.hasNext()) {
                    objectChanges = (ObjectChangeSet) removedObjects.next();
                    removeFrom(objectChanges.getOldKey(), objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession), valueOfTarget, targetSession);
                    registerRemoveNewObjectIfRequired(objectChanges, mergeManager);
                }
            } else {
                for (int i = removedIndices.size() - 1; i >= 0; i--) {
                    Integer index = removedIndices.get(i);
                    objectChanges = (ObjectChangeSet) changeRecord.getOrderedRemoveObject(index);
                    Object objectToRemove = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                    if ( (objectToRemove!=null) &&
                                (objectToRemove.equals(get(index, valueOfTarget, mergeManager.getSession()) )) ) {
                        removeFromAtIndex(index, valueOfTarget);
                        // The object was actually removed and not moved.
                        if (changeRecord.getRemoveObjectList().containsKey(objectChanges)) {
                            registerRemoveNewObjectIfRequired(objectChanges, mergeManager);
                        }
                    } else {

                        //Object is either not in the cache, or not at the location we expect
                        // Collection is invalid with respect to these changes, so invalidate the parent and abort
                        Object key = changeRecord.getOwner().getId();
                        targetSession.getIdentityMapAccessor().invalidateObject(key, changeRecord.getOwner().getClassType(targetSession));
                        return;
                    }
                }
            }

            // Step 2 - iterate over the added changes and add them to the container.
            for (ObjectChangeSet addChangeSet : changeRecord.getOrderedAddObjects()) {
                objectChanges =  addChangeSet;
                boolean objectAdded = changeRecord.getAddObjectList().containsKey(objectChanges);
                Object object = null;

                // The object was actually added and not moved.
                if (objectAdded && shouldMergeCascadeParts) {
                    object = mergeCascadeParts(objectChanges, mergeManager, targetSession);
                }

                if (object == null) {
                    // Retrieve the object to be added to the collection.
                    object = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                }

                // Assume at this point the above merge will have created a new
                // object if required and that the object was actually added and
                // not moved.
                if (objectAdded && mergeManager.shouldMergeChangesIntoDistributedCache()) {
                    // Bugs 4458089 & 4454532 - check if collection contains new item before adding
                    // during merge into distributed cache
                    if (! contains(object, valueOfTarget, mergeManager.getSession())) {
                        addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, mergeManager.getSession());
                    }
                } else {
                    addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, targetSession);
                }
            }
        }
    }

    /**
     * INTERNAL:
     */
    protected void registerRemoveNewObjectIfRequired(ObjectChangeSet objectChanges, MergeManager mergeManager) {
        if (! mergeManager.shouldMergeChangesIntoDistributedCache()) {
            mergeManager.registerRemovedNewObjectIfRequired(objectChanges.getUnitOfWorkClone());
        }
    }

    /**
     * INTERNAL:
     * Remove the element at the specified index.
     */
    protected void removeFromAtIndex(int index, Object container) {
        try {
            ((List) container).remove(index);
        } catch (ClassCastException ex1) {
            throw QueryException.cannotRemoveFromContainer(index, container, this);
        } catch (IllegalArgumentException ex2) {
            throw QueryException.cannotRemoveFromContainer(index, container, this);
        } catch (UnsupportedOperationException ex3) {
            throw QueryException.cannotRemoveFromContainer(index, container, this);
        }
    }

    /**
     * This method is used to bridge the behavior between Attribute Change Tracking and
     * deferred change tracking with respect to adding the same instance multiple times.
     * Each ContainerPolicy type will implement specific behavior for the collection
     * type it is wrapping.  These methods are only valid for collections containing object references
     */
    @Override
    public void recordAddToCollectionInChangeRecord(ObjectChangeSet changeSetToAdd, CollectionChangeRecord collectionChangeRecord){
        OrderedChangeObject orderedChangeObject = new OrderedChangeObject(CollectionChangeEvent.ADD, null, changeSetToAdd);
        collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
    }

    @Override
    public void recordRemoveFromCollectionInChangeRecord(ObjectChangeSet changeSetToRemove, CollectionChangeRecord collectionChangeRecord){
        OrderedChangeObject orderedChangeObject = new OrderedChangeObject(CollectionChangeEvent.REMOVE, null, changeSetToRemove);
        collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
    }

    @Override
    public void recordUpdateToCollectionInChangeRecord(CollectionChangeEvent event, ObjectChangeSet changeSet, CollectionChangeRecord collectionChangeRecord){
        int changeType = event.getChangeType();
        if (changeType == CollectionChangeEvent.ADD) {
            super.recordAddToCollectionInChangeRecord(changeSet, collectionChangeRecord);
        } else if (changeType == CollectionChangeEvent.REMOVE) {
            super.recordRemoveFromCollectionInChangeRecord(changeSet, collectionChangeRecord);
        } else {
            throw ValidationException.wrongCollectionChangeEventType(changeType);
        }

        OrderedChangeObject orderedChangeObject = new OrderedChangeObject(changeType, event.getIndex(), changeSet, event.getNewValue());
        collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
    }

    /**
     * INTERNAL:
     * Indicates whether addAll method should be called to add entire collection,
     * or it's possible to call addInto multiple times instead.
     */
    @Override
    public boolean shouldAddAll() {
        return this.listOrderField != null;
    }

    /**
     * INTERNAL:
     * Return any additional fields required by the policy for a fetch join.
     */
    @Override
    public List<DatabaseField> getAdditionalFieldsForJoin(CollectionMapping baseMapping) {
        if (this.listOrderField != null) {
            List<DatabaseField> fields = new ArrayList<>(1);
            fields.add(this.listOrderField);
            return fields;
        }
        return null;
    }

    /**
     * INTERNAL:
     * Add the index field count.
     */
    @Override
    public int updateJoinedMappingIndexesForMapKey(Map<DatabaseMapping, Object> indexList, int index) {
        if (this.listOrderField != null) {
            return 1;
        }
        return 0;
    }

    /**
     * INTERNAL:
     * Update a ChangeRecord to replace the ChangeSet for the old entity with the changeSet for the new Entity.  This is
     * used when an Entity is merged into itself and the Entity reference new or detached entities.
     */
    @Override
    public void updateChangeRecordForSelfMerge(ChangeRecord changeRecord, Object source, Object target, ForeignReferenceMapping mapping, UnitOfWorkChangeSet parentUOWChangeSet, UnitOfWorkImpl unitOfWork){
        ObjectChangeSet sourceSet = parentUOWChangeSet.getCloneToObjectChangeSet().get(source);
        for (OrderedChangeObject changeObject : ((CollectionChangeRecord)changeRecord).getOrderedChangeObjectList()){
            if (changeObject.getChangeSet() == sourceSet){
                changeObject.setChangeSet(((UnitOfWorkChangeSet)unitOfWork.getUnitOfWorkChangeSet()).findOrCreateLocalObjectChangeSet(target, mapping.getReferenceDescriptor(), unitOfWork.isCloneNewObject(target)));
            }
            return;
        }
    }

    /**
     * INTERNAL:
     * Return any tables that will be required when this mapping is used as part of a join query.
     */
    @Override
    public List<DatabaseTable> getAdditionalTablesForJoinQuery() {
        if (this.listOrderField != null) {
            List tables = new ArrayList(1);
            tables.add(this.listOrderField.getTable());
            return tables;
        }
        return null;
    }

    /**
     * INTERNAL:
     * Add the index field to the query.
     */
    @Override
    public void addAdditionalFieldsToQuery(ReadQuery selectionQuery, Expression baseExpression) {
        if (this.listOrderField != null) {
            if (selectionQuery.isObjectLevelReadQuery()) {
                ((ObjectLevelReadQuery)selectionQuery).addAdditionalField(baseExpression.getField(this.listOrderField));
            } else {
                ((SQLSelectStatement) selectionQuery.getSQLStatement()).addField(baseExpression.getField(this.listOrderField));
            }
        }
    }
}
