/// <summary>
 /// Iterates on the dependencies queue expanding all calculated dependendies inside
 /// this same queue
 /// </summary>
 /// <param name="queue"></param>
 private void ExpandDependencies(DependenciesQueue queue)
 {
     //Process all generated dependencies.
     while (queue.PendingCount != 0)
     {
         var resolutionInfo   = queue.Pop();
         var objectValue      = resolutionInfo.value;
         var dependencyValues = SurrogatesDirectory.GetObjectDependencies(objectValue, _stateManager, _stateManager.surrogateManager, this);
         foreach (var dependencyValue in dependencyValues)
         {
             if (dependencyValue != null)
             {
                 DependencyResolutionInfo resolutionInfoForDependency;
                 if (!queue.TryGetValue(dependencyValue, out resolutionInfoForDependency))
                 {
                     queue.Add(dependencyValue, resolutionInfoForDependency = new DependencyResolutionInfo());
                 }
                 queue.RegisterParentDependency(new DependencyParentInfo()
                 {
                     child = resolutionInfoForDependency, ParentValue = objectValue, ParentSurrogate = resolutionInfo.ResolvedSurrogate
                 });
             }
             else
             {
                 queue.RegisterParentDependency(new DependencyParentInfo()
                 {
                     child = null, ParentValue = objectValue, ParentSurrogate = resolutionInfo.ResolvedSurrogate
                 });
             }
         }
     }
 }
        private void GetResolvedValueEx(DependencyResolutionInfo dependency)
        {
            var surrogateManager  = _stateManager.surrogateManager;
            var value             = dependency.value;
            var istateObjectValue = dependency.value as IStateObject;

            if (istateObjectValue != null)
            {
                //The value is an state object
                if (_stateManager.IsInElementsToRemove(istateObjectValue.UniqueID))
                {
                    //If the object is present in the elements it is detached from so its UniqueID
                    //is changed to a temporal one.
                    //The current in the session must be removed
                    _stateManager.DettachObject(istateObjectValue);
                }
                dependency.canBeAnOrphan = !StateManager.AllBranchesAttached(istateObjectValue);
                dependency.ResolvedValue = istateObjectValue;
                dependency.IsStateObject = true;
            }
            else if (value is ISurrogateEventsInfo)
            {
                dependency.ResolvedValue = value;
                dependency.isEventsInfo  = true;
            }
            else
            {
                //if (surrogateManager.IsSurrogateRegistered(value.GetType())) Commented for performance
                StateObjectSurrogate currentSurrogate = null;
                //Get the surrogate instance from the surrogates that are already loaded in memory or create one
                dependency.ResolvedValue = currentSurrogate = dependency.ResolvedSurrogate = surrogateManager.GetSurrogateFor(value, generateIfNotFound: true);

                if (currentSurrogate == null)
                {
                    throw new ArgumentException("A surrogate could not be gotten for value of type " + value.GetType().FullName);
                }

                if (_stateManager.IsInElementsToRemove(currentSurrogate.UniqueID))
                {
                    //If the object is present in the elements it is restored,
                    //since it is a top element no adoption needs to be performed
                    _stateManager.UndoRemove(currentSurrogate.UniqueID);
                    //We must unremove the Value surrogate
                    var valueUniqueID = UniqueIDGenerator.GetRelativeUniqueID(currentSurrogate, StateObjectSurrogate.VALUE_PREFIX);
                    _stateManager.UndoRemove(valueUniqueID);
                }
                else
                {
                    //OK
                }
            }
        }