private IList <PersistableData> BeginRollback()
        {
            // Note regarding to RollingBack:
            // Every object raises a RollingBack event even if another object's RollingBack event changes the first object's state back to original
            // during its own RollingBack event. Because the event order of .NET is not deterministic, this behavior is desired to ensure consistency:
            // Every object changed during a ClientTransaction raises a RollingBack event regardless of the RollingBack event order of specific objects.

            // Note regarding to RolledBack:
            // If an object is changed back to its original state during the RollingBack phase, no RolledBack event will be raised,
            // because the object actually has never been changed from a ClientTransaction's perspective.

            var rollingBackEventNotRaised = GetNewChangedDeletedData().ToList();
            var rollingBackEventRaised    = new HashSet <ObjectID> ();

            // Repeat this until all objects in the rollback set have got the event. The rollback set can change while this loop is iterated.
            while (true)
            {
                var eventArgReadOnlyCollection = ListAdapter.AdaptReadOnly(rollingBackEventNotRaised, item => item.DomainObject);
                _eventSink.RaiseTransactionRollingBackEvent(eventArgReadOnlyCollection);

                // Remember which objects have got the event right now.
                rollingBackEventRaised.UnionWith(rollingBackEventNotRaised.Select(item => item.DomainObject.ID));

                // Reevaluate the rollback set - it might have changed. Have all objects in it got the event? If yes, return the rollback set.
                var changedItems = GetNewChangedDeletedData().ToList();
                rollingBackEventNotRaised = changedItems.Where(item => !rollingBackEventRaised.Contains(item.DomainObject.ID)).ToList();

                if (!rollingBackEventNotRaised.Any())
                {
                    return(changedItems);
                }
            }
        }
        public void IndexOf_WithReadOnlyAdapter()
        {
            var readOnlyAdapter = ListAdapter.AdaptReadOnly(_innerList, i => i.ToString());

            Assert.That(readOnlyAdapter.IndexOf("1"), Is.EqualTo(0));
            Assert.That(readOnlyAdapter.IndexOf("7"), Is.EqualTo(-1));
            Assert.That(readOnlyAdapter.IndexOf("b"), Is.EqualTo(-1));
        }
        public void Contains_WithReadOnlyAdapter()
        {
            var readOnlyAdapter = ListAdapter.AdaptReadOnly(_innerList, i => i.ToString());

            Assert.That(readOnlyAdapter.Contains("7"), Is.False);
            Assert.That(readOnlyAdapter.Contains("1"), Is.True);
            Assert.That(readOnlyAdapter.Contains("b"), Is.False);
        }
        public void AdaptReadOnly()
        {
            var adapter = ListAdapter.AdaptReadOnly(_innerList, i => i.ToString());

            Assert.That(adapter, Is.TypeOf(typeof(ReadOnlyCollection <string>)));
            Assert.That(adapter[1], Is.EqualTo("2"));

            _innerList[1] = 5;
            Assert.That(adapter[1], Is.EqualTo("5"));
        }
        private IList <PersistableData> BeginCommit()
        {
            // Note regarding to Committing:
            // Every object raises a Committing event even if another object's Committing event changes the first object's state back to original
            // during its own Committing event. Because the event order of .NET is not deterministic, this behavior is desired to ensure consistency:
            // Every object changed during a ClientTransaction raises a Committing event regardless of the Committing event order of specific objects.

            // Note regarding to Committed:
            // If an object is changed back to its original state during the Committing phase, no Committed event will be raised,
            // because in this case the object won't be committed to the underlying backend (e.g. database).

            var committingEventNotRaised = GetNewChangedDeletedData().ToList();
            var committingEventRaised    = new HashSet <ObjectID>();

            // Repeat this until all objects in the commit set have got the event. The commit set can change while this loop is iterated.
            while (true)
            {
                var eventArgReadOnlyCollection = ListAdapter.AdaptReadOnly(committingEventNotRaised, item => item.DomainObject);
                var committingEventRegistrar   = new CommittingEventRegistrar(_clientTransaction);
                _eventSink.RaiseTransactionCommittingEvent(eventArgReadOnlyCollection, committingEventRegistrar);

                // Remember which objects have got the event right now.
                committingEventRaised.UnionWith(committingEventNotRaised.Select(item => item.DomainObject.ID));

                // Remove objects registered for repeated Committing events so that they'll get the event again.
                committingEventRaised.ExceptWith(committingEventRegistrar.RegisteredObjects.Select(obj => obj.ID));

                // Reevaluate the commit set - it might have changed. Have all objects in it got the event? If yes, return the commit set.
                var changedItems = GetNewChangedDeletedData().ToList();
                committingEventNotRaised = changedItems.Where(item => !committingEventRaised.Contains(item.DomainObject.ID)).ToList();

                if (!committingEventNotRaised.Any())
                {
                    return(changedItems);
                }
            }
        }