Esempio n. 1
0
        //static int count = 10000000;

        ////[TestInitialize]
        //public void InitManually()
        //{
        //    base.InitManually(GetType());
        //}

        //static Object[] objects;

        //static ValueHolderContainerTest()
        //{
        //     objects = new Object[count];
        //        for (int a = count; a-- > 0; )
        //        {
        //            objects[a] = new Object();
        //        }
        //}

        //[TestMethod]
        //public void test_Dictionary()
        //{
        //    Dictionary<Object, Object> dict = new Dictionary<Object, Object>(count, new IdentityEqualityComparer<Object>());

        //    //for (int a = count; a-- > 0; )
        //    //{
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //}
        //    for (int a = count; a-- > 0; )
        //    {
        //        dict.Add(a, objects[a]);
        //    }
        //    for (int a = 10; a-- > 0; )
        //    {
        //        foreach (KeyValuePair<Object, Object> entry in dict)
        //        {
        //            Object key = entry.Key;
        //            Object value = entry.Value;
        //            if (!Object.ReferenceEquals(objects[(int)key], value))
        //            {
        //                throw new Exception();
        //            }
        //        }
        //    }
        //}

        //[TestMethod]
        //public void test_HashMap()
        //{
        //    IdentityLinkedMap<Object, Object> dict = IdentityLinkedMap<Object, Object>.Create(count);

        //    //for (int a = count; a-- > 0; )
        //    //{
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //}
        //    for (int a = count; a-- > 0; )
        //    {
        //        dict.Put(a, objects[a]);
        //    }
        //    for (int a = 10; a-- > 0; )
        //    {
        //        foreach (Entry<Object, Object> entry in dict)
        //        {
        //            Object key = entry.Key;
        //            Object value = entry.Value;
        //            if (!Object.ReferenceEquals(objects[(int)key], value))
        //            {
        //                throw new Exception();
        //            }
        //        }
        //    }
        //}

        //[TestMethod]
        //public void test_PropertyInfo()
        //{
        //    Material mat = new Material();

        //    PropertyInfo pi = mat.GetType().GetProperty("Name");

        //    DateTime prePi = DateTime.Now;
        //    for (int a = count; a-- > 0; )
        //    {
        //        Object piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //    }
        //    DateTime postPi = DateTime.Now;
        //    long piTime = postPi.Ticks - prePi.Ticks;
        //    Console.WriteLine(piTime);
        //}

        //[TestMethod]
        //public void test_GetDelegate()
        //{
        //    Material mat = new Material();

        //    MemberGetDelegate del = TypeUtility.GetMemberGetDelegate(mat.GetType(), "Name");

        //    MemberSetDelegate setDel = TypeUtility.GetMemberSetDelegate(mat.GetType(), "Id");

        //    setDel(mat, 5);

        //    DateTime preDel = DateTime.Now;
        //    for (int a = count; a-- > 0; )
        //    {
        //        Object delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //    }
        //    DateTime postDel = DateTime.Now;

        //    long delTime = postDel.Ticks - preDel.Ticks;
        //    Console.WriteLine(delTime);
        //}

        protected void WaitForUI()
        {
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                // Intended blank
            });
        }
Esempio n. 2
0
 public void ApplyChangesToOriginals(ICUDResult cudResult, IOriCollection oriCollection, ICache cache)
 {
     if (GuiThreadHelper.IsInGuiThread())
     {
         ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache);
         return;
     }
     GuiThreadHelper.InvokeInGuiAndWait(new IBackgroundWorkerDelegate(delegate()
     {
         ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache);
     }));
 }
        public virtual void Populate()
        {
            var localRequest = new Object();

            lock (currentRequestLock)
            {
                currentRequest = localRequest;
            }
            if (GuiThreadHelper.IsInGuiThread())
            {
                IFilterDescriptor       filterDescriptor = GetFilterDescriptor();
                IList <ISortDescriptor> sortDescriptors  = GetSortDescriptors();
                IPagingRequest          pagingRequest    = GetPagingRequest();
                Object[] contextInformation = GetContextInformation();

                Model.IsBusy = true;
                ThreadPool.Queue((GenericViewModel <T> model) =>
                {
                    CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate()
                    {
                        ConfigureCacheWithEagerLoads(Cache);
                        PopulateAsync(model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest);
                        return(null);
                    });
                }, Model);
            }
            else
            {
                IFilterDescriptor       filterDescriptor = null;
                IList <ISortDescriptor> sortDescriptors  = null;
                IPagingRequest          pagingRequest    = null;
                Object[] contextInformation = null;
                GuiThreadHelper.InvokeInGuiAndWait(delegate()
                {
                    filterDescriptor = GetFilterDescriptor();
                    sortDescriptors  = GetSortDescriptors();
                    pagingRequest    = GetPagingRequest();

                    contextInformation = GetContextInformation();

                    Model.IsBusy = true;
                });
                CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate()
                {
                    ConfigureCacheWithEagerLoads(Cache);
                    PopulateAsync(Model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest);
                    return(null);
                });
            }
        }
Esempio n. 4
0
        protected void DataChangedIntern(IDataChange dataChange, IList <Object> pausedEventTargets, IProcessResumeItem processResumeItem, CacheDependencyNode rootNode)
        {
            try
            {
                bool isLocalSource = dataChange.IsLocalSource;
                IList <IDataChangeEntry> deletes = dataChange.Deletes;
                IList <IDataChangeEntry> updates = dataChange.Updates;
                IList <IDataChangeEntry> inserts = dataChange.Inserts;

                CHashSet <Type>    occuringTypes       = new CHashSet <Type>();
                CHashSet <IObjRef> deletesSet          = new CHashSet <IObjRef>();
                CHashSet <Type>    directRelatingTypes = new CHashSet <Type>();
                bool acquirementSuccessful             = rootNode.rootCache.AcquireHardRefTLIfNotAlready();
                try
                {
                    for (int a = deletes.Count; a-- > 0;)
                    {
                        IDataChangeEntry deleteEntry = deletes[a];
                        Type             entityType  = deleteEntry.EntityType;
                        occuringTypes.Add(entityType);
                        if (deleteEntry is DirectDataChangeEntry)
                        {
                            // Ignore delete entries of unpersisted objects here
                            continue;
                        }
                        ObjRef tempORI = new ObjRef(entityType, deleteEntry.IdNameIndex, deleteEntry.Id, deleteEntry.Version);
                        deletesSet.Add(tempORI);
                    }
                    // Remove items from the cache only if they are really deleted/updates by a remote event
                    // And not 'simulated' by a local source
                    bool cleanupSecondLevelCaches = false;
                    if (pausedEventTargets != null && (deletes.Count > 0 || updates.Count > 0) && !isLocalSource)
                    {
                        cleanupSecondLevelCaches = true;
                    }
                    else if (updates.Count > 0)
                    {
                        for (int a = updates.Count; a-- > 0;)
                        {
                            IDataChangeEntry updateEntry = updates[a];
                            Type             entityType  = updateEntry.EntityType;
                            occuringTypes.Add(entityType);
                        }
                    }
                    for (int a = inserts.Count; a-- > 0;)
                    {
                        IDataChangeEntry insertEntry = inserts[a];
                        Type             entityType  = insertEntry.EntityType;
                        occuringTypes.Add(entityType);
                    }
                    EnsureMetaDataIsLoaded(occuringTypes, directRelatingTypes);

                    if (cleanupSecondLevelCaches)
                    {
                        CleanupSecondLevelCaches(rootNode, deletesSet.ToList(), updates, occuringTypes);
                    }

                    BuildCacheChangeItems(rootNode, dataChange);

                    rootNode.AggregateAllCascadedObjRefs();

                    ISet <IObjRef> intermediateDeletes = rootNode.lookForIntermediateDeletes();

                    ChangeSecondLevelCache(rootNode);

                    if (rootNode.IsPendingChangeOnAnyChildCache())
                    {
                        GuiThreadHelper.InvokeInGuiAndWait(delegate()
                        {
                            bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive;
                            AbstractCache.FailInCacheHierarchyModeActive = true;
                            try
                            {
                                ChangeFirstLevelCaches(rootNode, intermediateDeletes);
                            }
                            finally
                            {
                                AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive;
                            }
                        });
                    }
                }
                finally
                {
                    rootNode.rootCache.ClearHardRefs(acquirementSuccessful);
                }
            }
            finally
            {
                if (processResumeItem != null)
                {
                    processResumeItem.ResumeProcessingFinished();
                }
            }
        }
        public virtual void DataChanged(IDataChange dataChange, DateTime dispatchTime, long sequenceId)
        {
            dataChange = dataChange.Derive(InterestedEntityTypes);
            if (dataChange.IsEmpty)
            {
                return;
            }
            ISet <Object> directObjectsToDelete = null;

            ISet <Type> requestedTypes = new HashSet <Type>();
            IDictionary <Type, IEntityMetaData> typeToMetaDataDict = new Dictionary <Type, IEntityMetaData>();

            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                IList <T> entities = Model.Objects;

                for (int i = entities.Count; i-- > 0;)
                {
                    Object entity = entities[i];

                    requestedTypes.Add(entity.GetType());
                }
            });

            IList <IDataChangeEntry> dataChangeEntries = dataChange.Inserts;

            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }
            dataChangeEntries = dataChange.Updates;
            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }
            dataChangeEntries = dataChange.Deletes;
            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }

            IList <IEntityMetaData> metaDatas = EntityMetaDataProvider.GetMetaData(ListUtil.ToList(requestedTypes));

            foreach (IEntityMetaData metaData in metaDatas)
            {
                typeToMetaDataDict[metaData.EntityType] = metaData;
            }

            bool consistsOnlyOfDirectDeletes = false;

            if (dataChange.Deletes.Count > 0)
            {
                consistsOnlyOfDirectDeletes = true;
                foreach (IDataChangeEntry deleteEntry in dataChange.Deletes)
                {
                    if (deleteEntry is DirectDataChangeEntry)
                    {
                        if (directObjectsToDelete == null)
                        {
                            directObjectsToDelete = new IdentityHashSet <Object>();
                        }
                        directObjectsToDelete.Add(((DirectDataChangeEntry)deleteEntry).Entry);
                    }
                    else
                    {
                        consistsOnlyOfDirectDeletes = false;
                    }
                }
            }

            IList <T> interestingEntities = null;

            Object[]                contextInformation = GetContextInformation();
            IFilterDescriptor       filterDescriptor   = GetFilterDescriptor();
            IList <ISortDescriptor> sortDescriptors    = GetSortDescriptors();
            IPagingRequest          pagingRequest      = GetPagingRequest();

            IPagingResponse         pagingResponse  = null;
            List <IDataChangeEntry> modifiedEntries = new List <IDataChangeEntry>();

            modifiedEntries.AddRange(dataChange.All);

            if (!consistsOnlyOfDirectDeletes)
            {
                interestingEntities = CacheContext.ExecuteWithCache(CacheProvider.GetCurrentCache(), delegate()
                {
                    ConfigureCacheWithEagerLoads(Cache);
                    if (Refresher is IPagingRefresher <T> )
                    {
                        interestingEntities = new List <T>();
                        pagingResponse      = ((IPagingRefresher <T>)Refresher).Refresh(modifiedEntries, filterDescriptor, sortDescriptors, pagingRequest, contextInformation);
                        foreach (Object obj in pagingResponse.Result)
                        {
                            interestingEntities.Add((T)obj);
                        }
                        return(interestingEntities);
                    }
                    else
                    {
                        if (filterDescriptor != null || sortDescriptors != null)
                        {
                            contextInformation    = new Object[2];
                            contextInformation[0] = filterDescriptor;
                            contextInformation[1] = sortDescriptors;
                        }

                        return(((IRefresher <T>)Refresher).Refresh(modifiedEntries, contextInformation));
                    }
                });
            }
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                IList <T> entities = Model.Objects;

                ISet <T> entitiesToAdd                           = null;
                ISet <T> entitiesToRemove                        = null;
                IDictionary <T, T> entitiesToReplace             = null;
                IDictionary <IObjRef, T> oldObjRefToOldEntityMap = null;
                bool mergeModel = false;

                if (interestingEntities != null && interestingEntities.Count > 0)
                {
                    entitiesToAdd           = new IdentityHashSet <T>(interestingEntities);
                    entitiesToRemove        = new IdentityHashSet <T>(entities);
                    entitiesToReplace       = new IdentityDictionary <T, T>();
                    oldObjRefToOldEntityMap = new Dictionary <IObjRef, T>();
                    mergeModel = true;
                }
                for (int i = entities.Count; i-- > 0;)
                {
                    T oldEntity = entities[i];
                    if (directObjectsToDelete != null && directObjectsToDelete.Contains(oldEntity))
                    {
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        Model.RemoveAt(i);
                        continue;
                    }
                    Type oldEntityType       = ProxyHelper.GetRealType(oldEntity.GetType());
                    PrimitiveMember idMember = typeToMetaDataDict[oldEntityType].IdMember;
                    Object oldEntityId       = idMember.GetValue(oldEntity, false);
                    if (oldEntityId == null)
                    {
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        // Unpersisted object. This object should not be removed
                        // only because of a background DCE
                        continue;
                    }
                    bool entryRemoved = false;
                    foreach (IDataChangeEntry deleteEntry in dataChange.Deletes)
                    {
                        if (deleteEntry is DirectDataChangeEntry)
                        {
                            continue;
                        }
                        Object id = deleteEntry.Id;
                        if (!EqualsItems(oldEntityType, oldEntityId, deleteEntry.EntityType, id))
                        {
                            continue;
                        }
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        Model.RemoveAt(i);
                        entryRemoved = true;
                        break;
                    }
                    if (entryRemoved)
                    {
                        continue;
                    }
                    if (mergeModel)
                    {
                        IObjRef oldObjRef   = new ObjRef(oldEntityType, ObjRef.PRIMARY_KEY_INDEX, oldEntityId, null);
                        T existingOldEntity = DictionaryExtension.ValueOrDefault(oldObjRefToOldEntityMap, oldObjRef);
                        if (existingOldEntity == null)
                        {
                            oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity);
                        }
                        else if (!Object.ReferenceEquals(existingOldEntity, oldEntity))
                        {
                            // Force duplicate key exception
                            oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity);
                        }
                    }
                }
                if (oldObjRefToOldEntityMap != null && oldObjRefToOldEntityMap.Count > 0)
                {
                    IDictionary <IObjRef, T> newObjRefToNewEntityMap = new Dictionary <IObjRef, T>();
                    for (int a = interestingEntities.Count; a-- > 0;)
                    {
                        T newEntity              = interestingEntities[a];
                        Type newEntityType       = ProxyHelper.GetRealType(newEntity.GetType());
                        PrimitiveMember idMember = typeToMetaDataDict[newEntityType].IdMember;
                        Object newEntityId       = idMember.GetValue(newEntity, false);

                        IObjRef newObjRef = new ObjRef(newEntityType, ObjRef.PRIMARY_KEY_INDEX, newEntityId, null);
                        newObjRefToNewEntityMap.Add(newObjRef, newEntity);
                    }
                    DictionaryExtension.Loop(oldObjRefToOldEntityMap, delegate(IObjRef objRef, T oldEntity)
                    {
                        T newEntity = DictionaryExtension.ValueOrDefault(newObjRefToNewEntityMap, objRef);
                        if (newEntity == null)
                        {
                            // Nothing to do if current oldEntity has no corresponding newEntity
                            return;
                        }
                        entitiesToAdd.Remove(newEntity);
                        if (!Object.ReferenceEquals(oldEntity, newEntity) &&
                            (dataChange.IsLocalSource || !(oldEntity is IDataObject) || !((IDataObject)oldEntity).ToBeUpdated))
                        {
                            entitiesToReplace[oldEntity] = newEntity;
                        }
                        entitiesToRemove.Remove(oldEntity);
                    });
                }

                if (mergeModel)
                {
                    for (int a = entities.Count; a-- > 0;)
                    {
                        T item = entities[a];
                        if (entitiesToRemove.Contains(item))
                        {
                            Model.RemoveAt(a);
                            continue;
                        }
                        T replacingItem = DictionaryExtension.ValueOrDefault(entitiesToReplace, item);
                        if (replacingItem != null)
                        {
                            Model.Replace(a, replacingItem);
                            continue;
                        }
                    }
                    IEnumerator <T> enumerator = entitiesToAdd.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        T entityToAdd = enumerator.Current;
                        Model.Add(entityToAdd);
                    }

                    if (hasPagedViewModel)
                    {
                        UpdatePagingInformation(pagingResponse);
                    }
                    UpdateAfterDCE();
                }
            });
        }
Esempio n. 6
0
        public void test_PropertyChange_OutOfGuiThread()
        {
            HashMap <String, IMap <Thread, int> > counter = new HashMap <String, IMap <Thread, int> >();
            PropertyChangedEventHandler           handler = GetPropertyChangeHandlerForUI(counter);

            Thread         workerThread = null;
            CountDownLatch latch        = new CountDownLatch(1);

            ThreadPool.Queue(delegate()
            {
                workerThread = Thread.CurrentThread;
                Log.Info("Test()");
                try
                {
                    Material obj = EntityFactory.CreateEntity <Material>();
                    ((INotifyPropertyChanged)obj).PropertyChanged += handler;

                    Log.Info("ICacheModification.set_Active(true)");
                    CacheModification.Active = true;
                    try
                    {
                        Log.Info("set_Id");
                        obj.Id = 1;
                        Log.Info("set_Id finished");
                        Assert.AssertEquals(0, counter.Count);
                    }
                    finally
                    {
                        Log.Info("ICacheModification.set_Active(false)");
                        CacheModification.Active = false;
                        Log.Info("ICacheModification.set_Active(false) finished");
                    }
                    WaitForUI();
                    Assert.AssertEquals(3, counter.Count);
                    Log.Info(" set_Name");
                    obj.Name = "hallo";
                    WaitForUI();
                    Log.Info("set_Name finished");
                    Assert.AssertEquals(5, counter.Count);
                }
                finally
                {
                    latch.CountDown();
                }
            });
            Log.Info("Await()");
            latch.Await();
            // Wait till the current ui queue has been processed completely
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                // just an empty blocking delegate
            });
            Assert.AssertEquals(5, counter.Count);

            Thread guiThread = ValueHolderContainerTestModule.dispatcherThread;

            IMap <Thread, int> toBeCreatedMap = counter.Get("ToBeCreated");

            Assert.AssertNotNull(toBeCreatedMap);
            Assert.AssertEquals(1, toBeCreatedMap.Count);
            Assert.AssertTrue(toBeCreatedMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, toBeCreatedMap.Get(guiThread));

            IMap <Thread, int> idMap = counter.Get("Id");

            Assert.AssertNotNull(idMap);
            Assert.AssertEquals(1, idMap.Count);
            Assert.AssertTrue(idMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, idMap.Get(guiThread));

            // uiThread is intended for Name in the case where asynchronous PCEs are allowed
            // but dispatched transparently in the UI
            IMap <Thread, int> nameMap = counter.Get("Name");

            Assert.AssertNotNull(nameMap);
            Assert.AssertEquals(1, nameMap.Count);
            Assert.AssertTrue(idMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, nameMap.Get(guiThread));

            IMap <Thread, int> toBeUpdatedMap = counter.Get("ToBeUpdated");

            Assert.AssertNotNull(toBeUpdatedMap);
            Assert.AssertEquals(1, toBeUpdatedMap.Count);
            Assert.AssertTrue(toBeUpdatedMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, toBeUpdatedMap.Get(guiThread));

            IMap <Thread, int> hasPendingChangesMap = counter.Get("HasPendingChanges");

            Assert.AssertNotNull(hasPendingChangesMap);
            Assert.AssertEquals(1, hasPendingChangesMap.Count);
            Assert.AssertTrue(hasPendingChangesMap.ContainsKey(guiThread));
            Assert.AssertEquals(2, hasPendingChangesMap.Get(guiThread));
        }
Esempio n. 7
0
        protected void ProcessPendingOrelsAndObjRefs(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath,
                                                     AlreadyHandledSet alreadyHandledSet, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory,
                                                     IdentityLinkedMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad,
                                                     IdentityLinkedMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad, List <PrefetchCommand> pendingPrefetchCommands,
                                                     List <Object> hardRefList)
        {
            // all relation members where at least one instance of the owning entity type needs a prefetch on this member in the immediate next step
            MergePrefetchPathsCache mergePrefetchPathsCache = new MergePrefetchPathsCache(EntityMetaDataProvider);

            IdentityLinkedSet <Member> prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);

            LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
            LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);

            while (pendingPrefetchCommands.Count > 0)
            {
                PrefetchCommand[] currentPrefetchCommands = pendingPrefetchCommands.ToArray();
                // Clear the items to be ready for cascaded items in new batch recursion step
                pendingPrefetchCommands.Clear();
                if (prioMembers.Count > 0)
                {
                    for (int a = 0, size = currentPrefetchCommands.Length; a < size; a++)
                    {
                        PrefetchCommand      prefetchCommand = currentPrefetchCommands[a];
                        DirectValueHolderRef valueHolder     = prefetchCommand.valueHolder;
                        if (!prioMembers.Contains(valueHolder.Member))
                        {
                            currentPrefetchCommands[a] = null;
                            pendingPrefetchCommands.Add(prefetchCommand);
                        }
                    }
                }
                GuiThreadHelper.InvokeInGuiAndWait(delegate()
                {
                    ICacheModification cacheModification = CacheModification;
                    ValueHolderContainerMixin valueHolderContainerMixin = ValueHolderContainerMixin;
                    bool oldActive = cacheModification.Active;
                    if (!oldActive)
                    {
                        cacheModification.Active = true;
                    }
                    try
                    {
                        foreach (PrefetchCommand prefetchCommand in currentPrefetchCommands)
                        {
                            if (prefetchCommand == null)
                            {
                                continue;
                            }
                            DirectValueHolderRef valueHolder = prefetchCommand.valueHolder;
                            PrefetchPath[] cachePaths        = prefetchCommand.prefetchPaths;

                            RelationMember member = valueHolder.Member;
                            // Merge the root prefetch path with the relative prefetch path
                            cachePaths = mergePrefetchPathsCache.MergePrefetchPaths(member.ElementType, cachePaths, entityTypeToPrefetchPath);

                            IObjRefContainer vhc = valueHolder.Vhc;
                            ICacheIntern targetCache;
                            bool doSetValue = false;
                            if (valueHolder is IndirectValueHolderRef)
                            {
                                IndirectValueHolderRef valueHolderKey = (IndirectValueHolderRef)valueHolder;
                                targetCache = valueHolderKey.RootCache;
                            }
                            else
                            {
                                targetCache = ((IValueHolderContainer)vhc).__TargetCache;
                                doSetValue  = true;
                            }
                            int relationIndex = vhc.Get__EntityMetaData().GetIndexByRelation(member);
                            IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex);
                            Object obj        = valueHolderContainerMixin.GetValue(vhc, relationIndex, member, targetCache, objRefs, CacheDirective.FailEarly);
                            if (doSetValue && obj != null)
                            {
                                member.SetValue(vhc, obj);
                            }
                            EnsureInitializedRelationsIntern3(obj, cachePaths, entityTypeToPrefetchPath, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory,
                                                              cacheToOrelsLoadedHistory, alreadyHandledSet, pendingPrefetchCommands);
                        }
                    }
                    finally
                    {
                        if (!oldActive)
                        {
                            cacheModification.Active = false;
                        }
                    }
                });
                // Remove all oris which have already been tried to load before
                if (cacheToOrisToLoad.Count == 0 && cacheToOrelsToLoad.Count == 0 && pendingPrefetchCommands.Count == 0)
                {
                    return;
                }
                prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);
                LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
                LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);
            }
        }