/// <summary>
        /// Executes a single change on the file system and updates the cache. 
        /// Does not commit or persist in any other way.
        /// </summary>
        /// <param name="change">The change to execute on the file system.</param>
        private void Execute(AbstractChange change)
        {
            // Execute changes
            DisableFileSystemEvents();
            change.ExecuteChanges(FileSystemAdaptee);
            EnableFileSystemEvents();

            // Update cache
            if (change is FileModifiedChange)
            {
                var mod = (FileModifiedChange)change;
                _cache.Update(mod.AssociatedPath);
            }
            else if (change is ItemsCreatedChange)
            {
                var created = (ItemsCreatedChange)change;
                foreach (var creation in created.Items)
                {
                    _cache.Update(creation.GetAssociatedPath());
                }
            }
            else if (change is ItemsDeletedChange)
            {
                var deleted = (ItemsDeletedChange)change;
                foreach (var deletion in deleted.Items)
                {
                    _cache.Delete(deletion);
                }
            }
        }
        /// <summary>
        /// Attempts to version the given change in this file- and version control system. If a
        /// conflict occurs we return it to be handled by the caller.
        /// </summary>
        /// <param name="change">The change to persist.</param>
        /// <returns>A conflict if the merge failed, null otherwise.</returns>
        public Conflict? Save(AbstractChange change)
        {
            try
            {
                // Execute the change on the file system
                Execute(change);

                // Commit the change
                var version = new List<AbstractChange> { change };
                PersistVersion(version);

                // Push to server
                var conflicts = PushToServer();
                if (conflicts.Count > 1) throw new InvalidOperationException("Too many conflicts. Aborting.");
                else if (conflicts.Count == 1) return conflicts[0];
                else return null;
            }
            catch (Exception)
            {
                // If we hit an exception when pushing to server we simply ignore it
                // and avoid incrementing the version - the changes will be pushed once
                // the server is back on track
                return null;
            }
        }