/// <summary>
        ///     Liste des éléments impactés par les commandes lors de la session. Si plusieurs commandes opérent sur un même
        ///     élément, il ne sera répertorié qu'une fois.
        /// </summary>
        /// <value>
        ///     The involved elements.
        /// </value>
        internal bool PrepareModelElements(bool isAborted, bool schemaLoading)
        {
            if (_modelElementsPrepared)
            {
                return(_elements.Count > 0);
            }

            _modelElementsPrepared = true;

            // On est dans le cas d'une session annulée ou lors d'un chargement de metadonnées
            if (schemaLoading)
            {
                return(false);
            }

            var set  = new HashSet <Identity>();
            var list = _elements.Values.ToList();

            foreach (var element in list)
            {
                if (element is TrackedRelationship)
                {
                    var relationship = element as TrackedRelationship;
                    if (relationship.IsSchema)
                    {
                        //element.ModelElement = session.Store.GetMetaRelationship(element.Id);
                        continue;
                    }

                    if (set.Add(relationship.Id))
                    {
                        if (relationship.State != TrackingState.Removed)
                        {
                            var rel = _session.Store.GetRelationship(relationship.Id);
                            if (rel != null)
                            {
                                if (isAborted)
                                {
                                    ((IDisposable)rel).Dispose();
                                }
                                element.ModelElement = rel;
                            }
                        }

                        if (set.Add(relationship.StartId) && GetTrackedElementState(relationship.StartId) != TrackingState.Removed)
                        {
                            var mel = _session.Store.GetElement(relationship.StartId);
                            if (mel != null) // Au cas ou il a été supprimé
                            {
                                TrackedElement data;
                                if (!_elements.TryGetValue(mel.Id, out data))
                                {
                                    data = new TrackedElement
                                    {
                                        State    = TrackingState.Unknown,
                                        Id       = mel.Id,
                                        SchemaId = mel.SchemaInfo.Id
                                    };
                                    _elements.Add(mel.Id, data);
                                }
                                data.ModelElement = mel;
                            }
                        }

                        if (set.Add(relationship.EndId) && GetTrackedElementState(relationship.EndId) != TrackingState.Removed)
                        {
                            var mel = _session.Store.GetElement(relationship.EndId);
                            if (mel != null) // Au cas ou il a été supprimé
                            {
                                TrackedElement data;
                                if (!_elements.TryGetValue(mel.Id, out data))
                                {
                                    data = new TrackedElement
                                    {
                                        State    = TrackingState.Unknown, // N'a pas de conséquense sur la mise à jour de l'entité
                                        Id       = mel.Id,
                                        SchemaId = mel.SchemaInfo.Id
                                    };
                                    _elements.Add(mel.Id, data);
                                }
                                data.ModelElement = mel;
                            }
                        }
                    }
                }
                else
                {
                    // Element
                    if (element.IsSchema)
                    {
                        //element.ModelElement = session.Store.GetMetadata(element.Id);
                    }
                    else
                    {
                        if (set.Add(element.Id))
                        {
                            var mel = _session.Store.GetElement(element.Id);
                            if (mel != null)
                            {
                                if (element.State != TrackingState.Removed)
                                {
                                    element.ModelElement = mel;
                                    if (isAborted)
                                    {
                                        ((IDisposable)mel).Dispose();
                                    }
                                }
                                else if (element.State == TrackingState.Removed)
                                {
                                    ((IDisposable)mel).Dispose();
                                }
                            }
                        }
                    }
                }
            }

            return(_elements.Count > 0 && !isAborted);
        }
        internal void OnEvent(IEvent @event)
        {
            DebugContract.Requires(@event);

            // -----------------------------------------------------------------
            // Add Element
            // -----------------------------------------------------------------
            var addEvent = @event as AddEntityEvent;

            if (addEvent != null)
            {
                var entity = new TrackedElement
                {
                    DomainName = @event.Domain,
                    Extension  = @event.ExtensionName,
                    State      = TrackingState.Added,
                    Id         = addEvent.Id,
                    SchemaId   = addEvent.SchemaId,
                    Version    = @event.Version
                };
                _elements.Add(entity.Id, entity);
                return;
            }

            // -----------------------------------------------------------------
            // Remove Element
            // -----------------------------------------------------------------
            var removeEvent = @event as RemoveEntityEvent;

            if (removeEvent != null)
            {
                TrackedElement entity;
                if (!_elements.TryGetValue(removeEvent.Id, out entity))
                {
                    entity = new TrackedElement
                    {
                        DomainName = @event.Domain,
                        Extension  = @event.ExtensionName,
                        State      = TrackingState.Removed,
                        Id         = removeEvent.Id,
                        SchemaId   = removeEvent.SchemaId
                    };
                    _elements.Add(entity.Id, entity);
                }
                else
                {
                    entity.State = TrackingState.Removed;
                }

                return;
            }

            // -----------------------------------------------------------------
            // Add metadata element
            // -----------------------------------------------------------------
            var addMetadataEvent = @event as AddSchemaEntityEvent;

            if (addMetadataEvent != null)
            {
                var entity = new TrackedElement
                {
                    DomainName = @event.Domain,
                    Extension  = @event.ExtensionName,
                    State      = TrackingState.Added,
                    Id         = addMetadataEvent.Id,
                    SchemaId   = addMetadataEvent.SchemaId,
                    IsSchema   = true,
                    Version    = @event.Version
                };
                _elements.Add(entity.Id, entity);
                return;
            }

            // -----------------------------------------------------------------
            // Change Element
            // -----------------------------------------------------------------
            var changeEvent = @event as ChangePropertyValueEvent;

            if (changeEvent != null)
            {
                TrackedElement entity;
                if (!_elements.TryGetValue(changeEvent.Id, out entity))
                {
                    entity = new TrackedElement
                    {
                        DomainName = @event.Domain,
                        Extension  = @event.ExtensionName,
                        State      = TrackingState.Updated,
                        Id         = changeEvent.Id,
                        SchemaId   = changeEvent.SchemaId
                    };
                    _elements.Add(entity.Id, entity);
                }

                var prop = new PropertyValue
                {
                    Value          = changeEvent.GetInternalValue(),
                    CurrentVersion = changeEvent.Version,
                    OldValue       = changeEvent.GetInternalOldValue()
                };
                entity.Properties[changeEvent.PropertyName] = prop;
                entity.Version = Math.Max(entity.Version, changeEvent.Version);
                return;
            }

            // -----------------------------------------------------------------
            // Add relationship
            // -----------------------------------------------------------------
            var addRelationEvent = @event as AddRelationshipEvent;

            if (addRelationEvent != null)
            {
                var entity = new TrackedRelationship
                {
                    DomainName = @event.Domain,
                    Extension  = @event.ExtensionName,
                    State      = TrackingState.Added,
                    Id         = addRelationEvent.Id,
                    SchemaId   = addRelationEvent.SchemaId,
                    StartId    = addRelationEvent.StartId,
                    EndId      = addRelationEvent.EndId,
                    Version    = @event.Version
                };
                _elements.Add(entity.Id, entity);
                return;
            }

            // -----------------------------------------------------------------
            // Remove relationship
            // -----------------------------------------------------------------
            var removeRelationshipEvent = @event as RemoveRelationshipEvent;

            if (removeRelationshipEvent != null)
            {
                TrackedElement entity;
                if (!_elements.TryGetValue(removeRelationshipEvent.Id, out entity))
                {
                    entity = new TrackedRelationship
                    {
                        DomainName = @event.Domain,
                        Extension  = @event.ExtensionName,
                        State      = TrackingState.Removed,
                        Id         = removeRelationshipEvent.Id,
                        SchemaId   = removeRelationshipEvent.SchemaId,
                        StartId    = removeRelationshipEvent.StartId,
                        EndId      = removeRelationshipEvent.EndId,
                    };
                    _elements.Add(entity.Id, entity);
                }
                else
                {
                    entity.State = TrackingState.Removed;
                }
                return;
            }

            // -----------------------------------------------------------------
            // Add relationship metadata
            // -----------------------------------------------------------------
            var addRelationMetadataEvent = @event as AddSchemaRelationshipEvent;

            if (addRelationMetadataEvent != null)
            {
                var entity = new TrackedRelationship
                {
                    DomainName = @event.Domain,
                    Extension  = @event.ExtensionName,
                    State      = TrackingState.Added,
                    Id         = addRelationMetadataEvent.Id,
                    SchemaId   = addRelationMetadataEvent.SchemaId,
                    StartId    = addRelationMetadataEvent.StartId,
                    EndId      = addRelationMetadataEvent.EndId,
                    IsSchema   = true,
                    Version    = @event.Version
                };
                _elements.Add(entity.Id, entity);
            }
        }