/// <summary>
        /// Populates the object with previously serialized state, begins tracking it for changes and returns it.
        /// If the object is already tracked, an exception is thrown, unless returnExistingInsteadOfException is enabled.
        /// ReturnExistingInsteadOfException may still fail, if object cannot be cast to desired type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="object"></param>
        /// <param name="returnExistingInsteadOfException"></param>
        /// <returns></returns>
        /// <exception cref="InvalidCastException">
        /// object with same collectionId and persistentObjectId is already tracked, but is of incompatible type to the requested one
        /// </exception>
        public T LoadAndStartTracking <T>([NotNull] T @object, bool returnExistingInsteadOfException = false)
            where T : class, IPersistentObject
        {
            var result = Preprocess(@object);
            ObjectCompositeKey compositeKey     = result.ObjectCompositeKey;
            IPersistentObject  persistentObject = result.PersistentObject;

            PersistentObjectManager manager;

            if (objects.TryGetValue(compositeKey, out manager))
            {
                if (returnExistingInsteadOfException)
                {
                    var obj = manager.TryGetObject();
                    if (obj == null)
                    {
                        // object is referenced weakly, it may have been GC'd recently
                        // if so, continue and load it again
                    }
                    else
                    {
                        return((T)obj);
                    }
                }
                else
                {
                    throw new PersistentObjectAlreadyTracked(
                              string.Format("object with the same composite key already exists. Composite key: [ {0} ]",
                                            compositeKey.ToString()));
                }
            }

            var objectManager = new PersistentObjectManager(compositeKey, persistentObject, this);

            objectManager.Initialize();

            objects[compositeKey] = objectManager;

            return(@object);
        }
 internal void StopTracking(PersistentObjectManager manager)
 {
     objects.Remove(manager.CompositeKey);
 }